远程操作
网络系统可以通过网络执行操作。这些类型的操作有时称为远程过程调用。在网络系统中有两种类型的RPC,Command - 从客户端调用并在服务器上运行; 和ClientRpc调用 - 在服务器上调用并在客户端上运行。
下图显示了远程操作的方向:
Command
Command
从客户端上的玩家对象发送到服务器上的玩家对象。为了安全起见,Command
只能从您的玩家对象发送,因此您无法控制其他玩家的对象。要将一个函数变成一个命令,添加[Command]
自定义属性,并添加“Cmd”前缀。当在客户端上调用该函数时,该函数现在将在服务器上运行。任何参数将自动通过该命令传递给服务器。
命令函数必须具有前缀“Cmd”。这是读取调用该命令的代码时的一个提示 - 该函数是特殊的,并不像普通函数那样在本地调用。
class Player : NetworkBehaviour
{
public GameObject bulletPrefab;
[Command]
void CmdDoFire(float lifeTime)
{
GameObject bullet = (GameObject)Instantiate(
bulletPrefab,
transform.position + transform.right,
Quaternion.identity);
var bullet2D = bullet.GetComponent<Rigidbody2D>();
bullet2D.velocity = transform.right * bulletSpeed;
Destroy(bullet, lifeTime);
NetworkServer.Spawn(bullet);
}
void Update()
{
if (!isLocalPlayer)
return;
if (Input.GetKeyDown(KeyCode.Space))
{
CmdDoFire(3.0f);
}
}
}
小心每帧发送来自客户端的命令!这可能会导致大量网络流量。
默认情况下,命令在零通道 - 默认可靠通道上发送。所以默认情况下,所有命令都可靠地发送到服务器。可以使用[Command]
自定义属性的“Channel”参数进行自定义。该参数应该是一个整数,代表通道号。
通道1也默认设置为不可靠通道,因此要使用此参数,请在Command
属性中将参数值设为1,如下所示:
[Command(channel=1)]
从Unity 5.2版开始,可以从具有客户端权限的非玩家对象发送命令。这些对象必须由NetworkServer.SpawnWithClientAuthority
产生,或通过NetworkIdentity.AssignClientAuthority
设置权限。从这些对象发送的命令在对象的服务器实例上运行,而不是在客户端的关联玩家对象上运行。
ClientRpc呼叫
ClientRpc
调用从服务器上的对象发送到客户端上的对象。它们可以从任何带有已生成的NetworkIdentity
的服务器对象发送。由于服务器具有权限,因此服务器对象无法发送这些调用的安全问题。为了使函数进入ClientRpc
调用,添加[ClientRpc]
自定义属性,并添加“Rpc”前缀。当在服务器上调用该函数时,该函数现在将在客户端上运行。任何参数将自动通过ClientRpc
调用传递给客户端。
ClientRpc
函数必须具有前缀“Rpc”。当读取调用方法的代码时这是一个提示 - 这个函数是特殊的,并不像普通函数那样在本地调用。
class Player : NetworkBehaviour
{
[SyncVar]
int health;
[ClientRpc]
void RpcDamage(int amount)
{
Debug.Log("Took damage:" + amount);
}
public void TakeDamage(int amount)
{
if (!isServer)
return;
health -= amount;
RpcDamage(amount);
}
}
当使用LocalClient
作为主机运行游戏时,ClientRpc
调用将在LocalClient
上调用 - 即使它与服务器在同一进程中。因此,LocalClients
和RemoteClients
的行为对于ClientRpc
调用而言是相同的。
对远程操作的参数
传递给命令和ClientRpc调用的参数被序列化并通过网络发送。这些数据可以是:
• 基本类型(byte,int,float,string,UInt64等)
• 基本类型的数组
• 包含允许类型的结构
• 内置的Unity数学类型(Vector3,Quaternion等)
• NetworkIdentity
• NetworkInstanceId
• NetworkHash128
• 带有NetworkIdentity组件的GameObject
对远程操作的参数不能是GameObjects的子组件,例如脚本实例或Transform。它们不能是其他类型,不能通过网络序列化。
🔚