携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
Mirror中可以穿过网络执行行为,称为remote actions,也称为RPC(remote procedure calls,远程过程调用)。Mirror中的RPC包含 Commands 和 ClientRpc。其中Commands是客户端调用服务器上的方法,而ClientRpc是服务器调用客户端上的方法。
Command
Commands从客户端上的player object发送给服务器上的player object。出于安全考虑,默认只有你自己控制的player object(即Local player)可以发送command,因为你不能控制其他玩家的objects。
使用方法
- 将一个函数变成Command,只要加上
[Command]自定义属性,按照惯例,函数名前加前缀"Cmd"。前缀让其他人可以了解这是一个Command函数,而不是一个在客户端执行的普通函数。 - Command函数在客户端上被调用,但是是在服务器上执行的。
- Command函数可以带有参数,参数类型必须是Mirror支持的类型,当Comannd函数被调用时,参数也随之从客户端传递到服务器。
例子
public class Player : NetworkBehaviour
{
public GameObject cubePrefab;
void Update()
{
if(!isLocalPlayer) return;
if(Input.GetKey(KeyCode.J))
CmdDropCube();
}
[Command]
void CmdDropCube()
{
if(cubePrefab != null)
{
Vector3 pos = transform.position + tranform.forward*3;
GameObject cube = Instantiate(cubePrefab, pos, transform.rotation);
NetworkServer.Spawn(cube);
}
}
}
这个例子中,玩家在客户端上按下J键,就会调用一个CmdDropCube Command函数。该函数在服务器上执行,会在玩家面前生成一个方块,并且使用 NetworkServer.Spawn(cube)方法在其他客户端上也生成一个方块。该方块的prefab上需要有NetworkIdentity组件。
非Local Player调用Command的情况
一般情况,只有Local player可以调用Command,但也有几种情况,Command可以在其他对象上执行。
- 当该对象是使用客户端授权生成时。
- 该对象被授予了客户端授权,即使用 NetworkIdentity.AssignClientAuthority
- Command函数的Command属性的参数
requireAuthority被设置为false。此时,可以在Command函数上使用一个可选的参数:NetworkConnectionToClient sender=null,Mirror会将发送该Command的客户端连接填入这个参数。不要在调用时设置这connection参数,会被忽略掉。
注意:以上几种情况,Command函数是在服务器上该对象的实例上执行的,而不是在客户端所关联的服务器上的Player Object上。这个其实是显而易见的,毕竟Command函数本来就包含在该对象的NetworkBehaviour脚本中。 下面看一个非local player使用Command的简单例子:
public class Tree : NetworkBehaviour
{
[SyncVar]
public float HP;
[Client]
void OnMouseUp()
{
CmdCutTree();
}
[Command(requireAuthority=false)]
public void CmdCutTree(NetworkConnectionToClient sender=null)
{
HP--;
if(HP<=0)
{
//Destroy tree
NetworkServer.Destroy(gameObject);
}
}
}
这个例子中的Tree对象,可以在任意客户端上使用鼠标进行砍树操作,CmdCutTree是一个Command函数,由于设置了requireAuthority=false,因此可以被服务器执行,该函数执行时会扣减Tree的HP值,并且由于HP是一个SyncVar,所有玩家都可以看到树的血条在扣血,当HP扣减完后,服务器会删除这棵树,且所有的客户端会同步从客户端上删除这棵树。