携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
网络授权
Mirror中使用网络授权(Network Authority)来决定网络游戏对象可以被服务器控制还是被客户端控制。所谓控制包含对象的生成和销毁,对象的状态改变等。比如如果是服务器控制某对象,则服务器会负责生成对象,并且通过同步机制,让各个客户端也生成对应的对象;然后服务器会计算该对象的状态并同步到各客户端中的对象上,最后当服务器上删除了对象,则会通知所有的客户端上的对应对象删除。
服务器授权 Server Authority
服务器默认就拥有对象授权。因为只要是游戏场景中所有客户端都能同时看到的游戏对象,都是在服务器上维护的,因此默认也就需要服务器拥有其授权。例外的对象就是Player相关的对象,需要客户端去控制。
客户端授权 Client Authority
客户端授权意味着客户端拥有控制游戏对象的权利。即客户端可以修改对象的状态,且当客户端断开连接时,Mirror会自动删除该客户端所控制的所有对象。客户端授权对象时,可以使用Commands来执行服务器上的方法,修改服务器上的状态。另外既然该对象是网络游戏对象,那么它一定是要将其状态同步到其他客户端,所以服务器仍然要负责该对象的同步工作,比如使用SyncVar。
如何给予授权
服务器默认拥有所有网络游戏对象的授权。服务器可以给予客户端某对象的授权,如果客户端需要控制该对象,例如Player对象。如果使用NetworkServer.AddPlayerForConnection
方法生成一个player,则客户端自动拥有该player对象的授权。
使用NetworkServer.Spawn
当生成对象时,可指定拥有该对象授权的客户端连接,只要在NetworkServer.Spawn
方法的第二个参数里面填入网络连接对象。例如:
GameObject go = Instantiate(prefab);
NetworkServer.Spawn(go, connectionToClient);
使用identity.AssignClientAuthority
可以在任意时刻给任意客户端授权某对象。只要使用该对象对应的NetworkIdentity的AssignClientAuthority方法。例如:
//Command on player object
void CmdPickupItem(NetworkIdentity item)
{
item.AssignClientAuthority(connectionToClient);
}
这是某玩家捡起某个物品,在该玩家的player脚本中,调用这个command,command是在服务器上执行的代码,因此可以在其中将该物品授权给这个玩家。
如何移除授权
可以使用identity.RemoveClientAuthority
来移除某物体上的客户端授权。但是对于player对象,不能移除客户端授权,但可以替换player对象,通过NetworkServer.ReplacePlayerForConnection
方法。
授权回调
当授权被给予或移除时,相应的客户端会收到消息,OnStartAuthority
或OnStopAuthority
会被调用。
检查授权
- 在客户端,使用
identity.hasAuthority
属性来检查客户端是否拥有某对象的授权。 - 在服务端,使用
identity.connectionToClient
属性来获取拥有该对象授权的客户端,如果该属性返回null则说明服务器拥有该对象的授权。