目录
demo
框架下载5.0:https://github.com/egametang/ET
下载完成后,打开 ET\Server\server.sln
打开后按照下面的链接修改文件,运行的服务器即可打印日志
选择Server.App,然后【开始执行(不调试)】
打开 ET\Unity\Assets\Scenes\Init.unity
直接运行即可进入demo
自定义登录之客户端
1.自定义协议
每一个命令都有2个协议,IRequest向目标发送请求,IResponse请求完成后的回应
例如,向服务器发送登录信息,那么服务器就应该告诉客户端登录是否成功
打开 ET\Proto\HotfixMessage.proto
可以看到里面有很多协议,具体语法自己去官网看,我们添加2个协议
message CS_Login //IRequest
{
int32 RpcId = 90;
string User = 1;
string Password = 2;
}
message SC_Login // IResponse
{
int32 RpcId = 90;
int32 Error = 91;
string Message = 92;
string Address = 1;
int64 Key = 2;
}
然后打开Unity,执行菜单 Tools/Proto2CS
就会自动生成C#协议代码,观察下面2个文件
Assets\Hotfix\Module\Message\HotfixMessage.cs
Assets\Hotfix\Module\Message\HotfixOpcode.cs
服务器直接引用这些文件,不需要复制到服务器
2.修改进入函数
打开 Assets\Hotfix\Base\Event\EventIdType.cs 添加变量
public const string InitGameScene = "InitGameScene";
打开 Assets\Hotfix\Init.cs 修改为
//Game.EventSystem.Run(EventIdType.InitSceneStart);
Game.EventSystem.Run(EventIdType.InitGameScene);
创建 Assets\Hotfix\Module\Demo2\InitGameScene.cs
namespace ETHotfix
{
[Event(EventIdType.InitGameScene)]
public class InitGameScene : AEvent
{
public override void Run()
{
//创建UI面板
UI ui = LoginFactory.Create();
//把UI面板添加到UI组件
Game.Scene.GetComponent<UIComponent>().Add(ui);
}
}
}
即可从InitGameScene的Run进入
3.创建UI面板
直接使用 Assets\Bundles\UI\UILogin.prefab 登录面板
创建 Assets\Hotfix\Module\Demo2\LoginFactory.cs
namespace ETHotfix
{
public class LoginFactory
{
public static UI Create()
{
try
{
//获取资源管理组件
//里面维护2个字典,一个缓存字典,一个包信息字典
ResourcesComponent resourcesComponent = ETModel.Game.Scene.GetComponent<ResourcesComponent>();
//加载ab包
resourcesComponent.LoadBundle(UIType.UILogin.StringToAB());
//读取ab包的资源
GameObject bundleGameObject = (GameObject)resourcesComponent.GetAsset(UIType.UILogin.StringToAB(), UIType.UILogin);
//创建对象
GameObject gameObject = UnityEngine.Object.Instantiate(bundleGameObject);
//创建UI组件,把上面创建的对象的层级改为UI层级
UI ui = ComponentFactory.Create<UI, string, GameObject>(UIType.UILogin, gameObject, false);
//添加自定义登录组件
ui.AddComponent<LoginComponent>();
return ui;
}
catch(Exception e)
{
Log.Error(e);
return null;
}
}
}
}
4.创建登录组件
创建 Assets\Hotfix\Module\Demo2\LoginComponent.cs
namespace ETHotfix
{
//添加特性后会反射调用该类
[ObjectSystem]
public class LoginComponentSystem : AwakeSystem<LoginComponent>
{
public override void Awake(LoginComponent self)
{
//调用登录组件的Awake函数
self.Awake();
}
}
public class LoginComponent : Component
{
private InputField user;
private InputField password;
private GameObject loginButton;
public void Awake()
{
//获取面板上的引用组件
ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>();
loginButton = rc.Get<GameObject>("LoginBtn");
loginButton.GetComponent<Button>().onClick.Add(OnLogin);
this.user = rc.Get<GameObject>("Account").GetComponent<InputField>();
this.password = rc.Get<GameObject>("Password").GetComponent<InputField>();
}
void OnLogin()
{
//向服务器发送登录消息
MyLoginHelper.OnLoginAsync(user.text,password.text).Coroutine();
}
}
}
5.向服务器发送登录消息
创建 Assets\Hotfix\Module\Demo2\MyLoginHelper.cs
namespace ETHotfix
{
public class MyLoginHelper
{
public static async ETVoid OnLoginAsync(string user,string password)
{
//从网络监听组件取出一个 session
ETModel.Session session = ETModel.Game.Scene.GetComponent<NetOuterComponent>().Create(GlobalConfigComponent.Instance.GlobalProto.Address);
//创建 session,并调用它的Awake
Session realmSession = ComponentFactory.Create<Session, ETModel.Session>(session);
//向服务器发送CS_Login协议消息,并对返回的SC_Login协议消息进行处理
SC_Login r2CLogin = (SC_Login)await realmSession.Call(new CS_Login() { User = user, Password = password });
//释放 session
realmSession.Dispose();
Log.Debug(r2CLogin.Key.ToString());
}
}
}
自定义登录之服务器
创建 Sever.Hotfix/Module/Demo/TestLoginHandle.cs
using System;
using System.Net;
using ETModel;
namespace ETHotfix
{
//处理realm类型的消息
[MessageHandler(AppType.Realm)]
//带有返回的RPC调用
class TestLoginHandler : AMRpcHandler<CS_Login, SC_Login>
{
protected override async ETTask Run(Session session, CS_Login request, SC_Login response, Action reply)
{
// 随机分配一个Gate
StartConfig config = Game.Scene.GetComponent<RealmGateAddressComponent>().GetAddress();
IPEndPoint innerAddress = config.GetComponent<InnerConfig>().IPEndPoint;
//创建一个内部 gate
Session gateSession = Game.Scene.GetComponent<NetInnerComponent>().Get(innerAddress);
// 向gate请求一个key,客户端可以拿着这个key连接gate
G2R_GetLoginKey g2RGetLoginKey = (G2R_GetLoginKey)await gateSession.Call(new R2G_GetLoginKey() { Account = request.User });
//返回给客户端的地址,客户端用该地址建立 session
string outerAddress = config.GetComponent<OuterConfig>().Address2;
response.Address = outerAddress;
response.Key = g2RGetLoginKey.Key;
//返回 response 给客户端
reply();
}
}
}
右键 Sever.Hotfix 》 重新生成
启动服务器 》 运行Unity。。。。。巴拉巴拉。。。。