You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity分屏2D游戏中实现跨副本关卡等待界面的方法

实现2D分屏副本游戏的关卡同步与等待提示

嘿,这个需求在多人同步类游戏里挺常见的,我来给你捋捋具体的实现思路和代码示例,保证能搞定这个关卡同步的问题!

1. 核心:全局状态管理器(Singleton模式)

首先你需要一个全局的状态管理类,用来统一记录每个玩家的关卡完成状态——毕竟两个玩家在各自副本里,得有个“全局账本”来同步进度。用Singleton模式最合适,确保整个游戏只有一个实例,切换场景也不会丢失。

using UnityEngine;

public class GameSessionManager : MonoBehaviour
{
    // 单例实例,全局可访问
    public static GameSessionManager Instance { get; private set; }

    // 记录两个玩家是否完成当前关卡(索引0对应玩家1,索引1对应玩家2)
    private bool[] playerLevelComplete = new bool[2];

    private void Awake()
    {
        // 确保单例唯一,避免重复创建
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
        }
        else
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }

    // 标记指定玩家完成当前关卡
    public void MarkPlayerLevelComplete(int playerIndex)
    {
        if (playerIndex >= 0 && playerIndex < playerLevelComplete.Length)
        {
            playerLevelComplete[playerIndex] = true;
            // 标记后立刻检查是否所有玩家都完成了
            CheckAllPlayersComplete();
        }
    }

    // 重置关卡完成状态(进入下一关时调用)
    public void ResetLevelCompleteStatus()
    {
        for (int i = 0; i < playerLevelComplete.Length; i++)
        {
            playerLevelComplete[i] = false;
        }
    }

    // 检查是否所有玩家都完成当前关卡
    private void CheckAllPlayersComplete()
    {
        bool allComplete = true;
        foreach (bool completed in playerLevelComplete)
        {
            if (!completed)
            {
                allComplete = false;
                break;
            }
        }

        if (allComplete)
        {
            // 所有玩家都完成,触发关卡切换逻辑(加个延迟给玩家看提示)
            StartCoroutine(LoadNextLevelAfterDelay());
        }
    }

    // 延迟加载下一关,给玩家过渡体验
    private System.Collections.IEnumerator LoadNextLevelAfterDelay()
    {
        // 先隐藏所有玩家的等待提示
        UIManager.Instance.HideWaitPrompt();
        // 显示统一的完成提示
        UIManager.Instance.ShowTransitionMessage();
        yield return new WaitForSeconds(2f);
        // 加载下一关(这里用Unity默认的场景管理器,记得在Build Settings里添加关卡)
        UnityEngine.SceneManagement.SceneManager.LoadScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex + 1);
        // 重置状态,为下一关做准备
        ResetLevelCompleteStatus();
    }

    // 对外提供查询指定玩家是否完成关卡的方法
    public bool IsPlayerComplete(int playerIndex)
    {
        return playerIndex >= 0 && playerIndex < playerLevelComplete.Length ? playerLevelComplete[playerIndex] : false;
    }
}

2. 玩家关卡完成触发逻辑

每个玩家的副本里,当玩家达成关卡目标(比如到达终点、消灭所有敌人)时,调用状态管理器的标记方法,同时显示等待提示。

比如给玩家的终点触发器加这个脚本:

using UnityEngine;

public class LevelEndTrigger : MonoBehaviour
{
    public int playerIndex; // 在Inspector里设置对应的玩家索引(0或1)
    public GameObject waitPrompt; // 绑定该玩家的"Please Wait"UI面板

    private void OnTriggerEnter2D(Collider2D other)
    {
        // 检查碰撞的是对应玩家(记得给玩家设置对应的Tag,比如Player1、Player2)
        if (other.CompareTag($"Player{playerIndex + 1}"))
        {
            // 标记该玩家完成关卡
            GameSessionManager.Instance.MarkPlayerLevelComplete(playerIndex);
            // 显示等待提示
            waitPrompt.SetActive(true);
            // 禁用触发器,防止重复触发
            GetComponent<Collider2D>().enabled = false;
        }
    }
}

3. UI管理类(统一控制提示显示)

做一个专门的UI管理类,把所有提示的显示隐藏逻辑集中起来,避免代码分散:

using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance { get; private set; }

    public GameObject[] playerWaitPrompts; // 两个玩家的"Please Wait"提示面板
    public Text transitionMessageText; // 关卡切换时的过渡文本

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
        }
        else
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        // 初始状态隐藏所有提示
        HideWaitPrompt();
        transitionMessageText.gameObject.SetActive(false);
    }

    // 显示指定玩家的等待提示
    public void ShowWaitPrompt(int playerIndex)
    {
        if (playerIndex >= 0 && playerIndex < playerWaitPrompts.Length)
        {
            playerWaitPrompts[playerIndex].SetActive(true);
        }
    }

    // 隐藏所有等待提示
    public void HideWaitPrompt()
    {
        foreach (var prompt in playerWaitPrompts)
        {
            prompt.SetActive(false);
        }
    }

    // 显示关卡切换过渡消息
    public void ShowTransitionMessage()
    {
        transitionMessageText.gameObject.SetActive(true);
        transitionMessageText.text = "All Players Complete! Loading Next Level...";
    }
}

4. 额外注意点

  • 单例初始化:只需要在游戏的初始场景放置GameSessionManager和UIManager,因为用了DontDestroyOnLoad,切换场景时会保留实例。
  • 玩家索引对应:一定要在Inspector里给每个触发器和UI组件设置正确的玩家索引,避免搞混玩家1和玩家2的状态。
  • 异步场景加载:如果关卡较大,可以把SceneManager.LoadScene换成LoadSceneAsync,配合进度条显示加载状态,体验更好。
  • 测试验证:单独模拟一个玩家完成关卡,检查另一个玩家的等待提示是否正常显示,直到两个玩家都完成后是否自动切换关卡。

这样一套实现下来,就能完美满足你的需求:玩家完成自己的关卡后显示“Please Wait”提示,直到所有玩家都完成,才一起进入下一关~

内容的提问来源于stack exchange,提问作者Liam Flanagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:05:30