首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >非玩家对象的多玩家[SyncEvent]问题

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

Stack Overflow用户
提问于 2018-11-28 01:16:34
回答 1查看 411关注 0票数 0

我正在开发一个基于轮换的多人游戏。所以我有一个名为gameController的脚本,它有全局计时器来改变轮次,还可以选择在当前轮次中哪些球员在进攻,哪些球员在防守。此脚本是附加到带有网络标识的gameObject的单例脚本(此网络标识没有由服务器标记为控制器的复选框)。我试图在服务器连接时将此游戏对象派生到所有客户端,并且使该游戏对象已存在于场景中(展位情况不起作用)。

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

所以有谁知道如何触发此SyncEvent将播放器注册到由服务器控制的非播放器对象?

非常感谢。

我在这里附上一个简短的展台脚本,使其更容易理解:

GameController:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-11-28 23:06:56

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

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

我解决了删除这个信号的问题,如果GameController存在,直接在playerScript中检查,然后检查播放器是否已经注册。

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53504879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档