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自动处理(更推荐)
- 在Unity编辑器中选中你的
NetworkManager对象,在Inspector面板的NetworkManager组件里找到Player Prefab字段,拖入你的PlayerController预制体。 - 删除
GameManager中手动生成玩家的代码(包括OnNetworkSpawn和SpawnPlayerServerRpc)——NetworkManager会在客户端成功连接时自动生成玩家预制体,并自动完成PlayerObject的绑定。
额外优化建议
- 修复空引用与性能问题:
- 你的
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
相关产品推荐
相关产品推荐

