Unity中如何阻止IEnumerator协程导致的场景重复加载循环?
解决Unity协程循环加载场景的问题
你的问题根源很明确:每个场景中的Anim脚本在Start时都会启动Timer协程,导致切换到其他场景后,新场景里的脚本又开始10秒倒计时,到点就切回场景1。下面是几个直接可行的解决办法:
办法一:只在场景1启动协程
修改代码,判断当前场景是不是场景1,只有在场景1时才启动倒计时协程。这样切换到其他场景后,脚本不会触发倒计时,自然不会自动切回。
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class Anim : MonoBehaviour { IEnumerator Timer() { yield return new WaitForSeconds(10f); SceneManager.LoadScene(1); } void Start() { // 只有当前是场景1时,才启动协程 if (SceneManager.GetActiveScene().buildIndex == 1) { StartCoroutine(Timer()); } } }
办法二:用状态变量控制(修复报错版)
之前用状态变量报错,大概率是没做好状态的跨场景传递或初始化。可以用静态变量来保存状态,标记是否需要启动协程:
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class Anim : MonoBehaviour { // 静态变量会跨场景保留值 public static bool shouldStartTimer = true; IEnumerator Timer() { yield return new WaitForSeconds(10f); SceneManager.LoadScene(1); // 切回场景1后重置状态,保证下次能正常启动 shouldStartTimer = true; } void Start() { if (shouldStartTimer) { StartCoroutine(Timer()); } } // 把这个方法绑定到Play按钮的点击事件上 public void OnPlayButtonClicked() { // 标记不需要启动协程,避免切换场景后触发倒计时 shouldStartTimer = false; SceneManager.LoadScene("你的目标场景名称"); // 替换成实际场景名或索引 } }
注意:一定要把OnPlayButtonClicked绑定到Play按钮的点击事件上,这样点击按钮切换场景时,会先把状态改成false,新场景里的Anim脚本就不会启动协程了。
办法三:停止跨场景持久化对象的协程
如果你的Anim对象设置了DontDestroyOnLoad(场景切换不销毁),那它会一直运行协程。这种情况要在场景切换时停止协程:
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class Anim : MonoBehaviour { private Coroutine timerCoroutine; IEnumerator Timer() { yield return new WaitForSeconds(10f); SceneManager.LoadScene(1); } void Start() { timerCoroutine = StartCoroutine(Timer()); } // 监听场景切换事件 void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.buildIndex != 1) { // 切换到非场景1时,停止协程 if (timerCoroutine != null) { StopCoroutine(timerCoroutine); timerCoroutine = null; } } else { // 回到场景1时,重新启动协程(如果需要) if (timerCoroutine == null) { timerCoroutine = StartCoroutine(Timer()); } } } }
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

