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
相关产品推荐
相关产品推荐

