如何在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 ();
    }
}

}

如何在UNet(Unity)客户端调用[Command]

好的,从我所看到的,你正在尝试同步每个玩家使用的皮肤,以便每个玩家在每个客户端上都有正确的皮肤。

你的代码在语法和结构上都有一些问题。

首先看一下语法。

你绝对应该使用[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