Unity常用协程功能封装

1.前言

unity开发过程中,经常用到一些特定的协程功能,比如延时触发、等待触发、重复操作等。unity自带Invoke以及InvokeRepeating方法,但这些方法均采用反射机制,性能消耗,而且代码混淆时极其容易出错。所以再次对这些功能做以下简单封装。方便后续使用。

2.CoroutineJobCenter

CoroutineJobCenter封装了需要的基本方法。

2.1 延时触发

延时一定时间触发。

        public IEnumerator StartJobDelayed(float delayedTime, Action action)
        {
   
   
            yield return new WaitForSeconds(delayedTime);

            if (action != null)
            {
   
   
                action();
            }
        }

        public IEnumerator StartJobDelayed<T>(float delayedTime, Action<T> action, T t)
        {
   
   
            yield return new WaitForSeconds(delayedTime);

            if (action != null)
            {
   
   
                action(t);
            }
        }

2.2 等待触发

等待某一条件返回true时触发,采用unity自带的WaitUntil类。

        public IEnumerator StartJobUntil(Func<bool> funtion, Action action)
        {
   
   
            yield return new WaitUntil(funtion);

            if (action != null)
            {
   
   
                action();
            }
        }

        public IEnumerator StartJobUntil<T>(Func<bool> funtion, Action<T> action, T t)
        {
   
   
            yield return new WaitUntil(funtion);

            if (action != null)
            {
   
   
                action(t);
            }
        }

2.3 重复触发

2.3.1 每隔一帧触发,并规定触发次数。

<think>好的,我现在需要帮助用户了解Unity中的协程概念、用法以及工作原理。首先,我得回忆一下自己知道的关于Unity协程的知识,并结合用户提供的引用内容来组织回答。 用户提到了几个引用,其中引用[1]提到UniTask作为异步库,但用户的问题主要是关于协程本身,所以可能需要比较协程和UniTask的不同。引用[2]、[3]、[4]、[5]则直接涉及协程的教程、启动方式、模拟Update的方法以及底层机制。这些引用应该能用来支持回答。 首先,协程的定义。协程Unity中用于处理异步操作的一种机制,允许在多个帧中分段执行代码。常规函数一旦调用就会执行到完成,而协程可以在中途暂停,比如等待一段时间或某个条件满足后再继续。这点需要明确,可能引用[2]和[3]中的内容,比如启动协程的代码构造对象并由DelayedCallManager管理。 接下来是协程的启动方式,用户可能需要知道如何用StartCoroutine,以及如何传递IEnumerator。需要示例代码,比如使用IEnumerator函数,并在其中使用yield return语句。例如,等待一帧用yield return null,或者等待时间如yield return new WaitForSeconds(1f)。引用[5]中提到yield return的YieldInstruction类,当KeepWaiting为true时会暂停,这可能涉及到底层机制的解释。 然后,工作原理部分。需要解释协程Unity中的执行机制,比如协程被转化为IEnumerator对象,由Unity引擎逐帧驱动。每次yield return会返回一个条件,引擎检查条件是否满足,决定是否继续执行。这部分可以引用[3]和[5],比如DelayedCallManager的作用,以及YieldInstruction的KeepWaiting属性。 可能还需要比较协程和普通函数,以及协程和UniTask的区别。根据引用[1],UniTask基于async/await,性能更好,但协程Unity内置的,使用更广泛。但用户的问题主要关注协程,所以这部分可能作为补充。 用户还可能需要应用场景的示例,比如加载资源、分步生成敌人、延迟执行等。可以结合引用[4]中的模拟Update,比如用协程代替Update进行定时检测,减少每帧的开销。 此外,需要提到协程的停止方法,比如StopCoroutine和StopAllCoroutines,以及注意事项,比如在对象销毁时协程会自动停止,但最好手动管理。 现在,组织这些内容,确保结构清晰,分点说明,使用代码示例,并正确引用提供的资料。例如,在解释启动方式时引用[3],在底层机制时引用[5],在教程和协程应用时引用[2]和[4]。 最后,生成相关问题,可能涉及性能优化、与多线程比较、常见错误处理等。确保问题与用户可能的后续疑问相关。 检查是否有遗漏点,比如协程的执行依赖于MonoBehaviour,不能在非继承自MonoBehaviour的类中使用,或者协程的嵌套执行(如yield return另一个协程)。引用[5]中提到嵌套协程的原理,可能需要简要说明。 确保所有数学公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及较少数学内容,但如果有比如时间计算,可能需要正确应用格式。例如,等待时间的公式如$t = 1.0$秒,但可能不需要复杂公式。 最后,用中文回答,保持口语化,但结构清晰,分步骤解释,帮助用户逐步理解。</think>### Unity协程概念及使用教程 #### 一、协程的基本概念 协程(Coroutine)是Unity中实现**分段异步执行**的核心机制。它允许将代码逻辑拆分为多个步骤,在**特定条件满足时恢复执行**(例如等待1秒、加载完成等)。与普通函数不同,协程通过`yield return`语句主动暂停,交由Unity引擎管理恢复时机[^2][^3]。 #### 二、协程的使用方法 1. **定义协程函数** 协程函数需返回`IEnumerator`类型,并在内部使用`yield return`控制执行流程: ```csharp IEnumerator MyCoroutine() { Debug.Log("开始执行"); yield return new WaitForSeconds(1f); // 暂停1秒 Debug.Log("1秒后继续"); } ``` 2. **启动协程** 通过`StartCoroutine()`方法启动: ```csharp void Start() { StartCoroutine(MyCoroutine()); } ``` 3. **常用控制指令** - `yield return null`:等待下一帧 - `yield return new WaitForSeconds(t)`:等待$t$秒 - `yield return StartCoroutine(AnotherCoroutine())`:嵌套执行其他协程[^5] #### 三、工作原理(底层机制) 1. **协程对象化** 协程启动时会被封装为`IEnumerator`对象,Unity的`DelayedCallManager`根据条件调度其执行[^3]。 2. **执行流程控制** - 每次迭代调用`MoveNext()`方法推进代码执行 - 当遇到`YieldInstruction`(如`WaitForSeconds`)时,检查其`keepWaiting`属性: - 若为`true`:暂停协程 - 若为`false`:继续执行下一段代码 $$流程图示例:\\ 协程启动 \rightarrow 执行至yield \rightarrow 注册到调度器 \rightarrow 条件满足后恢复$$ #### 四、典型应用场景 1. **分帧加载**:避免卡顿 ```csharp IEnumerator LoadData() { for(int i=0; i<1000; i++){ ProcessDataChunk(i); yield return null; // 每帧处理一部分 } } ``` 2. **定时触发**:替代Update检测 ```csharp IEnumerator CheckStatus() { while(true) { UpdateEnemyAI(); yield return new WaitForSeconds(0.5f); // 每0.5秒执行一次[^4] } } ``` #### 五、注意事项 1. **生命周期管理** - 使用`StopCoroutine()`停止特定协程 - 禁用GameObject或销毁组件时,其启动的协程会自动终止 2. **性能对比** 协程比传统多线程更轻量,但大量协程仍可能影响性能。对性能敏感场景可考虑UniTask等优化方案[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值