Unity Mirror客户端调用Server Cmd无法完整执行问题求助
问题分析与解决
问题根源
客户端调用CmdServer后仅打印日志却无后续执行,核心原因是Command方法中传递的PlayerContext参数在服务器端无效:
- 客户端传递的是本地
PlayerContext实例,但网络同步场景下,服务器无法直接识别客户端本地的对象引用,导致服务器端接收的playerContext可能为null,或是非对应主机玩家的服务器端实例,进而跳过了MarkPlayer()的执行。 - 只有继承自
NetworkObject的对象引用,才能在Command/Rpc中正确跨网络传递,普通组件引用不具备网络标识,无法被服务器解析。
解决方案
将Command的参数替换为NetworkObject类型(目标玩家GameObject挂载的NetworkObject组件),服务器端通过该组件获取对应的PlayerContext实例,确保调用到正确的服务器端方法。
修改后代码示例
客户端Movement类代码
//somemovementClass private void TriggerEntered(PlayerContext playerContext) { Debug.Log($"Collided with {playerContext.name}"); // 传递目标玩家的NetworkObject组件引用 CmdServer(playerContext.GetComponent<NetworkObject>()); } [Command] public void CmdServer(NetworkObject targetNetworkObj) { Debug.Log($"CmdServer"); // 从NetworkObject获取服务器端的PlayerContext实例 if (targetNetworkObj != null && targetNetworkObj.TryGetComponent(out PlayerContext targetPlayer)) { targetPlayer.MarkPlayer(); } else { Debug.LogError("无法找到目标玩家的PlayerContext组件"); } }
PlayerContext.cs代码(核心逻辑无需修改,需确保挂载在带NetworkObject的GameObject上)
// PlayerContext.cs [SyncVar(hook = nameof(OnPlayerGetDamage))] private bool wasDamaged; [Server] public void MarkPlayer() { Debug.Log("On Server"); wasDamaged = true; } private void OnPlayerGetDamage(bool oldState, bool newState) { Debug.Log("On Get Damage"); cashedMaterial.color = Color.red; }
额外检查项
- 确保所有玩家的GameObject都挂载了
NetworkObject组件,且通过网络生成(如用NetworkManager.Spawn生成)。 - 确认调用
CmdServer的客户端玩家,是该Command所在NetworkObject的拥有者(默认Command仅允许拥有者客户端调用,符合当前场景)。
内容的提问来源于stack exchange,提问作者niek 352
相关产品推荐
相关产品推荐

