Unity Mirror联网游戏开发(10) 远程行为之ClientRpc

1,775 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

ClientRpc

ClientRpc即服务器发起的,调用客户端上的方法的远程命令。服务器上的任意具有Network Identity组件的对象都可以发起ClientRpc。

  • 将一个函数设置为ClientRpc需要给他加上一个自定义属性[ClientRpc]
  • ClientRpc函数按照惯例添加前缀"Rpc"
  • ClientRpc函数的参数类型必须是Mirror支持的类型。
  • ClientRpc函数不能有返回值
  • ClientRpc函数是由客户端的网络对象执行的,因此需要存在于继承自NetworkBehaviour的脚本中。

一个例子:

public class Player : NetworkBehaviour
{
    int hp;
    
    [ServerCallback]
    public void TakeDamage(int damage)
    {
        hp -= damage;
        RpcDamage(damage);
    }
    
    [ClientRpc]
    public void RpcDamage(int damage)
    {
        PlayAttackEffect(damage);
    }
}

在这个例子中,TakeDamage是一个在服务器上被执行的方法,注意他被标记了属性[ServerCallback],如果客户端执行这个方法会忽略掉。当然也可以在这个方法内部判断isServer。该服务器方法内部会调用RpcDamage方法,这是一个ClinetRpc方法,会被发送给客户端上相应的Player对象脚本去执行。在ClientRpc方法内部一般会进行一些只需要在客户端进行的操作,比如播放特效。

排除对象拥有者

ClientRpc消息会被发送给该对象的所有观察者,而Player对象也是他们自己的观察者。在某些情况下,你可能不需要对象调用针对自己的ClientRpc。这可以通过给[ClientRpc]增加一个参数: [ClientRpc(includeOwner = false]

TargetRpc

ClientRpc是从服务器给所有客户端群发消息,如果想向特定的客户端单独发送消息,就要使用TargetRpc

  • 将一个函数设定为TargetRpc需要给它添加自定义属性[TargetRpc]
  • TargetRpc函数按照惯例使用前缀Target
  • 如果TargetRpc函数的第一个参数的类型为NetworkConnection,那么该Rpc调用则由这个Connection对应的对象接收。
  • 如果TargetRpc函数的第一个参数是其他类型,那么包含该TargetRpc函数的脚本的拥有者在客户端上的对象作为Rpc调用的接收者。

一个例子:

public class Player : NetworkBehaviour
{
    int hp;
    
    [Command]
    public void CmdMagic(GameObject target, int damage)
    {
        target.GetComponent<Player>().hp -= damage;
        NetworkIdentity targetIdentity = target.GetComponent<NetworkIdentity>();
        TargetDoMagic(targetIdentity.connectionToClient, damage);
    }
    
    [TargetRpc]
    public void TargetDoMagic(NetworkConnection target, int damage)
    {
        //攻击目标的客户端会执行该方法
        PlayerMagicEffectOnMe();
    }
    
    [Command]
    public void CmdHealSelf()
    {
        hp += 10;
        TargetHealed(10);
    }
    
    [TargetRpc]
    publc void TargetHealed(int amount)
    {
        //没有NetworkConnection参数,因此该脚本的拥有者对象执行该方法
        PlayerHealEffectOnMe();
    }
}

这个例子中展示了[Command]Rpc方法的通常用法。使用Mirror写网络游戏时,一定要区分哪些操作是在服务器执行,哪些是在客户端执行。在这儿,CmdMagicCmdHealSelf都是在服务器上执行的Command方法,在其内部会进行Player的hp值的操作,然后在Command内部调用Rpc方法,让客户端去执行其他需要在客户端上进行的操作,比如更新UI或者播放特效等等。这个例子展示了两类TargetRpc,其中TargetDoMagic是在指定的客户端进行操作,而TargetHealed是对拥有者操作。