Unity多人联机解决方案 -- Mirror知识总结
作者:互联网
组件
Network Transform
这个组件的功能现在只用于同步位置、旋转和缩放。
当我们添加NetWork Transform的时候,会自动为我们添加一个Network Identity的组件,这也是NetWork Transform组件依赖的一个必须组件。
默认情况下,NetWork Transform组件是服务器来控制权限的,除非你勾选了“Client Authority”,Client Authority适用于玩家对象已经明确被分配给客户端来操作权限,就像是非玩家对象一样。但是它只能用于此组件,一旦被勾选,位置旋转等被改变就会从客户端发送给服务器。
Send Interval:多久同步一次
NetWork Animator
Network Animator组件允许你同步对象的动画状态,它从Animator动画状态机控制器同步状态和参数。
注意,如果在一个空的对象上创建了一个Network Animator组件,那么Mirror也会在改游戏对象上创建一个Network Identity组件和一个Animator组件。
- Client Authority:允许对客户端发送到服务器的动画参数进行更改
- Animator:要与 Network Animator组件同步的Animator组件
SyncVars
SyncVars是从Network Behavior继承的类的属性,它们从服务器同步到客户端。当一个游戏对象产生时,或者一个新玩家加入一个正在进行的游戏时,SyncVars 的最新状态将会被发送至网络上所有的可见对象。使用 SyncVar 自定义属性指定脚本中要同步的变量。
SyncVars 的状态在调用 OnStartClient ()之前被应用于客户端上的游戏对象,因此对象的状态在 OnStartClient ()中始终是最新的。
SyncVars 可以使用Mirror支持的任何类型。在一个 NetworkBehavior 脚本上最多可以有64个 SyncVars,包括 SyncLists (参见下一节)。
当 SyncVar 的值更改时,服务器会自动发送 SyncVar 更新,因此您不需要跟踪它们何时更改或自己发送有关更改的信息。更改Inspector面板上的值不会触发更新。
SyncVar hook属性可用于指定当 SyncVar 更改客户端上的值时要调用的方法.
举例
假如我们有一个网络对象挂载了Enemy的脚本
public class Enemy : NetworkBehaviour
{
[SyncVar]
public int health = 100;
void onm ouseUp()
{
NetworkIdentity ni = NetworkClient.connection.identity;
PlayerController pc = ni.GetComponent<PlayerController>();
pc.currentTarget = gameObject;
}
}
主角的控制器可能是这样的:
public class PlayerController : NetworkBehaviour
{
public GameObject currentTarget;
void Update()
{
if (isLocalPlayer)
if (currentTarget != null &¤tTarget.tag == "Enemy")
if (Input.GetKeyDown(KeyCode.X))
CmdShoot(currentTarget);
}
[Command]
public void CmdShoot(GameObject enemy)
{
// Do your own shot validation here because this runs on the server
enemy.GetComponent<Enemy>().health -= 5;
}
}
在本例中,当一个玩家单击一个敌人时,网络化的敌人游戏对象被分配给 PlayerController.currentTarget。当玩家按下 X 键,选择一个正确的目标时,该目标将通过一个运行在服务器上的 Command 来减少健康 SyncVar。所有客户端都将更新该新值。然后可以在敌人身上设置一个 UI 来显示当前值。
SyncVars同样可以在类的继承中使用。
class Pet : NetworkBehaviour
{
[SyncVar]
string name;
}
class Cat : Pet
{
[SyncVar]
public Color32 color;
}
你可以将 Cat 组件附加到您的 Cat 预置,它将同步它的名称和颜色。
坦克案例
位移
通常来说,我们的玩家,在该案例中也就是坦克,至少有3个组件,NetWork Identity、NetWorkTransform、Network Transform Child,其中 Network Transform Child 用于同步子物体的位置等信息。
因为Network Transform 和Network Transform Child会帮我们处理位置等信息,所以我们只需要在Update里面像处理单机游戏时一样去处理我们的主角的位移就好了,但是需要注意的是,我们需要判断是否是本地的Player,因为如果没有这条判断,则在我们的客户端上,我们执行位移代码,则其他的客户端也会被执行位移等。
试想一下,我们的客户端上存在多个坦克的物体(本机和其他玩家所产生的物体),因为如果没有做是否是本地的判断的话,则玩家的输入势必会影响所有的坦克物体(但只有本机的客户端物体的位置信息会被同步出去)
动画
如图,如果我们没有任何处理的去设置动画参数,那么它不会被同步到其他的客户端,即使你像处理位移的去处理这个动画(位移能同步是因为有Network Transform组件)
我们可以通过 [Command]特性来使我们的动画参数进行同步,如(调用的地方在上面图中可以看到):
// this is called on the server
[Command]
void CmdFire()
{
GameObject projectile = Instantiate(projectilePrefab, projectileMount.position, projectileMount.rotation);
NetworkServer.Spawn(projectile);
RpcOnFire();
}
// this is called on the tank that fired for all observers
[ClientRpc]
void RpcOnFire()
{
animator.SetTrigger("Shoot");
}
[Command]特性可以让函数的执行被客户端发送到服务器端,服务器去处理;其中NetworkServer.Spawn,可以让所有的客户端都生成该物体。
RpcOnFire这个函数被标记为[ClientRpc],RPC是远程调用的意思,服务器使用远程过程调用(RPC)在客户端上运行此函数。
碰撞检测
碰撞检测的代码被[ServerCallback]标记,表明该方法会被防止客户端执行;表明碰撞检测是在服务器上进行的,NetworkServer.Destory是指:销毁此对象以及所有客户端上的对应对象。
[ServerCallback]
void OnTriggerEnter(Collider other)
{
if (other.GetComponent<Projectile>() != null)
{
--health;
if (health == 0)
NetworkServer.Destroy(gameObject);
}
}
标签:同步,Network,SyncVar,--,Transform,Unity,Mirror,组件,客户端 来源: https://www.cnblogs.com/LemonInCup/p/16477295.html