You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

额外检查项

  1. 确保所有玩家的GameObject都挂载了NetworkObject组件,且通过网络生成(如用NetworkManager.Spawn生成)。
  2. 确认调用CmdServer的客户端玩家,是该Command所在NetworkObject的拥有者(默认Command仅允许拥有者客户端调用,符合当前场景)。

内容的提问来源于stack exchange,提问作者niek 352

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 12:24:24