UNET客户端不能发送服务器命令,主机可以
本文关键字:主机 命令 服务器 客户端 不能 UNET | 更新日期: 2023-09-27 18:11:16
因此,正如标题所示,我遇到了客户端发送的命令未被触发的问题。
我想要实现的基本功能是,当敌人出现在玩家面前而我点击时,玩家将被暂时击昏。如果我是主持人就行了,而且双方都能很好地登记。
如果我作为客户端玩,我到达命令"应该"发送的点,但我注意到我得到一个警告,说"试图为非本地玩家发送命令"。同样,两端都没有任何反应。显然,我一定是在客户端做错了什么,但不知道还有什么其他方法可以解决这个问题。
问题代码。
if (Input.GetButtonDown("Fire1")) {
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit = new RaycastHit();
Physics.Raycast(ray, out hit, 20f);
if (hit.transform != null) {
if (hit.rigidbody != null) {
PlayerController controller = hit.rigidbody.GetComponent<PlayerController>();
if (controller != null) {
if (!controller.stunned) {
// Send the stun command to the server
controller.CmdStun();
}
}
}
}
}
方法调用
[Command]
public void CmdStun() {
// Report that the stun was sent
UnityEngine.Debug.Log("Stun Sent");
RpcStun();
}
[ClientRpc]
public void RpcStun() {
// Activate the stun timer.
stunTimer.Start();
// Track the players original color.
normalColor = manager.color;
// Make the players bot look like its shut down.
manager.InitiateColorChange(Color.black);
// Other code will check against this before trying to send another stun command.
stunned = true;
}
编辑:应要求,这里是两个脚本的完整版本。
http://pastebin.com/mr4A9ZgH http://pastebin.com/Qg0AjCCDunity中的玩家配置:
https://gyazo.com/400c5b3a95c1a58f9b6e930b0c3c853b https://gyazo.com/c17a7317767a00e2150ff34b03a03e8f https://gyazo.com/322731aefbe69f9567d2b395523b8f2a完整警告信息
尝试为非本地播放器发送命令。UnityEngine.Networking.NetworkBehaviour: SendCommandInternal (NetworkWriter,PlayerController:CallCmdStun()ObjectInteractor:Update() (at Assets/Scripts/ObjectInteractor.cs:58)
必须将script分配给OBJECT的根目录。我也有同样的问题。你必须考虑一些限制条件。
- NetworkIdentity必须在可生成预制的根游戏对象上
- NetworkBehaviour脚本必须与NetworkIdentity在同一个游戏对象上,而不是在子游戏对象上
- prefab不能注册到NetworkManager,除非他们有一个NetworkIdentity在他们的根对象
我猜你是在networkserver
生成的gameobject
上调用命令,或者该对象已经存在于场景中。无论如何,该对象不是您在NetworkManager's SpawnInfo
中分配的playerprefab
。
所以,对于那些对象,'Trying to send command for non-local player'
。你需要给他们的NetworkIdentity
一个'Authority'
,这样他们就可以调用[Command]
。要给他们"权限",你应该使用
NetworkIdentity.AssignClientAuthority(connectionToClient).
并且,事实上NetworkIdentity.AssignClientAuthority
只能在服务器上调用。在'Player'
到'AssignClientAuthority'
上需要另一个[Command]
。
更多细节在这里:
Unity UNET -在播放器对象之外调用[Command]
(我是一个中国人,所以可能我没有表达清楚,希望你能理解)
确保在播放器预制件上有一个NetworkIdentity组件,并选中了Local Player Authority。然后在问题代码上面,只有当它是本地播放器时才运行它,添加以下内容:
if (!isLocalPlayer)
return;
EDIT:一定要包括UPID(从注册你的项目https://multiplayer.unity3d.com)在Unity的播放器设置(编辑->项目设置->播放器)在云项目Id字段,如果你测试远程客户端。即使你使用的是本地主机,远程客户端也会使用Unity的中继服务器连接到你的主机游戏。
EDIT 2:尝试将对controller.CmdStun()
的调用更改为controller.Stun()
。然后在PlayerController
中添加一个调用私有函数CmdStun()
的公共函数Stun()
。
如你所说:
提示"尝试为非本地播放器发送命令"。
你可以从非玩家对象发送命令,如unity文档所述:
命令从客户端的播放器对象发送到播放器对象在服务器上。为了安全起见,命令只能从YOUR发送玩家对象,所以你不能控制其他玩家的对象。
从Unity发布5.2开始,可以从具有客户端权限的非玩家对象。这些物体必须有由NetworkServer派生。SpawnWithClientAuthority或have使用NetworkIdentity.AssignClientAuthority设置权限。命令从这些对象发送的消息在该对象的服务器实例上运行,