Многопользовательская проблема [SyncEvent] с неигровыми объектами - PullRequest
0 голосов
/ 27 ноября 2018

Я разрабатываю многопользовательскую игру, основанную на ходах.Итак, у меня есть скрипт с именем gameController, который обладает глобальным таймером для изменения ходов, а также для выбора, какие игроки атакуют, а какие защищаются в текущем ходу.Этот скрипт представляет собой одиночный файл, прикрепленный к gameObject с идентификатором сети (этот идентификатор сети не имеет флажков, помеченных сервером как контроллер).Я пытался создать этот игровой объект для всех клиентов при подключении к серверу, а также чтобы игровой объект уже находился на сцене (не работают кабины).

Ну, главная проблема в том, что вскрипт gameController У меня есть функция проверки в функции обновления, чтобы проверить, подключен ли новый игрок.В случае подключения он должен вызвать syncEvent с именем EventOnNewPlayerAddedDelegate (я пытался вызвать его напрямую, также используя [command] и используя [ClientRpc]), чтобы дать игрокам понять, что они должны вызвать свою функцию с именем «OnRegisterPlayer", которая является функцией в их собственном сценарии игрока, которая вызывает функцию в сценарии gameController, передавая объект игрока (я пробовал также через команду и rpc), что-то вроде этого: GameController.instance.RegisterPlayer(this);

Так что любой знает, какмогу ли я вызвать этот SyncEvent, чтобы зарегистрировать игрока на объекте, не являющемся игроком, управляемом сервером?

Большое спасибо.

Я прилагаю здесь краткое описание сценариев стенда, чтобы сделать еголегче понять:

GameController:

public class GameController : NetworkBehaviour
{

    public delegate void OnNewPlayerAddedDelegate();
    [SyncEvent]
    public event OnNewPlayerAddedDelegate EventOnNewPlayerAddedDelegate;

    List<GamePlayerManager> players = new List<GamePlayerManager>();

    public static GameController instance { get; private set; }

    float timePerTorn = 30f;
    bool isCountdown = false;
    [System.NonSerialized]
    public float countdownTime;
    int roundNumber = 0;

    int NumberOfPlayers;
    int NumberOfPlayersChanged;

    void Awake()
    {
        Debug.Log("Awaking ");
        if (instance != null)
        {
            Debug.Log("Destoring ");
            DestroyImmediate(this);
            return;
        }
        instance = this;
    }
    // Use this for initialization
    void Start()
    {
        if (!isServer)
        {
            return;
        }

        players = new List<GamePlayerManager>();
        StartCountdown(5f);//20
    }

    void Update()
    {
        if (isServer)
        {
            if (isCountdown)
            {
                countdownTime -= Time.deltaTime;
                if (countdownTime <= 0)
                {
                    AlterGlobalTurns();
                }
            }

        }
        NumberOfPlayers = NetworkManager.singleton.numPlayers;

        if (NumberOfPlayersChanged != NumberOfPlayers)

        {
            Debug.Log("num of players changed ---> " + NumberOfPlayers);
            NumberOfPlayersChanged = NumberOfPlayers;

            EventOnNewPlayerAddedDelegate();

            //RpcNewPlayerAdded();
            //CmdNewPlayerAdded();

        }
    }
    [ClientRpc]
    void RpcNewPlayerAdded()
    {
        Debug.Log("---------------- RpcNewPlayerAdded ------------");
        EventOnNewPlayerAddedDelegate();
    }
    [Command]
    void CmdNewPlayerAdded()
    {
        Debug.Log("---------------- CmdNewPlayerAdded ------------");
        EventOnNewPlayerAddedDelegate();
    }
    public void RegisterPlayer(GamePlayerManager player)
    {
        Debug.Log("player ---> " + player.name);
        if (players.Contains(player))
        {
            return;
        }
        Debug.Log("players ---> " + players);
        players.Add(player);
    }
}

PlayerScript:

public class GamePlayerManager : NetworkBehaviour
{

    [System.NonSerialized]
    public bool isPlayingOnTorn = true;

    void Awake()
    {
        GameController.instance.EventOnNewPlayerAddedDelegate += OnRegisterPlayer;   

    }
    private void Start()
    {

        if (!isLocalPlayer)
        {
            return;
        }
    }
    public override void OnStartServer()
    {
        GameObject gc = (GameObject)Instantiate(NetworkManager.singleton.spawnPrefabs[2], transform.position, transform.rotation);
        NetworkServer.Spawn(gc);

    }

    void OnRegisterPlayer(){

        if (isLocalPlayer)
        {
            //GameController.instance.RegisterPlayer(this);
            //RpcRegisterPlayer();
            CmdRegisterPlayer();
        }
    }

    [Command]
    void CmdRegisterPlayer(){
        Debug.Log("-------------Command Register player -------------");
        GameController.instance.RegisterPlayer(this);

    }
    [ClientRpc]
    void RpcRegisterPlayer()
    {
        Debug.Log("------------- RPC REgister Player -------------");
        GameController.instance.RegisterPlayer(this);
    }
}

1 Ответ

0 голосов
/ 28 ноября 2018

Я думаю, что я уже видел проблему здесь.

Проблема заключается в том, что GameController порождается playerScript (только если игрок также является хостом) в функции OnStartServer ().Итак, первая проблема заключается в том, что GameController не обнаруживает хост-плеер, потому что это не новые подключения.И вторая проблема - когда подключен второй клиент, GameController обнаруживает соединение с клиентом и отправляет сигнал о событии быстрее, чем пробуждение клиента, поэтому, когда клиент уже работает, сигнал пропал.

Я решилпроблема с удалением этого сигнала и проверкой непосредственно в playerScript, если GameController существует, то проверьте, зарегистрирован ли игрок уже.

Мой вопрос теперь состоит в том, что есть ли возможность экземпляра и пробуждения объектов сервера перед игроком (Host), что я понимаю, что ответ «нет», потому что, поскольку игрок является хостом, он должен быть запущен, чтобы иметь сервер.И второй вопрос: есть ли какой-либо сигнал о том, что подключен новый плеер, и подождите, пока он не проснется.

Большое спасибо.Вы можете проверить эту тему на форумах Unity: https://forum.unity.com/threads/multiplayer-syncevent-problem-with-non-player-objects.589309/

...