主机是同一进程中的服务器和客户端。主机使用一种称为的特殊客户端,而其他客户端则为RemoteClientLocalClient通过直接函数调用和消息队列与(本地)服务器进行通信,因为它是在相同的过程中。它实际上与服务器共享场景。RemoteClients通过常规网络连接与服务器进行通信。

    网络系统的目标之一是将LocalClientsRemoteClients的代码相同,以便开发人员大多数时候只需要考虑一种类型的客户端。

    在Unity中,GameObject.Instantiate创建新的Unity游戏对象。但是,通过网络系统,对象也必须“生成”才能在网络上处于活动状态。这只能在服务器上完成,并导致在连接的客户端上创建对象。产生物体后,生成系统使用分布式对象生命周期管理和状态同步原则。

    在网络系统中,玩家对象是特殊的。有一个玩家对象与每个玩游戏的人相关联,命令被路由到该对象。一个人不能对另一个人的玩家对象调用命令 - 只能是自己的。所以有一个“我的”玩家对象的概念。当添加玩家并且通过连接进行关联时,该玩家对象成为该玩家的客户端上的“本地玩家”对象。有一个属性isLocalPlayer设置为true,并且在客户端上的对象上调用的回调OnStartLocalPlayer()。下图显示了两个客户及其当地玩家。

    只有“你的”玩家对象将设置isLocalPlayer标志。这可以用于过滤输入处理,处理相机附件,或做任何其他客户端的事情,只能为您的玩家完成。

    除了之外,玩家对象可以拥有“本地权限”。这意味着其所有者的客户端上的玩家对象对该对象负责 - 它具有权限。这最常用于控制运动,但也可以用于其他的东西。NetworkTransform组件了解这一点,如果设置了这一点,将从客户端发送移动。NetworkIdentity有一个用于设置LocalPlayerAuthority的复选框。

    对于非玩家对象(如敌人),没有关联的客户端,所以权限驻留在服务器上。

     6.21 网络系统概念  - 图3

    NetworkBehaviour上有一个属性“hasAuthority”,可以用来判断对象是否具有权限。因此,非玩家对象在服务器上具有权限,并且具有localPlayerAuthority集合的玩家对象对其所有者的客户端具有权限。

    向客户端分配权限会导致在对象上的NetworkBehaviours上调用,并且hasAuthority属性将为true。在其他客户端上,hasAuthority属性仍将为false。具有客户授权的非玩家对象可以发送命令,就像玩家可以一样。这些命令在对象的服务器实例上运行,而不是在与连接相关联的玩家上运行。

    具有客户端权限的非玩家对象必须在其NetworkIdentity中检查LocalPlayerAuthority

    下面的示例产生一个对象,并将权限分配给生成它的玩家的客户端。

    NetworkBehaviour类中有一些属性,允许脚本随时知道网络对象的网络上下文。

    isServer - 如果对象位于服务器(或主机)上并已生成,则为true。• isClient - 如果对象在客户端上,并且由服务器创建,则为true。• - 如果对象是此客户端的玩家对象,则为true。• hasAuthority - 如果对象由本地进程拥有,则为true

    ?