ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Unity多人联机解决方案 -- Mirror知识总结

2022-07-14 13:03:31  阅读:403  来源: 互联网

标签:同步 Network SyncVar -- Transform 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组件

image.png

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 &&currentTarget.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 用于同步子物体的位置等信息。
image.png

因为Network Transform 和Network Transform Child会帮我们处理位置等信息,所以我们只需要在Update里面像处理单机游戏时一样去处理我们的主角的位移就好了,但是需要注意的是,我们需要判断是否是本地的Player,因为如果没有这条判断,则在我们的客户端上,我们执行位移代码,则其他的客户端也会被执行位移等。
image.png
试想一下,我们的客户端上存在多个坦克的物体(本机和其他玩家所产生的物体),因为如果没有做是否是本地的判断的话,则玩家的输入势必会影响所有的坦克物体(但只有本机的客户端物体的位置信息会被同步出去)
image.png

动画

如图,如果我们没有任何处理的去设置动画参数,那么它不会被同步到其他的客户端,即使你像处理位移的去处理这个动画(位移能同步是因为有Network Transform组件)
image.png
我们可以通过 [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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有