zoukankan      html  css  js  c++  java
  • 1:虚幻引擎网络架构:Actors

      终于有时间了,打算在这个周末认认真真的研究虚幻引擎网络架构,同时我在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;

      

      

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/NEOCSL/p/4670684.html
Copyright © 2011-2022 走看看