Unity中使用Foreach遍历子对象并添加执行延迟的问题求解
问题根源
你当前的写法是同步阻塞逻辑,ReelIn 方法调用后会在当前帧直接执行所有逻辑:
进入while循环后主线程被完全占用,Update 方法根本得不到执行机会,simpleTimer 的值永远不会增长,直接造成死循环,Unity自然会出现无响应的情况。
正确实现方案(协程实现)
Unity的协程可以非常方便的实现帧间延时、分步执行的需求,是处理这类需求的首选方案,代码如下:
using System.Collections; using UnityEngine; public class YourComponent : MonoBehaviour { public void ReelIn() { // 启动协程处理子对象遍历逻辑 StartCoroutine(ReelInCoroutine()); } IEnumerator ReelInCoroutine() { // 先获取所有子对象的Transform Transform[] allChildren = gameObject.GetComponentsInChildren<Transform>(); foreach (Transform child in allChildren) { // GetComponentsInChildren默认会包含父对象自身,不需要处理可以加这行跳过 if(child == transform) continue; // 在这里写激活子对象组件的逻辑,示例: // child.GetComponent<你要激活的组件类型>().enabled = true; // 等待0.5秒后再处理下一个子对象 yield return new WaitForSeconds(0.5f); } } }
替代方案(Update轮询实现)
如果不想使用协程,也可以用队列+变量标记执行状态,在Update里分步处理:
using System.Collections.Generic; using UnityEngine; public class YourComponent : MonoBehaviour { private Queue<Transform> childProcessQueue = new Queue<Transform>(); private const float ProcessInterval = 0.5f; private float timer; public void ReelIn() { // 先把所有需要处理的子对象加入队列 childProcessQueue.Clear(); foreach (Transform child in gameObject.GetComponentsInChildren<Transform>()) { if(child != transform) childProcessQueue.Enqueue(child); } timer = ProcessInterval; } private void Update() { if (childProcessQueue.Count == 0) return; timer += Time.deltaTime; if (timer >= ProcessInterval) { timer = 0; Transform currentChild = childProcessQueue.Dequeue(); // 在这里写激活组件的逻辑 // currentChild.GetComponent<你要激活的组件类型>().enabled = true; } } }
注意:
GetComponentsInChildren<Transform>()默认会把父节点自身的Transform也返回,如果你不需要处理父对象,记得加判断跳过,不然会多执行一次延时逻辑。
内容的提问来源于stack exchange,提问作者Joey
相关产品推荐
相关产品推荐

