Синхронизация переменных с Unity UNET

Что я хочу сделать · Запустить приложение 1, приложение 2 · Если я нажму кнопку в приложении 1, кнопка будет нажата даже в приложении 2 (изменить событие клика или переменную типа bool)

Что я пробовал (здесь помещаю файлы Unity) https://drive.google.com/open?id=1aV-1SiB56L3JGVzWqAmqc85PYFNW1268

Добавьте следующее к объекту кнопки, нажмите

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class MoviePlay : NetworkBehaviour {
    [SyncVar]
    bool IsPlay = false;

    void Update(){
        if(IsPlay){
            Debug.Log("再生中");
        }        
    }

    public void OnClick(){
        CmdOnClick();
    }
    [Command]
    void CmdOnClick(){
        IsPlay = true;
    }
}

Результат: на консоли отображается Не найдена цель для сообщения синхронизации для 1 и не синхронизировано

-----Добавлять------

Я пробовал. Кнопка (объект игрока)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;

public class PushButton : NetworkBehaviour {
    [SerializeField]
    GameObject DebugScript;

    public void OnClickButton(){
        NetworkInstanceId target = DebugScript.GetComponent<NetworkIdentity>().netId;
        CmdSendMessageToServer(target, "DebugText");
    }
    [Command]
    public void CmdSendMessageToServer (NetworkInstanceId target, string message)
    {
        NetworkServer.FindLocalObject(target).SendMessage(message);
    }
}

Отладочный скрипт

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DebugScript : MonoBehaviour {
    void DebugText(){
        Debug.Log("再生");
    }
}

person Tsunehiko Shimadu    schedule 06.08.2018    source источник
comment
Пожалуйста, предоставьте MCVE: похоже, вам не нужно, чтобы люди загружали пакет единства, поэтому вам следует попытаться обойтись без него. Кроме того, использование каталога tmpfile в стороннем облачном провайдере затруднит архивирование вашего вопроса.   -  person Gabriel Devillers    schedule 06.08.2018


Ответы (1)


Команды можно ТОЛЬКО вызывать для объектов игрока. Так что, если это не локальный игрок, команды просто не будут вызываться. Вы должны переместить функцию в объект игрока и вызвать метод на кнопке.

Вместо того, чтобы создавать тонны и тонны методов для игрока, я сделал единственный метод, чтобы просто использовать метод SendMessage каждого GameObject. У меня был метод для объекта проигрывателя с именем CmdSendMessageToServer, у которого было два параметра: NetworkInstanceId и строка. Это выглядело немного так...

[Command]
public void CmdSendMessageToServer (NetworkInstanceId target, string message)
{
     NetworkServer.FindLocalObject(target).SendMessage(message);
}

Передайте переменную 'netId' (NetworkInstanceId) вашей кнопки вышеуказанной функции вместе с именем метода, который вы хотите вызвать (в данном случае OnClick).

Надеюсь это поможет!

РЕДАКТИРОВАТЬ: Для уточнения вы должны создать отдельный класс, который помещается в объект игрока. Как и следующее...

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class TestNetworkPlayer : NetworkBehaviour 
{
     //a singleton for the CLIENT
     public static TestNetworkPlayer local;

     public override void OnStartLocalPlayer ()
     {
        base.OnStartLocalPlayer();
        //so whenever we access TestNetworkPlayer.local,
        //it will ALWAYS be looking for the LOCAL player on the client we use
        local = this;
     }

    [Command]
    public void CmdSendMessageToServer(NetworkInstanceId target, string message)
    {
        NetworkServer.FindLocalObject(target).SendMessage(message);
    }
}

а затем в вашем сценарии «MoviePlay» у вас будет этот код вместо этого...

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class MoviePlay : NetworkBehaviour {
    [SyncVar]
    bool IsPlay = false;

    void Update(){
        if(IsPlay){
            Debug.Log("再生中");
        }        
    }

    //called when the button is clicked
    public void OnClick(){
        TestNetworkPlayer.local.CmdSendMessageToServer (netId, "ServerOnClick");
    }

    //ONLY called on the server, and then IsPlay should change on all clients as well
    void ServerOnClick(){
        IsPlay = true;
    }
}

Надеюсь, это прояснилось!

person Scornz    schedule 06.08.2018
comment
Я пробовал. Однако удаленный клиент не изменился. - person Tsunehiko Shimadu; 06.08.2018
comment
@TsunehikoShimadu Как я уже сказал в своем посте, этот метод должен применяться к объекту игрока. Вы *не можете вызывать команды для чего-либо, кроме объектов игрока. Вы поместили этот метод на свою кнопку, поэтому он не работал. Кроме того, «DebugText» в любом случае никогда не вызывался бы на клиенте, поскольку вы вызывали его в команде. Однако если вы изменили SyncVar с помощью метода (как в исходном примере), вы изменили его на сервере, а затем атрибут SyncVar автоматически отправил это значение всем клиентам. - person Scornz; 07.08.2018
comment
@TsunehikoShimadu Я отредактировал свой ответ, чтобы лучше прояснить, что я пытался объяснить. - person Scornz; 07.08.2018