如何在Unity中仅停止部分协程实例而不影响其他协程运行
Unity淡入淡出协程多触发冲突解决方案
冲突本质是同一个渲染组件同一时间运行了多个修改alpha值的Fade协程,导致最终alpha计算结果不符合预期。可通过按渲染对象存储活跃协程引用的方式精准控制协程启停,不会影响项目中其他无关协程运行:
实现步骤
- 定义字典存储每个渲染器对应的活跃淡变协程,作为类成员变量:
private Dictionary<Renderer, Coroutine> _activeFadeRoutines = new Dictionary<Renderer, Coroutine>();
- 封装统一的协程启动方法,启动新协程前先停止同一渲染器上正在运行的旧淡变协程:
public void StartFadeOut(Renderer rend, float speed) { // 停止同渲染器上的旧协程 if (_activeFadeRoutines.TryGetValue(rend, out Coroutine existingRoutine)) { StopCoroutine(existingRoutine); _activeFadeRoutines.Remove(rend); } // 存储新协程引用 Coroutine newRoutine = StartCoroutine(FadeOut(rend, speed)); _activeFadeRoutines[rend] = newRoutine; } // FadeIn的启动方法逻辑完全一致,仅调用的协程换成FadeIn即可 public void StartFadeIn(Renderer rend, float speed) { if (_activeFadeRoutines.TryGetValue(rend, out Coroutine existingRoutine)) { StopCoroutine(existingRoutine); _activeFadeRoutines.Remove(rend); } Coroutine newRoutine = StartCoroutine(FadeIn(rend, speed)); _activeFadeRoutines[rend] = newRoutine; }
- 修改原协程逻辑,执行完成后自动清理字典中的无效引用:
IEnumerator FadeOut(Renderer rend, float speed) { while (rend.material.color.a > 0) { Color objectColor = rend.material.color; float fadeAmount = objectColor.a - (speed * Time.deltaTime); objectColor = new Color(objectColor.r, objectColor.g, objectColor.b, fadeAmount); rend.material.color = objectColor; yield return null; } // 协程结束后清理记录 if (_activeFadeRoutines.ContainsKey(rend)) { _activeFadeRoutines.Remove(rend); } } // FadeIn协程结束后添加同样的清理逻辑即可 IEnumerator FadeIn(Renderer rend, float speed) { while (rend.material.color.a < 1) { Color objectColor = rend.material.color; float fadeAmount = objectColor.a + (speed * Time.deltaTime); objectColor = new Color(objectColor.r, objectColor.g, objectColor.b, fadeAmount); rend.material.color = objectColor; yield return null; } if (_activeFadeRoutines.ContainsKey(rend)) { _activeFadeRoutines.Remove(rend); } }
调用方式
原有触发位置直接调用封装后的启动方法即可,无需手动处理协程停止逻辑:
// 原来的StopAllCoroutines()可以完全删掉 StartFadeOut(tilemap,1f);
该方案支持多个渲染组件同时运行各自的淡变协程,互不干扰,仅会停止同一渲染组件上的旧协程,完全不会影响项目中其他功能的协程运行。
内容的提问来源于stack exchange,提问作者Denis Denis
相关产品推荐
相关产品推荐

