【问题标题】:Multiplayer [SyncEvent] problem with non-player objects非玩家对象的多人 [SyncEvent] 问题
【发布时间】:2019-04-29 12:01:31
【问题描述】:

我正在开发一款基于回合的多人游戏。 所以我有一个名为 gameController 的脚本,它具有全局计时器来改变回合,并选择在当前回合中哪些玩家正在攻击和哪些玩家正在防守。 这个脚本是一个附加到gameObject 的单例,上面有一个网络标识(这个网络标识没有被服务器标记为控制器的复选框)。我试图让这个游戏对象在服务器连接时生成给所有客户端,并且让游戏对象已经在场景中(展台不工作)。

嗯,主要问题是在 gameController 脚本中,我在更新函数中有一个检查器来检查是否连接了任何新玩家。如果已连接,它应该调用一个名为 EventOnNewPlayerAddedDelegatesyncEvent(我尝试直接调用它,也使用 [command] 并使用 [ClientRpc])让玩家知道他们必须调用名为“OnRegisterPlayer”的函数",这是他们自己的播放器脚本中的一个函数,它调用 gameController 脚本上的一个函数,传递播放器对象(我也通过命令和 rpc 尝试过),如下所示:GameController.instance.RegisterPlayer(this);

那么任何人都知道如何触发这个SyncEvent 将玩家注册到服务器控制的非玩家对象?

非常感谢。

我在这里附上一个展位脚本的简要说明,以便于理解:

游戏控制器:

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

播放器脚本:

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

【问题讨论】:

    标签: unity3d multiplayer unity3d-unet


    【解决方案1】:

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

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

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

    我现在的问题是,如果无论如何要在播放器(主机)之前实例化和唤醒服务器对象,我知道答案是“否”,因为播放器是主机,它需要运行才能拥有服务器。 第二个问题是,是否有任何信号或任何信号知道新玩家已连接,并等到它被唤醒。

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

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 2016-12-21
      • 1970-01-01
      • 2023-02-08
      相关资源
      最近更新 更多