2016-10-03 8 views
1

Я работаю над многопользовательской игрой Unity 2D с использованием UNet. Моя проблема заключается в том, что клиент не может отправить [Command] на сервер. Im отлаживает UnityEditor и встроенный apk для моего телефона Android.Как вызвать [Command] для клиента в UNet (Unity)

Сначала я использовал UnityEditor как Host и телефон как Клиент, Debug.Log(SkinName)APPEARS on the console.

Затем я использовал UnityEditor в качестве Клиента и телефона как Host, Debug.Log(SkinName)DOES NOT APPEAR.

Я попытался использовать [ClientRpc] вместо [Client], но это только сделало его хуже, и клиент, и хост не синхронизируются. Я не знаю, правильно ли я вызвал [ClientRpc] (im a noob at 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

предлагает добавить тег unet. –

+0

Добавлено, ты можешь помочь мне с этим сэром?Его прослушивание меня в течение нескольких дней :( – Daniel

+0

Хотелось бы, я попробовал и провалил систему unet. Вот почему я подумал, что вам лучше бросить большую сеть. Извините, мой друг. –

ответ

2

Итак, из того, что я вижу, что вы пытаетесь синхронизировать шкуры используются каждым игроком, так что каждый игрок имеет правильную кожу на каждом клиенте.

Есть пара проблем с вашим кодом, как в синтаксисе, так и в структуре.

Сначала рассмотрим синтаксис.

Вы должны использовать [ClientRpc] вместо [Client], а метод следует называть RpcTransmitSkins. Если скрипт прикреплен к сборке проигрывателя, а локальный агент пользователя проверен в сетевом удостоверении, он будет работать. [Client] полностью принадлежит к различным сетевым API.

Теперь давайте посмотрим на структуру.

Основная логика правильная, однако на самом деле метод SyncSkin будет называться задолго до передачи.

Метод «Пуск» не будет ждать передачи, поэтому почему бы не переместить назначение скина на 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

+0

Я попробую это сразу. – Daniel

+0

Кстати, в этом скрипте я должен использовать [SyncVar]? – Daniel

+0

Нет, вам здесь не нужно. SyncVar только синхронизирует с Server> Client, и он делает это часто. Насколько я вижу, вам просто нужно это синхронизируется один раз при запуске. На самом деле, я думаю, что вы можете полностью избавиться от SkinName – turnipinrut