非玩家对象的多玩家[SyncEvent]问题

时间:2018-11-27 17:16:34

标签: unity3d multiplayer unity3d-unet

我正在开发基于回合的多人游戏。 因此,我有一个名为gameController的脚本,该脚本具有全局计时器来更改回合,还可以选择当前回合中攻击的玩家和防御的玩家。 该脚本是一个附加到gameObject并带有网络标识的单例(此网络标识没有复选框标记为服务器控制)。当服务器连接时,我试图将这个游戏对象生成给所有客户端,并且还试图将游戏对象放置在场景中(展位无法使用)。

好吧,主要的问题是在gameController脚本中,我在更新功能中有一个检查器来检查是否连接了任何新玩家。万一已连接,它应该调用一个名为syncEvent的{​​{1}}(我尝试直接调用它,也使用[command]和[ClientRpc])来让玩家知道他们必须调用他们的名为“ OnRegisterPlayer”的函数,这是他们自己的播放器脚本中的函数,该函数在gameController脚本上调用一个函数,传递播放器对象(我也通过command和rpc尝试过),如下所示:EventOnNewPlayerAddedDelegate

任何人都知道我该如何触发此GameController.instance.RegisterPlayer(this);来将播放器注册到服务器控制的非播放器对象?

非常感谢您。

我在此处附上简短的Boots脚本,以使其更易于理解:

GameController:

SyncEvent

PlayerScript:

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);
    }
}

1 个答案:

答案 0 :(得分:0)

我想我已经在这里看到了问题。

问题在于GameController是由OnStartServer()函数中的playerScript(即使玩家也是主机)产生的。因此,第一个问题是GameController不能检测主机玩家,因为它不是新连接。第二个问题是当连接了第二个客户端时,GameController会检测到客户端连接,并比客户端唤醒更快地发送事件信号,因此当客户端已经在工作时,信号消失了。

我解决了删除此信号并直接在playerScript中检查GameController是否存在然后检查玩家是否已经注册的问题。

我现在的问题是,是否有任何实例可以在播放器(主机)之前唤醒服务器对象,我知道答案是“否”,因为作为播放器是主机,它需要运行才能拥有服务器。 第二个问题是,是否有信号或信号知道新播放器已连接,请等待它唤醒。

非常感谢。 您可以在Unity论坛上检查漏洞:https://forum.unity.com/threads/multiplayer-syncevent-problem-with-non-player-objects.589309/