如何在UNet(Unity)客户端调用[Command]
本文关键字:调用 客户端 Command Unity UNet | 更新日期: 2023-09-27 18:11:25
我正在使用UNet制作一款Unity 2D多人游戏。我的问题是客户端不能发送[Command]
到服务器。我调试unityeeditor和一个内置的apk为我的安卓手机。
首先,我使用unityeeditor作为主机和电话作为客户端,Debug.Log(SkinName)
APPEARS on the console
。
然后我使用UnityEditor作为客户端,手机作为主机,Debug.Log(SkinName)
DOES NOT APPEAR
。
我试图使用[ClientRpc]
而不是[Client]
,但它只是使情况更糟,客户端和主机不会同步。我不知道我执行[ClientRpc]的方式是否正确。(我是UNet的新手)
我访问了其他线程/论坛和其他UNet教程来寻找解决方案,但这就是我想到的。
注意:在我访问的其他线程中,人们大多建议本地玩家权限未检查,这就是导致问题的原因,但在这种情况下是CHECKED
。
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using Spine;
using Spine.Unity;
using Spine.Unity.Modules;
class SetupLocalPLayer : NetworkBehaviour {
[SyncVar]
public string SkinName;
public string[] CharNames;
public string[] SlotNames;
public string[] AttachmentSuffix;
void Start (){
TransmitSkins ();
SyncSkin ();
if (isLocalPlayer) {
var skeletonrenderer = GetComponent<SkeletonRenderer>();
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],GameController.control.skinName+AttachmentSuffix[z]);
}
GetComponent<PlayerManager> ().enabled = true;
GetComponent<FollowCam> ().enabled = true;
}
}
void Update () {
}
void SyncSkin(){
if (!isLocalPlayer) {
var skeletonrenderer = GetComponent<SkeletonRenderer>();
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],SkinName+AttachmentSuffix[z]);
}
}
}
[Command]
void CmdSetSkin(){
SkinName = GameController.control.skinName;
Debug.Log (SkinName);
}
[Client]
void TransmitSkins(){
if (isLocalPlayer) {
CmdSetSkin ();
}
}
}
好的,从我所看到的,你正在尝试同步每个玩家使用的皮肤,以便每个玩家在每个客户端上都有正确的皮肤。
你的代码在语法和结构上都有一些问题。
首先看一下语法。
你绝对应该使用[ClientRpc]
而不是[Client]
,方法应该命名为RpcTransmitSkins
。如果脚本被附加到播放器预制件和本地玩家权限检查网络身份,那么它将工作。[Client]
属于一个完全不同的网络API。
现在让我们看一下结构。
基本逻辑是正确的,然而,在现实中,SyncSkin方法将在传输被接收之前被调用。
Start方法不会等待传输,所以为什么不将皮肤分配给Rpc,这样其他版本的播放器只会在收到消息后才尝试分配他们的皮肤。
你也有某些动作拆分,所有客户端需要做的,获得骷髅渲染器,例如
这是我将如何重构你的脚本。
void Start (){
//first, grab the SkeletonRenderer on every version of the player.
//note that it should not be a local var now, but a field in the script
skeletonrenderer = GetComponent<SkeletonRenderer>();
//now do the local player specific stuff
if (isLocalPlayer) {
//transmit the skin name to the other versions of the player
CmdSendSkinRpc(GameController.control.skinName);
//then assign the skin to the local version of the player
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],GameController.control.skinName+AttachmentSuffix[z]);
}
GetComponent<PlayerManager> ().enabled = true;
GetComponent<FollowCam> ().enabled = true;
}
}
[Command]
void CmdSendSkinRpc(string skin){
RpcTransmitSkins(skin);
Debug.Log("Transmitting Skin Named: " + skin);
}
[ClientRpc]
void RpcTransmitSkins(string TransmittedSkinName){
if (!isLocalPlayer) {
Debug.Log("Receiving Skin Named: " + TransmittedSkinName);
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],TransmittedSkinName+AttachmentSuffix[z]);
}
}
}
不要对UNET系统的学习曲线感到沮丧。从多客户端和多服务器的角度来思考是非常令人困惑的。就连这个简单的动作也让我挠头了好几分钟:D