我正在使用UNet开发Unity 2D多人游戏。我的问题是客户端无法将[Command]
发送到服务器。我调试UnityEditor和我的Android手机的内置apk。
首先,我使用UnityEditor作为主机,将手机用作客户端Debug.Log(SkinName)
APPEARS on the console
。
然后我使用UnityEditor作为客户端,将手机用作主机Debug.Log(SkinName)
DOES NOT APPEAR
。
我尝试使用[ClientRpc]
代替[Client]
,但它只是让它变得更糟,客户端和主机都不会同步。我不知道我是否以正确的方式执行了[ClientRpc]。(我是UNet的一个菜鸟)
我已经访问过其他线程/论坛和其他UNet教程以寻找解决方案,但这就是我想出来的。
注意:在我访问过的其他主题中,人们主要建议取消选中Local Player Authority,这就是造成问题的原因,但在这种情况下它是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 ();
}
}
}
答案 0 :(得分:2)
好的,所以我可以看到你试图同步每个玩家使用的皮肤,这样每个玩家的每个玩家都拥有正确的皮肤。
您的代码在语法和结构方面都存在一些问题。
首先让我们看看语法。
您绝对应该使用[ClientRpc]
而不是[Client]
,并且该方法应命名为RpcTransmitSkins
。如果脚本附加到播放器预制件并且网络标识上的“本地播放器权限”已选中,则它将起作用。 [Client]
完全属于不同的网络API。
现在让我们看看结构。
基本逻辑是正确的,但实际上,在收到传输之前很久就会调用SyncSkin方法。
Start方法不会等待传输,所以为什么不将皮肤分配移动到Rpc,这样其他版本的播放器只会在收到消息后尝试分配他们的皮肤。
您还有一些所有客户需要执行的操作,例如获取SkeletonRenderer
以下是重构脚本的方法。
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