C# 如何在UNet(Unity)中对客户端调用[Command]
我正在使用UNet制作一个Unity 2D多人游戏。我的问题是客户端无法将C# 如何在UNet(Unity)中对客户端调用[Command],c#,unity3d,multiplayer,unity3d-unet,C#,Unity3d,Multiplayer,Unity3d Unet,我正在使用UNet制作一个Unity 2D多人游戏。我的问题是客户端无法将[命令]发送到服务器。我在UnityEdit上调试,并为我的android手机安装了一个内置的apk 首先,我使用UnityEditor作为主机,手机作为客户端,控制台上会出现Debug.Log(SkinName) 然后我使用UnityEdit作为客户端,手机作为主机,调试日志(SkinName)不会出现 我尝试使用[ClientRpc]而不是[Client],但这只会让情况变得更糟,客户端和主机都无法同步。我不知道我是否
[命令]
发送到服务器。我在UnityEdit上调试,并为我的android手机安装了一个内置的apk
首先,我使用UnityEditor作为主机,手机作为客户端,控制台上会出现Debug.Log(SkinName)
然后我使用UnityEdit作为客户端,手机作为主机,调试日志(SkinName)
不会出现
我尝试使用[ClientRpc]
而不是[Client]
,但这只会让情况变得更糟,客户端和主机都无法同步。我不知道我是否以正确的方式执行了[ClientRpc]
我访问了其他线程/论坛和其他UNet教程来寻找解决方案,但这就是我想到的
注意:在我访问的其他线程中,人们大多建议取消选中本地播放器权限,这就是导致问题的原因,但在本例中,它是选中的
代码:
使用UnityEngine;
使用系统集合;
使用UnityEngine。联网;
使用脊柱;
使用脊柱。团结;
使用Spine.Unity.Modules;
SetupLocalPLayer类:网络行为{
[同步变量]
公共字符串名称;
公共字符串[]字符名;
公共字符串[]SlotNames;
公共字符串[]AttachmentSuffix;
无效开始(){
传人皮肤();
SyncSkin();
if(IsLocalLayer){
var skeletonrenderer=GetComponent();
对于(intz=0;zOk),我可以看到您正在尝试同步每个玩家使用的皮肤,以便每个玩家在每个客户端上都有正确的皮肤
您的代码在语法和结构方面都存在一些问题
首先让我们看看语法
您绝对应该使用[ClientRpc]
而不是[Client]
,并且该方法应命名为rpctrTransmistskins
。如果脚本附加到播放机预置,并且在网络标识上检查了本地播放机权限,则该方法将起作用。[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]);
}
}
}
void Start(){
//首先,在每个版本的播放器上获取SkeletonRenderer。
//请注意,现在它不应该是本地变量,而是脚本中的一个字段
skeletonrenderer=GetComponent();
//现在做本地玩家特定的事情
if(IsLocalLayer){
//将皮肤名称传输到播放器的其他版本
CmdSendSkinRpc(GameController.control.skinName);
//然后将蒙皮指定给播放器的本地版本
对于(int z=0;z建议也添加unet标记。添加,你能帮我吗,先生?它困扰了我好几天:(我希望我可以,我已经尝试过unet系统,但失败了。这就是为什么我认为你最好撒一个更大的网。对不起,伙计。顺便问一下,在这个脚本中我应该使用[SyncVar]?不,这里不需要。SyncVar只从服务器>客户端同步,而且经常同步。据我所知,您只需要在启动时同步一次。事实上,我认为您可以摆脱SkinName。我尝试了代码,结果是,在主机上,两个播放器的外观相同。[链接]现在在主机上可以了,但在客户端发生了这种情况。[link]。蓝头发的角色应该是一个黑发的家伙,并给出了此错误NullReferenceException:对象引用未设置为对象SetupLocalPLayer.rpCtrTransmistSkins(System.String TransmittedSkinName)(位于Assets/Scripts/SetupLocalPLayer.cs:52)
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]);
}
}
}