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

Unity Netcode获取已连接客户端PlayerObject为空的问题求助

问题根源

你通过SpawnWithOwnership生成玩家对象时,仅完成了所有权赋值,但没有将该对象注册为对应客户端的PlayerObject——NetworkClient.PlayerObject需要手动关联,SpawnWithOwnership不会自动完成这个绑定,这就是为什么你看到所有客户端的PlayerObject都是null。

解决方案

方式1:手动绑定PlayerObject(适配你当前的代码)

修改GameManager中的SpawnPlayerServerRpc方法,在生成玩家后调用SetPlayerObject完成绑定:

[ServerRpc(RequireOwnership = false)]
private void SpawnPlayerServerRpc(ulong playerId) {
    var spawn = Instantiate(_playerPrefab);
    var playerNetworkObj = spawn.NetworkObject;
    playerNetworkObj.SpawnWithOwnership(playerId);
    // 关键:将生成的玩家对象设置为客户端的PlayerObject
    NetworkManager.Singleton.SetPlayerObject(playerId, playerNetworkObj);
}

方式2:让NetworkManager自动处理(更推荐)

  1. 在Unity编辑器中选中你的NetworkManager对象,在Inspector面板的NetworkManager组件里找到Player Prefab字段,拖入你的PlayerController预制体。
  2. 删除GameManager中手动生成玩家的代码(包括OnNetworkSpawn和SpawnPlayerServerRpc)——NetworkManager会在客户端成功连接时自动生成玩家预制体,并自动完成PlayerObject的绑定。
额外优化建议
  1. 修复空引用与性能问题:
    • 你的MonsterController中未定义nearestPlayer变量,需添加:private NetworkObject nearestPlayer;
    • 每帧调用ServerRpc会造成不必要的网络开销,改为固定间隔计算:
      private float calculateInterval = 1f;
      private float timer;
      
      void Update()
      {
          timer += Time.deltaTime;
          if (timer >= calculateInterval)
          {
              RecalculateNearestPlayerServerRpc();
              timer = 0;
          }
          if (nearestPlayer != null)
          {
              var dir = (nearestPlayer.transform.position - transform.position).normalized;
              rb.velocity = dir * speed; // 归一化方向,避免速度随距离波动
          }
      }
      
    • 在RecalculateNearestPlayerServerRpc中增加空值判断,防止报错:
      [ServerRpc]
      private void RecalculateNearestPlayerServerRpc()
      {
          float nearestPlayerDistance = float.MaxValue;
          nearestPlayer = null;
          foreach (NetworkClient client in NetworkManager.Singleton.ConnectedClientsList)
          {
              if (client.PlayerObject == null) continue; // 跳过无玩家的客户端
              float sqrDistance = (client.PlayerObject.transform.position - transform.position).sqrMagnitude;
      
              if (sqrDistance < nearestPlayerDistance)
              {
                  nearestPlayerDistance = sqrDistance;
                  nearestPlayer = client.PlayerObject;
              }
          }
      }
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:13:16