Unity/Mirror网络同步射线投射建筑对象异常问题排查
问题分析
核心问题是客户端的射线检测位置未正确同步到主机,且客户端可能越权生成了无权威的网络物体:客户端自己生成的物体没有服务器同步标识,主机会用默认位置(地图中央)生成一个新的同步物体,双端物体位置不一致就会引发闪烁。
解决方案
1. 严格遵循服务器权威规则
客户端只做3件事:
- 检测本地按键输入
- 执行射线检测获取放置位置
- 将位置通过
[Command]传给主机
主机负责:
- 接收客户端传来的位置
- 生成带网络身份的物体并同步给所有客户端
2. 修正代码示例(以Mirror框架为例)
假设你用的是Mirror,修正后的核心逻辑如下:
using UnityEngine; using Mirror; public class BuildingSystem : NetworkBehaviour { // 预制体必须挂载NetworkIdentity,且在NetworkManager的Spawnable Prefabs中注册 public GameObject cubePrefab; private Camera playerCamera; void Start() { // 仅本地玩家初始化相机 if (isLocalPlayer) { playerCamera = GetComponentInChildren<Camera>(); } } void Update() { // 非本地玩家不处理输入 if (!isLocalPlayer) return; if (Input.GetKeyDown(KeyCode.T)) { // 客户端本地执行射线检测 if (Physics.Raycast(playerCamera.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, 10f)) { // 把检测到的位置传给主机 CmdSpawnCube(hit.point); } } } // Command:客户端调用,主机端执行 [Command(requiresAuthority = true)] void CmdSpawnCube(Vector3 spawnPos) { // 主机生成物体,用客户端传来的同步位置 GameObject cube = Instantiate(cubePrefab, spawnPos, Quaternion.identity); // 同步生成的物体到所有客户端 NetworkServer.Spawn(cube); } }
3. 关键注意事项
- 预制体配置:立方体预制体必须挂载
NetworkIdentity组件,且添加到NetworkManager的Spawnable Prefabs列表中;不需要勾选"Local Player Authority"(除非后续需要客户端操作该物体) - 禁止客户端本地生成网络物体:绝对不能让客户端直接调用
Instantiate生成带NetworkIdentity的物体,否则这个物体没有服务器权威,主机会额外生成一个默认位置的同步物体,导致双端出现两个物体引发闪烁 - 预览物体处理:如果需要实时显示放置预览(半透明立方体),这个预览物体必须是客户端本地物体,不要挂载NetworkIdentity,只有确认放置时才通过Command让主机生成正式同步物体
4. 常见错误排查
- 检查
[Command]方法调用条件:确保只有本地玩家(isLocalPlayer为true)才能调用,且物体挂载了NetworkIdentity组件 - 确认预制体已注册:未注册的预制体无法被
NetworkServer.Spawn同步 - 排查射线检测逻辑:确保射线能正确命中可放置表面,避免返回无效位置(比如
Vector3.zero)
内容的提问来源于stack exchange,提问作者Skourge
相关产品推荐
相关产品推荐

