统一3D。试图在没有权限的情况下为对象发送命令
Posted
技术标签:
【中文标题】统一3D。试图在没有权限的情况下为对象发送命令【英文标题】:Unity3D. Trying to send command for object without authority 【发布时间】:2016-07-06 14:14:28 【问题描述】:我有一个多人回合制策略游戏,需要一个游戏经理来控制当前的游戏状态(轮到谁等)。这个管理器应该对每个客户端都是通用的,它的状态应该在服务器上同步。
这是我的做法: 游戏管理器对象是 NetworkBehaviour,它具有 NetworkIdentity,既不是本地玩家权限也不是服务器权限。我制作了一个自定义 NetworkManager,它在客户端连接时生成游戏管理器,还测试它是否是服务器。这是一个代码:
public override void OnClientConnect(NetworkConnection conn)
ClientScene.Ready(conn);
if (NetworkServer.active)
var manager = Instantiate(MultiplayerManagerPrefab, Vector3.zero, Quaternion.identity) as GameObject;
var tacticsManager = manager.GetComponent<MultiplayerManagerModel>();
NetworkServer.RegisterHandler(MsgType.AddPlayer, tacticsManager.CreatePlayerOnServer);
NetworkServer.Spawn(manager);
ClientScene.AddPlayer(0);
当我在服务器上运行它时它工作正常,它会在客户端上创建一个实例并将变量从服务器同步到客户端。但是当我尝试从客户端运行命令时,它会忽略它们,并抛出此警告:
试图在没有权限的情况下为对象发送命令。 UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter, Int32,字符串)
请注意,此游戏管理器会在任何玩家之前生成,因为它必须负责生成玩家。我做错了什么?
【问题讨论】:
【参考方案1】:在您的代码片段旁边,警告
试图为未经授权的对象发送命令。
表示:您正在从一个您的(玩家)没有权限的对象发送命令。
Unity 文档说明了什么: 命令 从客户端上的玩家对象发送到服务器上的玩家对象。为了安全起见,命令只能从您的玩家对象发送,因此您无法控制其他玩家的对象。
但是
从 Unity 5.2 版开始可以从 具有客户端权限的非玩家对象。这些对象必须有 使用 NetworkServer.SpawnWithClientAuthority 生成或拥有 使用 NetworkIdentity.AssignClientAuthority 设置的权限。命令 从这些对象发送的对象的服务器实例上运行, 不在客户端的关联播放器对象上 (more)。
那么解决办法是什么: 在发送 Command(或执行 command 函数)之前,将该对象的权限分配给您的播放器。像这样的
assignAuthorityObj.GetComponent<NetworkIdentity>().AssignClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);
"this" 将代表您的 Player 对象。 Command 调用后,您可以使用此代码 sn-p 删除权限。
assignAuthorityObj.GetComponent<NetworkIdentity>().RemoveClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);
同样,“this”将代表您的 Player 对象。
重要提示:我通常使用 OnTriggerEnter 分配对象的权限(如果我想使用它)并删除 的权限>OnTriggerExit。这取决于具体的场景,您希望在什么情况下获取或删除对象权限。
【讨论】:
【参考方案2】:你不能在没有本地权限的情况下发送命令。
if (!isLocalPlayer) return;
但是,你用这个命令发送什么样的数据? 一般来说,正如你所说:
"它的状态应该在服务器上同步"
所以,恕我直言,您没有理由从您的播放器发送Command
。
命令应该用于玩家输入。
这些输入将触发您游戏中的操作。
您的经理将从这些操作(分数更新、游戏结束...)中获取信息,并使用ClientRpc
在客户端上发送数据和/或触发操作
这是服务器权限模型。如果你让本地对象发送命令,黑客很容易进来告诉你的经理
“嘿,轮到我了。嘿,又轮到我了。嘿,我的分数是9999999,我1秒就赢了。”。
【讨论】:
我遇到了类似的问题,但是我的命令在 OnStartLocalClient 函数中,所以这不应该工作吗? 我认为您使用了错误的方法名称,请尝试 OnStartLocalPlayer docs.unity3d.com/ScriptReference/…【参考方案3】:如果您使用的是镜像,则使用绕过权限,花了一整天时间尝试实施上述不起作用的解决方案。 这里应该怎么做:https://mirror-networking.gitbook.io/docs/guides/communications/remote-actions
[Command(requiresAuthority = false)]
public void Something ()
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于统一3D。试图在没有权限的情况下为对象发送命令的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在没有 root 权限的情况下为 SQL 服务器安装 unixODBC 驱动程序
matplotlib (python) - 在没有 pyplot 的情况下为多个绘图创建单个自定义图例