【ET框架】基础及实践难题解答

6.0 疑问可以直接看 13.ET基础问题总结


ET


1、ET 框架基础

(1).前后端通讯流程Demo

整个Demo的流程围绕这张图的顺序来执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

(2).登录系统Demo总结

ET框架的登录流程: 客户端点击登录按钮(含账号、密码、服务器IP地址)触发login方法,创建一个session(绑定服务器二进制版本IP地址),将客户端页面的信息赋值给C2R_Login实例,使用session发送请求,LoginHandler会拦截C2R_Login类型的请求并且返回R2C_Login类型的响应,之后关闭该session,因为此处session主要请求Realm网关负载均衡用来获取网关的key和IP,得到了之后就可以再次创建session直连网关来登录


(3).ESC编程原则

ESC相关概念

1、实体既组件,组件既实体。
2、如要编写一个新的实体或者组件,绝不继承除Entity之外的任何父类!
3、绝不使用任何的虚函数,使用逻辑分发替代。
4、ModelModelView只存放实体和组件的数据字段声明,如非必要绝不放任何逻辑函数
5、HotfixHotfixView中只保留纯逻辑函数,也就是使用静态类和扩展方法编写的System,且绝不允许存在任何数据字段。
6、ModelHotfix中绝不允许出现跟Unity3d引擎相关的游戏对象类和调用相关API函数。
7、如实体或组件有数据字段声明必须编写相关生命周期函数,以防实体对象池回收再利用导致逻辑错误。

要严格遵循要求,不同文件放置不同的内容
更新之后组件接口出 IAwake,实体需要实现IAwake、IUpdate、IDestroy
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

包括根据ET框架中ESC组件思想的处理方式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了方便拓展,可以采用switch、case的方式来实现:
在这里插入图片描述


(4).组件生命周期

在这里插入图片描述
在这里插入图片描述


(5).Scene层级树

①.什么是Scene

在这里插入图片描述

②.客户端Scene的层级关系

在这里插入图片描述
第4点中的Computer实体就是挂载在Zonescene下方

③.服务器端Scene的层级关系

在这里插入图片描述
比如ET框架开发了一款网游,它的客户端只有一个ZoneScene,因此只有一个进程。而服务器可以拥有多个进程,每个进程都是一个ZoneScene,比如地图和位置都可以是不同的ZoneScene。这意味着ET框架中的服务器实际上是一个单线程多进程的服务器。

④.服务器机器人Scene的层级关系

在这里插入图片描述

(6).关于Scene的一些疑问

①.如何创建新的ZoneScene

服务器当中创建ZoneScene的方法就是在SceneType里面添加ZoneScene的名称和对应ID,之后在SceneFactory中添加case newZoneScene和对应的组件并编译。之后再StartSceneConfig文件中按表格填入newZoneScene的对应数据,启动win_startExcelExport,重新编译之后newZoneScene就成功创建了。

②.self.ZoneScene()

在客户端代码中,可以使用self.ZoneScene()来获取客户端所连接的服务器ZoneScene的实例。但是,在服务器端代码中,self.ZoneScene()这样的代码是无法使用的,因为服务器端没有self这个对象。
self.DomainScene()通常用来获取客户端所连接的服务器DomainScene的实例


(7).Excel配置工具使用

在这里插入图片描述
上图中cs文件的类属性由excel文件中配置来决定,我们根据不同需求在不同端展现不同类; ID不可重复
同样的我们可以在Model\Generate\ConfigPartial\StartSceneConfig.cs中定义配置类的一些逻辑函数 比如根据ID查找、根据身高查找
在这里插入图片描述

配置完excel之后,运行win_startExcelExport; 
类属性就会根据excel配置来刷新,excel中的json文件使用vscode打开,能够看到json格式的类属性

(8).ET框架事件系统

首先需要在ET-release6.0\Unity\Codes\Model\Demo\EventType.cs当中设计你的结构体
说明: Model本身不是显示层无法调用Unity相关API,但是可以使用vector3因为我们在ThirdParty中的UnityEngine中定义了相关内容,Vector3本身是纯数字计算函数,所以依然可以在Model层中使用。前提是定义好命名空间
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图代码中就会在登陆界面初始化之后,调用InstallComputer结构体定义好的事件函数


(9).ETTask异步编程

同步: 当代码执行到同步操作的时候,会阻塞在这里等待同步操作执行完才能继续执行后面的代码
异步: 调用了异步操作之后,代码就可以直接继续往后执行了,等异步操作做完会把结果在发送回来;在 C# 中,可以使用asyncawait关键字来实现异步编程。例如,可以定义一个 async 方法来执行异步操作,并在调用该方法时使用 await 关键字等待操作完成。
await 并不是同步,它知识暂停了当前方法的执行,但不会阻塞整个线程
简单说await是放在async标记的方法里面用的,执行到这里的时候必须等待await语句执行完,不过不会干扰主线程,因为await也是被包裹在async方法里面的

调用一个async函数时,你可以选择使用await等待它的结果,也可以不使用await。如果你不使用await,那么async函数会立即返回一个Promise对象,你可以通过在这个Promise对象上调用.then方法来获取它的结果。但是,如果你在一个async函数内部调用另一个async函数,并且希望在继续执行之前等待它的结果,那么你应该使用await1


(10).ProtoBuf通讯消息(非Google开源C++版本)

在这里插入图片描述
在这里插入图片描述
使用VSCODE打开Porto文件夹
注: Proto文件中定义的属性所对应的数字不能相同
在这里插入图片描述
Unity\Codes\Model\Generate\Message\OuterMessage.cs文件中会产生与proto文件对应的类
在这里插入图片描述

(11).网络通讯消息编写

下方实例中我们重新编写ET框架中的Login
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
针对call()方法定制的相应方法,注意类名上方的特性声明
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编写完四条消息的函数之后编译完就可以在控制台和日志中查看输出结果
在这里插入图片描述


(12).Actor模型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


(13).ET服务器与客户端之间登录流程

在这里插入图片描述

(14).服务器的编写流程

①.SceneType添加服务器

在这里插入图片描述

②.Server.Model中添加组件和所需变量

在这里插入图片描述

③.Server.Hotfix中添加组件所需的函数和周期函数

在这里插入图片描述

④.StartSceneConfig中配置服务器信息

在这里插入图片描述
内网端口在:StartProcessConfig@s文件夹中,编写完之后运行win_startExcelExport

⑤.编写账号服务器与登录中心服务器交互信息

由于登陆服务器主要是服务器之间传输信息,所以我们在InnerMessage中编写 注释也很重要
在这里插入图片描述

⑥.在SceneFactory里面补上登陆服务器的组件

在这里插入图片描述

⑦.登录模块中发送讯息给登陆中心服务器做判断

在这里插入图片描述
在登录模块里面使用ActorMessage来发送彼此的信息。第一句代码应该是拿到当前服务器配置信息,然后拿到服务器的ID,拿着账号ID发送一个请求给这个服务器ID并且拿到响应,判断下响应中的错误码是否正确

⑧.编写登录中心服务器与网关服务器交互信息

在这里插入图片描述

⑨.Server.Hotfix编写登录信息拦截方法

在这里插入图片描述
其中能够看到,如果用户登录的账户可以在登陆中心服务器中找到,那说明该账号已经在线。此时我们需要从登陆中心服务器发送消息给网关服务器来将该账号踢下线。因此我们发送了L2G的信息,再去编写一个拦截方法来回应。

⑩.编写G2L的逻辑处理回应

在这里插入图片描述
在这里我们直接找到网关重所在角色,直接将其移除“在线的游戏角色”字典,让该角色掉线,然后关闭链接简单处理。


(15).UI界面入门

Dlg文件:表示窗口。
将下方UI拖入NormalRoot,修改名字后再重新拖入下方,则复制了一个场景。
在这里插入图片描述
然后右点击SpawnEUICode就可以生成文件,ET-EUI-main\Unity\Codes\ModelView\Demo\UI\DlgTest
在这里插入图片描述
如遇报错,则进入D:\GameWork\ET-EUI-main\Unity\Codes\HotfixView\Demo\UI\DlgTest\Event\DlgTestEventHandler.cs
添加新的窗口ID,并指定
在这里插入图片描述
在这里插入图片描述
在Unity中添加AssetBundle
在这里插入图片描述
登录成功之后,隐藏登录页,显示我们创建的测试窗口
在这里插入图片描述


(16).公共UI的创建与使用

EUI使用教程
看完这四集还要自己手动尝试一下才能明白自己编写的使用。


(17).登录模块Realm、Gate流程

在这里插入图片描述
登录流程: 用户登录成功之后选择角色,当用户点击确定。客户端发送一条请求向Account服务器请求Realm负载均衡服务器请求一个Gate的key,之后Account需要向Realm服务器发送请求得到这个key。为什么客户端不能直接向Realm服务器请求这个gatekey呢?

客户端不能直接向Realm服务器请求GateKey的原因可能是出于安全和验证的考虑。当客户端向Account服务器请求GateKey时,Account服务器可以验证客户端的身份和权限,然后再向Realm服务器请求GateKey。这样,Realm服务器只需要处理来自已验证的Account服务器的请求,而不需要处理来自所有客户端的请求,这可以减少Realm服务器的负载,并提高系统的安全性。此外,这种设计也有助于分离关注点,使得每个服务器只需要关注其特定的任务。这是一种常见的设计模式,被广泛应用于许多大型分布式系统中。

(18).3D场景创建与服务端导航数据生成

①:将地表预设物设为静态

在这里插入图片描述

②:打开Navigation导航网格面板

在这里插入图片描述

③:直接Bake

在这里插入图片描述

④:选择想导出的位置,将导航数据导出

在这里插入图片描述

⑤:将导出的导航数据拖入场景

在这里插入图片描述

⑥:将数据中的子物体标签(Tag)设置为NavMesh

在这里插入图片描述

⑦:Tools使用工具生成网格数据,数据将显示在下方路径

在这里插入图片描述在这里插入图片描述

⑧:双击RecastDemo.exe , 打开后在右侧面板选择第一个,Map1.obj

在这里插入图片描述
在这里插入图片描述

⑨:此时就能够看到面板,右侧移到下方选择Build,之后选择Save

在这里插入图片描述在这里插入图片描述

⑩:之后bin文件发生变动,我们将其Copy到图二路径。删除掉Map1,将bin文件改名为Map1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

①:打开Unity,将所有地表预设物Layer设置为Map,没有可以自行添加。与此同时隐藏我们之前放在场景中的网格数据。

在这里插入图片描述
这边取消勾选就行
在这里插入图片描述

②:打开服务器sever.app,F5 unity,启动init场景,就可以了!

在这里插入图片描述


(19).角色跟随摄像机功能

①:Package Manager中安装Cinemachine插件

在这里插入图片描述

②:Asset/ModelView 与 HotfixView 中新增引用并且Apply

在这里插入图片描述

③:打开init场景查看MainCamera的Tag是否是MainCamera,这决定代码中的名字

在这里插入图片描述

④:Unity.ModelView定义相机跟随组件

在这里插入图片描述

⑤:Unity.HotfixView编写System

AwakeSystem直接调用self.Awake();
DestroySystem销毁组件
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
Mouse ScrollWheel
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(20).AOI视野模块

①:什么是AOI?

Area Of Interest
一个游戏对象实体(Unit)在游戏地图场景当中的所能看到和接触到的区域范围,这个区域范围可以覆盖整个游戏地图场累,也可以被缩小至游戏对象实体周围几米的区域范围内。

②:为什么需要AOI视野管理?

距离玩家角色实体过远的游戏对象实体是不会与之发生任何的交互,故不需要关注它们的变化信息。
出于服务器端与客户端的性能优化角度考虑。

(21).AOI视野模块源码解析

①:何时挂载AOI相关组件

在这里插入图片描述在这里插入图片描述

②:挂载后Awake函数内容

在这里插入图片描述
在这里插入图片描述
左手坐标系(Unity使用): 伸开我们的左手, 掌心向外, 大拇指与食指成90度, 中指、无名指和小指弯曲, 大拇指指向的方向就是X轴正方向, 食指指向的方向就是Y轴正方向, 中指、无名指和小指指向的方向就是Z轴正方向。
在这里插入图片描述
在这里插入图片描述

(22).关于不同消息处理抽象类的使用

AMHandler: 这是一个基础的消息处理类,它处理的是普通的消息(Msg)。这些消息通常是无需响应的。

AMRpcHandler: 这个类用于处理远程过程调用(RPC)的请求和响应。这些消息通常需要响应。

AMActorRpcHandler: 这个类用于处理发送给Actor的RPC消息。这些消息通常是服务器之间的通信。

AMActorLocationRpcHandler: 这个类用于处理发送给特定位置的Actor的RPC消息。这些消息通常是在服务器之间进行特定位置通信时使用。

actor实际上就是服务器的信箱,服务器可以自己根据任务进度去信箱里面“取件”然后处理,其实类似于java的rabbitmq中间件,微服务做完一个任务会自己去取下一个任务。而且actor主要是针对服务器之间的通信。

这些类都是抽象类,你不能直接使用它们,而是需要创建它们的子类来处理特定的消息。你可以根据需要创建自己的消息处理类,但是你需要确保你的类继承自正确的基类,并且正确地实现了所需的方法
此外,Actor模型确实主要用于处理服务器之间的通信。通过使用Actor模型,服务器可以并行处理多个任务,提高系统的并发性能。

⭕ET基础问题总结

1:我的组件没有ID这个属性,从何而来?

在ET框架中,每一个实体(Entity)都有一个唯一的ID。这个ID是在实体被创建时自动分配的。所以,当你看到account.Id这样的代码时,这个Id实际上是来自于Entity类的

2:ATimer类与计时器类与run方法的关系

ATimer是一个抽象类,它定义了一个计时器的基本行为。如果你定义了一个计时器类,但是没有创建计时器,那么这个类中的Run方法将永远不会被执行

3:组件与客户端关联吗?每个玩家的客户端上都有自己的组件吗?

组件通常挂载在服务器上,并由服务器管理。它们不会与任何特定的会话或客户端状态相关联。相反,它们通常以独立的方式运行,并根据需要为所有玩家提供服务。例如,登录检查组件可能会在每个玩家登录时运行,以验证其凭据并授予访问权限。尽管每个玩家都可以使用该组件,但该组件本身仍然独立于任何特定的玩家或会话。

4:ET框架服务器是单线程,多个玩家同时请求同一个组件的时候如何执行?

在ET框架中,登录组件是用来处理用户登录请求的。当多个玩家同时点击登录时,服务器会依次处理每个登录请求。由于ET框架是单线程但可异步的,所以服务器可以在处理一个登录请求的同时,异步等待其他登录请求的结果。

5:只要不使用async就一定不会异步执行吗?

服务器是否异步并不仅仅取决于你写的组件方法是否是async方法。它还取决于服务器所使用的框架和并发模型。在ET框架中,服务器本身就支持异步操作,即使你没有在组件方法中使用async关键字。

6:awake生命周期函数的执行时间点

总之awake方法是在组件还没挂在好的时候开始执行,一旦awake执行完成等于组件已经挂在好了。这个时候Load方法开始执行
7:客户端与组件、服务器与组件之间有什么区别?
在客户端中,所有unity的实体都塞给客户端做组件。但是在服务器中,由于有太多服务器,所以我们根据需求把对应的实体给对应的服务器做组件,是选择性的添加。

8:domainScene、zoneScene究竟是什么?

ET框架中,domainScene是属于服务器server文件夹中使用的,它代表当请求所属服务器,因为调用服务器方法都会传进来一个Scene类型,这个Scene就是该玩家所属服务器的信息。domainscene表示所属区服。而客户端unity文件夹中有一个zonescene,它表示当前场景所存在的信息。客户端中可以调用domainscene,但是服务器无法调用zonescene

9:Excel配置中127.0.0.1:10005地址和端口究竟是啥?

127.0.0.1:10005是服务器的IP地址和端口号。127.0.0.1是一个特殊的IP地址,它代表本机,也就是你的电脑。端口号10005是服务器监听的端口;如果你想让前端代码连接到其他电脑上的服务器,你需要将IP地址改为那台电脑的IP地址。例如,如果服务器运行在IP地址为192.168.1.100的电脑上,那么你应该将前端代码中的服务器地址改为192.168.1.100:10005。

10:为什么游戏物体添加了多个组件,只返回其中一个,返回内容同样可以包含其他组件

在Unity中,游戏对象(GameObject)可以被看作是一个容器,它可以包含多个组件(Component)。这些组件定义了游戏对象的行为和显示方式。例如,Button组件使游戏对象可以作为一个按钮使用,而Text组件则允许游戏对象显示文本。
当我们创建一个新的按钮时,我们实际上是在创建一个新的游戏对象,并向其添加了Button和Text两个组件。这意味着,这个游戏对象既有按钮的功能,也能显示文本。
所以,即使我们只返回了Button组件,由于它是附加到游戏对象上的,我们仍然可以通过这个游戏对象来访问其它的组件,包括Text组件。这就是为什么我们可以设置按钮的文本,即使我们只返回了Button组件。

11:为什么我Unity的 文字是 TMP不能显示,或者显示为中文乱码

解决文章

12:Call、CallActor、CallLocationActor的区别?

Call:这个方法通常用于客户端向服务器发送同步请求。这种请求会阻塞当前线程,直到服务器响应。
CallActor:这个方法通常用于客户端向服务器发送异步请求。这种请求不会阻塞当前线程,服务器会在处理完请求后返回结果。
CallLocationActor:这个方法通常用于服务器之间的通信。它允许一个服务器向另一个特定位置的服务器发送请求。

13:publishasync出现:event error: xxxxxxxxxxxxxxxxxxx

出现类似错误因为你的消息拦截类,使用的是AEvent<> 而不是 AEventAsync<>

14:Unity中的代码该如何Debug?

启动server.app debug第二个内容
在这里插入图片描述

❗❗❗15:IDeserialize 和 ISerializeToEntity 之间有什么作用?

两者都能进行序列化与反序列化,ISerializeToEntity 的组件一般是 IDeserialize 的子组件
ISerializeToEntity 在使用 AddComponent 或 Addchild 的时候,源码中 [BsonElement("C")] 自动序列化到数据库中 名为"C"
IDeserialize 在使用 AddComponent 或 Addchild 的时候,源码中 [BsonElement("Children")] 自动序列化到数据库中 名为"Children"

注: 实现前两个接口进行序列化,不能常规的使用DBManager来简单的搜索出数据内容。
通常在组件System中实现接口的方法,进行反序列化
例如:

// 反序列化
        public class BagComponentDeserializeSystem : DeserializeSystem<BagComponent>
        {
            public override void Deserialize(BagComponent self)
            {
                foreach (Entity entity in self.Children.Values)
                {
                    self.AddContainer(entity as Item);
                }
            }
        }

❗❗❗16:如何将消息发给自定义服务器?

1.首先在Proto中定义好消息内容,其中的注释为自定义的消息接口名称
IActor*****Request
在这里插入图片描述
2.在D:\GameWork\ET-EUI-main\Unity\Codes\Model\Module\Actor创建你的消息接口声明,名字定义为:IActorRankInfoMessage.cs
声明内容如下,第一条为不需要回复的消息接口定义,后两条为request和response
在客户端声明之后我们同时引用Add links到服务端的model\Module\Actor中
在这里插入图片描述
3.在D:\GameWork\ET-EUI-main\Unity\Codes\Model\Generate\Message\OuterMessage.cs文件中alt+enter一下你的接口;服务端与客户端都需要这个操作
在这里插入图片描述
4.最后开始修改Server\Hotfix\Demo\Session\SessionStreamDispatcherServerOuter.csDispatchAsync方法,在这个方法中,将接口进行判断,不同的接口做不同的处理,实际上也就是不同的接口表示不同服务器之间的消息通讯
在这里插入图片描述
6.这种方法的拦截类采用 AMActorRpcHandler
同时需要在D:\GameWork\ET-EUI-main\Server\Hotfix\Demo\Scene\SceneFactory.cs中添加case,以此判定不同服务器需要添加的组件

❗❗❗17:如何将消息发给服务器?

在ET框架中,服务器之间的通信主要依赖于Actor消息机制。实体对象只需要挂上MailBoxComponent消息组件,这个实体对象就成了一个Actor,任何服务器只需要知道这个实体对象的id即可向其发送消息,完全不用关心实体对象在哪个服务器上(如UnitId)。原理就是ET框架提供了一个位置服务器,所有挂在MailBoxComponent的实体对象都会将自己的id跟位置注册到这个位置服务器上,其他服务器向这个实体对象发送消息的时候如果不知道这个实体对象在哪个服务器上,会先去位置服务器查询,查询到位置再进行发送。

至于你提到的两种方法CallLocationActor和CallActor,它们都是用来发送Actor消息的。不同的是,CallLocationActor的第一个参数是目标实体的UnitId(所以这个消息是发给玩家这个实体),而CallActor的第一个参数是目标实体的InstanceId1。这两个参数都是用来标识目标实体的,但是它们在不同的场景下使用。具体来说,如果你知道目标实体的确切位置(即在哪个服务器上),那么你可以使用InstanceId来发送消息。如果你不知道目标实体的位置,那么你可以使用UnitId来发送消息,框架会自动查询目标实体的位置并发送消息。

// 如何获取服务器InstanceId
StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.GetBySceneName(session.DomainZone(), "LoginCenter");
long loginCenterInstanceId = startSceneConfig.InstanceId; // 服务器ID拿出来
L2A_LoginAccountResponse l2ALoginAccountResponse = (L2A_LoginAccountResponse) await ActorMessageSenderComponent.Instance.
                           Call(loginCenterInstanceId, new A2L_LoginAccountRequest() { AccountId = account.Id }); // 发送请求给这个ID

❗❗❗18:为什么动画组件无效无法控制动画?

将AnyState连接到你需要的动画上,点击箭头这条线,创建Trigger
前提是MotionType里面有这个变量,有定义这个动画名
在这里插入图片描述
在这里插入图片描述

2、基础知识补充

(1).Mono打包

Mono本身是一个虚拟机,因为C#本身是运行在DotNet平台上面的,而DotNet平台本身就是一个基于虚拟机的平台,Mono虚拟机是对DotNet虚拟机的跨平台移植。

选择Mono方式打包出来的程序只能支持32位的程序。如果使用Mono方式打包,那么就只能打一个32位的系统包,这也就意味着你的程序虽然跑在64位的系统上,但它只能作为一个兼容的32位程序来运行,最多只能支持使用四个G的内存1。对于一个大型游戏而言,只使用4个G的内存是完全不够用的。所以要注意:使用Mono方式打包的程序不支持64位系统。

(2).32位和64位的区别

处理内存大小不同:32位操作系统最多只能识别4GB内存,而64位操作系统最多可识别数十TB的内存。

支持的处理器不同:64位的操作系统支持基于64位的处理器,而32位的系统却不能完全支持64位的处理器。

运行的软件不同:32位的系统只能运行32位的软件程序,但64位的可以向下兼容,运行32位的软件程序。

处理数据的能力:32和64表示CPU可以处理最大位数,一次性的运算量不一样,理论上64位的会比32位快1倍,内存寻址也不一样。

系统大小不同:32位操作系统相对于64位操作系统会稍小一些。

兼容性:32位的操作系统,支持基于32位的软件,不能运行64位的软件;而64位的系统一般这两种类型的都支持,基本上与各种软件都兼容。

总的来说,64位的系统和CPU在处理数据的能力和内存支持上都优于32位的,但是也需要更多的资源

(3).MONO和IL2CPP打包的区别?

简单说 Mono和IL2cpp这两种打包模式,前者只能打包出32位的程序,后者可以打包出更大的程序。由于C#本身就是在dotnet的虚拟机上运行,Mono打包等于是把这些代码放到Mono这个虚拟机上面,然后封装起来,方便我们移植其他平台使用,IL2CPP打包兼容性更强,它会把程序中的IL代码替换成C++方便其他平台编译 ,它的性能比mono高,速度快,而且每个平台都有良好优化的c++编译器,所以用IL2CPP打包出来的程序方方面面都比Mono打包出来的程序高效好用

(4).帧同步、状态同步、状态帧同步

帧同步:客户端按照帧速率,也就是每一个tick上传玩家的所有操作指令,然后发给服务器,服务器转发给其他客户端(服务端主要是校验每个玩家的数据是否正常,反外挂等等),其他客户端在本地在执行这些指令,使得所有玩家看到的画面一致。

状态同步:客户端一旦发生某种状态变化,比如玩家进入冒险关卡,玩家血量不足,蓝量变少。客户端就会收集数据发送给服务端,服务端计算完之后将结果返回客户端。

状态帧同步:客户端在每个tick都会向服务器发送消息,无论状态是否发生变化。这样,服务器可以实时获取到每个客户端的状态,从而保证了游戏的同步。但是,这种方式可能会导致网络负载较大,因为即使状态没有发生变化,也需要发送数据包。所以在设计时,需要权衡网络负载和游戏同步的需求。

(5).客户端是如何预测的?

比如我玩CS,我按下W的那一刻,人物前进是在本地客户端直接执行的。执行完之后传输到服务端,服务器返回之后客户端再校验,看看客户端这个预测是否准确,如果一样那就没问题,如果不一样那就“回滚”,也就是我们游戏中延迟高的时候产生的“瞬移回原位”

(6).什么是UDP(用户数据报协议)?

UDP(用户数据报协议)是一种无连接的、不可靠的、面向报文的传输层协议。它的主要特点是简单快速,但由于其不可靠性,可能会导致数据包丢失。然而,有些应用场景并不需要TCP那样严格的可靠性,例如实时游戏或流媒体传输。


功能开发思路

好友功能需要用户A向用户B发送消息请求,而ET框架中自带的MessageHelper转发消息需要得到角色的GateSessionActorId,所以我决定先创建一个组件用来存储所有登陆过的角色的名字以及GateSessionActorId。
在这里插入图片描述
在角色进入游戏的时候调用这个方法,传入角色的名字和GateSessionActorId;
在这里插入图片描述
在这里插入图片描述
为了保证数据的稳定就不适用序列化接口,直接自己存储到数据库
在这里插入图片描述
编写发送好友请求的部分
在这里插入图片描述


3、ET7.2与8.0 实践

1.Unity打开之后却没有出现ET菜单(BuildTool)?

在这里插入图片描述
##2.ET底层框架原理

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
写在前面 一直从事java方面的工作,用过大大小小各种框架,尝试过各种复杂的配置以及不同学习曲线,感觉java的世界是如此杂而乱。借此希望造一个轮子,已简化java web开发,开发者不需要学习更多的知识,只要一个框架就能解决绝大多数日常应用开发中的问题。由于诞生了这个框架,暂且取名为:ET-Framework (来自外星人的框架) 目标与计划 (1)简洁—去掉不必要依赖,尽量减少对外部环境的依赖,使用jdk源码实现的尽量用jdk源码实现 (2)高效—开发效率要高,集成server,支持热部署,动态替换 (3)简单—学习曲线低,几天就可以上手 Roadmap 序号 模块名称 模块说明 1 et-framework (maven父工程,管理所有的子模块或者是子项目,以及负责整体发布,整体打包,等等) 2 et-service  这个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI 支持,引入et-service.jar和et-common.jar 文件就可以了。 3 et-web  这个jar 文件包含ET MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何类。 4 et-dao  这个jar 文件包含对ET对JDBC 数据访问进行封装的所有类。和事务访问数据库 5 et-common  这个jar 文件包含ET 框架基本的核心工具类。et 其它组件要都要使用到这个包里的类,是通用的核心的工具类,当然你也可以在自己的应用系统中使用这些工具类 备注 采用maven搭建项目,管理依赖以及版本的控制,代码托管在github ,希望大家为中国的开源事业贡献自己的一份力量 基础知识准备:git和eclipse集成maven和eclipse集成 有疑问请联系liuhaihua@59et.com 标签:etframework
Unity ET框架是一套双端框架,可以同时支持前端和后端开发。它提供了一些特色功能,比如ET版本的ECS和异步模块,以及双端网络模块。使用ET框架可以提高双端开发的效率,因为前后端的代码可以共享。然而,需要注意的是,ET框架限制了后端只能使用C#开发语言。此外,ET框架的功能并不是非常完整和精细,特别是前端的框架部分,可能只能作为一个建议的demo使用,无法满足商业项目的需求。\[1\] 相比之下,GF框架是一套比较成熟、完整的游戏框架,适用于任何游戏引擎。GF框架提供了几乎所有在Unity开发游戏中可能用到的模块,结构清晰、耦合度低。然而,由于GF框架的完整性,学习成本可能会比较高,需要一定的适应时间。\[2\] 总的来说,ET框架更适合有经验的小团队或个人游戏开发者,尤其是那些熟悉C#语言的开发者。而GF框架则更适合需要一个完整、成熟的游戏框架的开发团队。选择哪个框架取决于团队的需求和开发经验。 #### 引用[.reference_title] - *1* *2* *3* [Unity 游戏框架之GameFramework和ET对比](https://blog.csdn.net/qq563129582/article/details/106993157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值