从ET看到ET4.0,越趋于稳定,今天开始学习了
地址:https://github.com/egametang/ET
这篇文章有什么:
目前是基于ET4.0(2018.11.16日版本)写的
- Mac下把程序跑起来的方法(Windows跟着GitHub里写的流程就能跑起来了)
- 官方Demo的启动入口解释
- ET 的UI框架需要注意的地方
- ET的服务端协议生产
- 未完待续...
1.Mac下发现启动不了服务器,会报Win32Exception
,于是直接用终端Terminal启动发现是可行的
#!/bin/bash
cd /Users/4dage/Documents/GitHub/ET/Bin/
dotnet App.dll --appId=1 --appType=AllServer --config=../Config/StartConfig/LocalAllServer.txt
- 将这个文本输入(cd 后面的是工程
Server.sln
编译出来的文件夹),然后保存成.command结尾的文件 - 为这个文件赋一下mac权限,在终端中输入
chmod +x [你的文件夹的全部路径,例如:User/Document/server.command]
然后每次双击一下,就能快速开启服务器了,美滋滋
1.1补充,直接在Rider或者VS中启动Server更加方便,还能实时调试
如果是在Rider中,我遇到一个找不到DLL的错误,导致无法启动,可以修改下面的运行文件夹为Bin即可
1.2 发现要配置好完全的开发环境还是挺麻烦的
- 需要特殊编译的Protobuf ,用来将协议
.proto
文件转成cs脚本的工具
https://github.com/egametang/protobuf3-for-Unity-and-ILRuntime - Go语言的运行环境,用来运行Web服务器的,Web服务器就是用来下打包好的资源文件的
有位高人在Mac下的教学步骤:http://www.liuocean.com/index.php/2018/07/25/et-kuang-jiamac-duan-gong-ju-zhi-chi/
修改源码,源码不经过修改跑不起来,版本是2018.11月的 ET4.0分支
1.3Proto2CS.cs
//Proto2CS.cs的第40行
#if !UNITY_EDITOR_OSX
CommandRun($"protoc.bat", "");
#else
("cd "+ System.Environment.CurrentDirectory + " && bash ./protoc.sh").Bash(System.Environment.CurrentDirectory,true);
#endif
1.4PathHelper.cs
//PathHelper.cs第40行
#if UNITY_IOS || UNITY_STANDALONE_OSX
return $"file://{Application.streamingAssetsPath}";
#else
return Application.streamingAssetsPath;
#endif
1.5Hotfix.cs
//Hotfix.cs第56行
public void LoadHotfixAssembly()
{
Game.Scene.GetComponent().LoadBundle($"code.unity3d");
#if ILRuntime
Log.Debug($"当前使用的是ILRuntime模式");
this.appDomain = new ILRuntime.Runtime.Enviorment.AppDomain();
GameObject code = (GameObject)Game.Scene.GetComponent().GetAsset("code.unity3d", "Code");
byte[] assBytes = code.Get("Hotfix.dll").bytes;
byte[] mdbBytes = code.Get("Hotfix.pdb").bytes;
using (MemoryStream fs = new MemoryStream(assBytes))
using (MemoryStream p = new MemoryStream(mdbBytes))
{
//this.appDomain.LoadAssembly(fs, p, new Mono.Cecil.Pdb.PdbReaderProvider());
this.appDomain.LoadAssembly(fs, null, new Mono.Cecil.Pdb.PdbReaderProvider());
}
this.start = new ILStaticMethod(this.appDomain, "ETHotfix.Init", "Start", 0);
#else
Log.Debug($"当前使用的是Mono模式");
GameObject code = (GameObject)Game.Scene.GetComponent().GetAsset("code.unity3d", "Code");
byte[] assBytes = code.Get("Hotfix.dll").bytes;
#if UNITY_EDITOR_OSX
byte[] mdbBytes = code.Get("Hotfix.pdb").bytes;
#else
byte[] mdbBytes = code.Get("Hotfix.mdb").bytes;
#endif
this.assembly = Assembly.Load(assBytes, mdbBytes);
Type hotfixInit = this.assembly.GetType("ETHotfix.Init");
this.start = new MonoStaticMethod(hotfixInit, "Start");
#endif
Game.Scene.GetComponent().UnloadBundle($"code.unity3d");
}
2.运行测试
1.Tools -- Proto2CS
(这个是用来把Protobuf协议生成CS文件的)
2.Tools -- Web资源服务器
(这个是用来给客户端下载资源的)
3.Tools -- 打包工具
-- 选择你自己的平台(我的是Mac),然后点打包
然后打包一个执行文件出来,就可以开始运行了,当连上两个客户端的时候,就可以动了
2.Demo初解
(为了方便改成Mono模式,就是把ILRuntime宏去掉了)
BuildSetting--PlayerSetting--OtherSetting--Scripting Define Symbols里面
1.在ET非热更的Init.cs
里面Game.Hotfix.GotoHotfix();
这句话很重要,是加载内容的起点
其实就是去加载并调用打包好的热更新程序Hotfix.dll里面的一个Init类的Start静态方法。这个方法会做一些初始化,比如加载UI管理工具,然后创建UI,通过字符串去识别
Type hotfixInit = this.assembly.GetType("ETHotfix.Init");
this.start = new MonoStaticMethod(hotfixInit, "Start");
下面的EventIdType.InitSceneStart
就是一个字符串,标记在类上后就可以通过事件去触发它的run方法,方法里面就是创建UI的过程了,大概思路就是创建一个UI(继承自Entity),然后Add一个UI逻辑脚本(继承自Component)
[Event(EventIdType.InitSceneStart)]
public class InitSceneStart_CreateLoginUI: AEvent
{
public override void Run()
{
UI ui = Game.Scene.GetComponent().Create(UIType.UILogin);
}
3.UI框架接入
看着4.0+准备进军FairyGUI了,所以我决定把TinyTeamUI框架加进去试试,ET的UI有点不方便
已成功!
有几个注意的点
1.新做了一个UI放在Bundle里,没有打包
在打包工具中没调用标记AB包的功能,在BuildEditor.cs
加上一个新的仅标记功能就行了,如果做了新的预置物(.prefab)先标记一下就行了
[MenuItem("Tools/打包工具(仅标记)")]
public static void PakeTag()
{
SetPackingTagAndAssetBundle();//把下面的该方法修改为Public Static
}
[MenuItem("Tools/打包工具")]
public static void ShowWindow()
{
GetWindow(typeof(BuildEditor));
}
效果就是需要显示UI的时候,只需要简单的写一行代码,比如需要显示UIEntry界面,目前还可能存在问题,得等我用一段时间再放出来
//打开进入界面
UIPage.ShowPage();
//关闭UI
UIPage.ClosePage();
//打开的同时获取界面
UIEntry entry = UIPage.ShowPage();
Log.Debug(entry.pageName);
这样用起来就很舒服了,FGUI还是观望一段时间(2018.11.16)
2.ILRuntime的一些常用功能添加
使用的时候发现一些Button的Onclick事件是需要添加ILRuntime委托的转换器的,这样之后能就能用Button.OnClick.AddListener( ()>={ }; );
方法了
ILHelper.cs
在30行后面加上
#region adapter
//TODO:Osmin 添加Unity的委托事件
appdomain.DelegateManager.RegisterDelegateConvertor((action) =>
{
return new UnityEngine.Events.UnityAction(() =>
{
((System.Action)action)();
});
});
appdomain.DelegateManager.RegisterMethodDelegate();
appdomain.DelegateManager.RegisterMethodDelegate();
appdomain.DelegateManager.RegisterDelegateConvertor>((action) =>
{
return new UnityEngine.Events.UnityAction((a) =>
{
((System.Action)action)(a);
});
});
#endregion
3.服务端
1.添加自定义协议
首先通信是需要协议的。比如发送玩家仅使用名字登陆的信息,需要有个协议写成这样
message C2G_GameEntry_IRequest // IRequest
{
int32 RpcId = 90;
string Name = 1; //名字进入游戏的名字
}
message G2C_GameEntry_IResponse // IResponse
{
int32 RpcId = 90;
int32 Error = 91;
string Message = 92;
}
这里ET用了protobuf,然后还用了一个猫大自己加的protobuf转cs的功能。
- 协议统一放在一个文件夹
ET/Proto/
里面,比如新建一个GameMessage.proto
- 第二步,在Proto2CS.cs里面添加两行代码
[MenuItem("Tools/Proto2CS")]
public static void AllProto2CS()
{
// InnerMessage.proto生成cs代码
InnerProto2CS.Proto2CS();
msgOpcode.Clear();
Proto2CS("ETModel", "OuterMessage.proto", clientMessagePath, "OuterOpcode", 100);
msgOpcode.Clear();
Proto2CS("ETModel", "FrameMessage.proto", "Assets/Model/Module/FrameSync/", "FrameOpcode", 10);
msgOpcode.Clear();
Proto2CS("ETHotfix", "HotfixMessage.proto", hotfixMessagePath, "HotfixOpcode", 10000);
//在这里添加新协议的转换代码,这里生成的是GameOpcode.cs
msgOpcode.Clear();
Proto2CS("ETHotfix", "GameMessage.proto", "Assets/Hotfix/Module/Message/", "GameOpcode", 20000);
...
...
...
}
- 第三步,在
ET/Unity/Proto.sh
里面添加(如果是Windows,则在ET/Unity/Proto.bat
里面添加一行代码)这一步是生成GameMessage.cs协议文件的
protoc --csharp_out="./Assets/Hotfix/Module/Message/" --proto_path="../Proto/" GameMessage.proto - 第四步,点击Unity内的
Tools/Proto2CS
按钮,他先会生成GameOpcode.cs文件,然后调用系统命令,使用猫大自己做的Protobuf3.2工具生成GameMeesage.cs文件,
注:上面的Assets/Hotfix/Module/Message/
文件路径是可以换的,只要在Unity工程文件里面就行了