1:虚幻引擎网络架构:Actors

Posted on 2015-08-15 19:58  neocsl  阅读(1499)  评论(0编辑  收藏  举报

  终于有时间了,打算在这个周末认认真真的研究虚幻引擎网络架构,同时我在Safaribooksonline上面发现了一本能让我的生活变得轻松的书Multiplayer Game Programming by Rough Cuts,这个周末好好享用哟。

   好了,承接上一次的内容:为什么虚幻引擎的网络架构这么的高效?

 

  1.从他的架构模式继续广义的客户端-服务器模型(Generalized Client-Server model):

      在这个模型中服务器还是控制着游戏状态的变化,客户端运行着和服务器一样的代码判断游戏的运行状态。服务器通过复制replication的方式将游戏状态信息发送到客户端,客户端和服务器也可以replication交换信息。

  当然为了最小化的复制内容,我们分类出了仅有调用函数的Actors。

 

  2.从最早Tim Sweeney阐明的虚幻网络架构,Unreal 3- Unreal 4我并未发现有太大的变化。

  在引擎中通常可以有以下内容可以进行复制Variable, Function ,Actor,Object, game state, tick。

  -Client 是一个Unreal.exe的运行实例,维持着一组和世界中发生事件的近似游戏状态子集,并且可以渲染世界的近似视图。

  - Server是一个正在运行的实例,负责每一个独立关卡并把游戏状态传给客户端。

 

  3.Unreal发生在Server和Client之间的更新循环

  - 如果我是Server,我可以将自己的状态传给所有的客户端。

  -如果我是Client,我可以把我请求的运动发送给服务器,并从服务器收到游戏状态信息,发送到客户端上渲染到屏幕上。

  

  4.关于虚幻中的实时状态更新:event Tick(float DeltaTime)

  每次Tick影响到游戏所有Actors的更新,实现了他们的物理等变量或事件,例如Position+=velocity*DeltaTime;

  因此在Tick对于作用于Actor可以

  - 修改Actor的变量

  - 创建Actor

  - 销毁Actor

 

  你会好奇我为什么花费那么多能量来阐述虚幻中的更新呢?因为服务器管理游戏状态就是在管理世界中的所有Actors的状态。因此服务器被看做是一个真正的游戏状态,客户端上的游戏状态可以说是服务器端的近似状态,需要被督导和斧正。存在于客户端的对象,不能被当作代理,因为他们只是一个代理的近似。

  例如你的iPhone机器上跑了自己的角色Pawn,那其实不是真正的Pawn,而是一个向服务器端的Pawn的Clone,仅为你呈现而已。悲哀吧,你只能在客户端玩到一个阿凡达。

 

  5.为了节省性能,我们得对Actor进行一些分类:这些标志可以表明这个Actor的那些环节将会被replication

  在一个关卡中,有一些Actor的状态不会产生什么变化,我们知道他们是一成不变的,所以复制没有意义只会浪费不必要的带宽和浪费。我们使用两种标志位将bNoDelete || bStatic 的Actor进行排除,这两种标志位的Actor一般或是StaticMesh等或者GameInfo。

  那么Actor为了进行replication还需要进行哪些特殊的标注呢?

  在服务器和客户端都存在的Actor我们标注其为Authority。对于服务器端是一直都会保存其为Authority权威,而对于客户端是进行优先级进行区分的:例如在网络复制中同步到客户端,如果一个溅血粒子效果的表现的重要性,肯定不及玩家射出的子弹。根据优先级我们可以分为:

  DumbProxy(哑代理):传送门,拾取物品

  SimulatedProxy(仿真代理):射弹等可以使用物理在客户端进行预测的Actor。说明这是个临时Actor,在客户端模拟物理和动画。

  AutonomousProxy(自治代理) :说明这是一个本地玩家,可以进行一些本地预测运动(给予玩家控制)。可以执行本地脚本,只可在本地客户端可见,不会在服务器和单人玩家游戏中见到。

  Authority:可以执行脚本,进入状态,所有在服务器端的Actor。当在本地,这个Actor只在本地生成以便减少带宽,例如特效。 在服务器端,所有Role=ROLE_Authority和RemoteRole设置成同一种代理类型。在客户端和服务器端是相反的。

// Net variables.
enum ENetRole
{
   ROLE_None,              // No role at all.
   ROLE_SimulatedProxy,    // Locally simulated proxy of this actor.
   ROLE_AutonomousProxy,   // Locally autonomous proxy of this actor.
   ROLE_Authority,         // Authoritative control over the actor.
};
var ENetRole RemoteRole, Role;
  
 用以下的举例来结束这一片内容:
a.因为Actor.AmbientSound变量是从服务器发送给客户端的
 if(Role==Role_Authority)
AmbientSound;

b.Actor.AnimSequence,只有当actor被渲染成为mesh时才会
从服务器发送给客户端
 if(DrawType==DT_Mesh && RemoteRole<ROLE_SimulatedProxy) AnimSequence;

c.Server传送给client velocity为代理模拟。当被初始化为mover时
 if((RemovetRole==ROLE_SimulatedProxy && (bNetInitial||bSimulatedPawn))||bIsMover)velocity;