使用Mirror开发多人游戏时CmdFight权限错误求助
Mirror多人游戏Command射击判定权限错误解决方案
错误根源分析
错误提示Command Function System.Void CharacterMovement::CmdFight() called on NetworkCharacterContainer(Clone) without authority说明:
- 调用
CmdFight的对象未被Mirror正确标记为拥有本地权限的玩家对象 - 玩家生成逻辑未完成连接关联,导致权限校验失败
- 服务器端无法直接获取客户端输入,原代码的射线逻辑存在根本性错误
分步修复方案
1. 修正玩家生成逻辑(核心权限问题)
OnServerAddPlayer必须将生成的玩家对象关联到对应客户端连接,Mirror才会自动赋予其本地权限。替换原生成代码:
public override void OnServerAddPlayer(NetworkConnectionToClient conn) { GameObject player = Instantiate(playerPrefab, transform.position, transform.rotation); // 关键:将玩家绑定到客户端连接,自动处理权限与网络同步 NetworkServer.AddPlayerForConnection(conn, player); // 无需单独调用NetworkServer.Spawn,AddPlayerForConnection会自动完成 }
原代码仅实例化并Spawn对象,但未完成连接绑定,导致Mirror无法识别该对象为玩家的本地授权对象。
2. 修复Command的射线参数传递(服务器无法读取客户端Input)
服务器端无法直接访问客户端的Input.mousePosition,必须在客户端计算好射线数据后,通过Command参数同步到服务器:
public void HandleFighting() { if(Input.GetMouseButtonDown(0)) { Debug.Log(this); // 客户端计算射线的起点与方向 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); CmdFight(ray.origin, ray.direction); } } [Command] private void CmdFight(Vector3 rayOrigin, Vector3 rayDirection) { if (!isLocalPlayer) { Debug.LogWarning("Command Function CmdFight() called on CharacterMovement without authority."); return; } if (WeaponData != null) { RaycastHit raycastHit; if (Physics.Raycast(rayOrigin, rayDirection, out raycastHit, WeaponData.Range)) { GameObject hitObj = raycastHit.collider.gameObject; Health health; if (hitObj.TryGetComponent<Health>(out health)) { health.SubstactHealth(WeaponData.damage); health.AddEffects(WeaponData.effects); } } } }
3. 验证玩家预制体的NetworkIdentity配置
确保玩家预制体的NetworkIdentity组件满足:
- 勾选Local Player Authority
- 未勾选Server Only
- 已正确添加到NetworkManager的
Player Prefab字段中
内容的提问来源于stack exchange,提问作者user19886119
相关产品推荐
相关产品推荐

