unity 有关协程脚本的停止
创始人
2024-06-02 07:11:45
0

最近总结了一个协程使用的文章,实现了一个利用协程使物体自带材质闪烁的脚本,然后在使用过程中遇到了如下情况:取消勾选(或者禁用脚本)协程不会停止,闪烁效果依然存在,即协程没有被终止

using System.Collections;
using UnityEngine;public class Glinting : MonoBehaviour
{/// /// 闪烁颜色/// public Color color = new Color(1, 0, 1, 1);/// /// 最低发光亮度,取值范围[0,1],需小于最高发光亮度。/// [Range(0.0f, 1.0f)]public float minBrightness = 0.0f;/// /// 最高发光亮度,取值范围[0,1],需大于最低发光亮度。/// [Range(0.0f, 1)]public float maxBrightness = 0.5f;/// /// 闪烁频率,取值范围[0.2,30.0]。/// [Range(0.2f, 30.0f)]public float rate = 1;[Tooltip("勾选此项则启动时自动开始闪烁")][SerializeField]private bool _autoStart = false;private float _h, _s, _v;           // 色调,饱和度,亮度private float _deltaBrightness;     // 最低最高亮度差private Renderer _renderer;private Material _material;private readonly string _keyword = "_EMISSION";private readonly string _colorName = "_EmissionColor";private Coroutine _glinting;private void Start(){_renderer = gameObject.GetComponent();_material = _renderer.material;if (_autoStart){StartGlinting();}}/// /// 校验数据,并保证运行时的修改能够得到应用。/// 该方法只在编辑器模式中生效!!!/// private void OnValidate(){// 限制亮度范围if (minBrightness < 0 || minBrightness > 1){minBrightness = 0.0f;Debug.LogError("最低亮度超出取值范围[0, 1],已重置为0。");}if (maxBrightness < 0 || maxBrightness > 1){maxBrightness = 1.0f;Debug.LogError("最高亮度超出取值范围[0, 1],已重置为1。");}if (minBrightness >= maxBrightness){minBrightness = 0.0f;maxBrightness = 1.0f;Debug.LogError("最低亮度[MinBrightness]必须低于最高亮度[MaxBrightness],已分别重置为0/1!");}// 限制闪烁频率if (rate < 0.2f || rate > 30.0f){rate = 1;Debug.LogError("闪烁频率超出取值范围[0.2, 30.0],已重置为1.0。");}// 更新亮度差_deltaBrightness = maxBrightness - minBrightness;// 更新颜色// 注意不能使用 _v ,否则在运行时修改参数会导致亮度突变float tempV = 0;Color.RGBToHSV(color, out _h, out _s, out tempV);}/// /// 开始闪烁。/// public void StartGlinting(){_material.EnableKeyword(_keyword);if (_glinting != null){StopCoroutine(_glinting);}_glinting = StartCoroutine(IEGlinting());}/// /// 停止闪烁。/// public void StopGlinting(){_material.DisableKeyword(_keyword);if (_glinting != null){StopCoroutine(_glinting);}}/// /// 控制自发光强度。/// /// private IEnumerator IEGlinting(){Color.RGBToHSV(color, out _h, out _s, out _v);_v = minBrightness;_deltaBrightness = maxBrightness - minBrightness;bool increase = true;while (true){if (increase){_v += _deltaBrightness * Time.deltaTime * rate;increase = _v <= maxBrightness;}else{_v -= _deltaBrightness * Time.deltaTime * rate;increase = _v <= minBrightness;}_material.SetColor(_colorName, Color.HSVToRGB(_h, _s, _v));//_renderer.UpdateGIMaterials();yield return null;}}
}

在这里插入图片描述
如图所示,即使取消勾选(或者禁用脚本)协程不会停止,闪烁效果依然存在。
通过在 MonoBehaviour 实例上将 enabled 设置为 false 来禁用 MonoBehaviour 时,协程不会停止。

协程是挂在MonoBehaviour上的,必须要通过一个MonoBehaviour才能开启协程。
MonoBehaviour被Disable的时候协程会继续执行只有MonoBehaviour被销毁的时候协程才会被销毁。
协程看起来有点像是轻量级线程,但是本质上协程还是运行在主线程上的,协程更类似于Update()方法,Unity会每一帧去检测协程需不需要被唤醒。
因为协程是“跟着gameobject走的”所以禁用这个脚本并不会终止协程

可以使用 StopCoroutineStopAllCoroutines 来停止协程。 当用 SetActive(false) 禁用某个协程所附加到的游戏对象时,该协程也将停止。调用 Destroy(example)(其中 example 是一个 MonoBehaviour 实例)会立即触发 OnDisable,并会处理协程,从而有效地停止协程。

然而 我们往往可能需要在场景中保留这个闪烁的物体,我们只需要在**OnDisable()**中放入写好的停止协程的函数即可

 public void StopGlinting(){_material.DisableKeyword(_keyword);if (_glinting != null){StopCoroutine(_glinting);}}

然后,禁用脚本或者取消勾选 (调用OnDisable生命周期)协程就会终止。

相关内容

热门资讯

安卓系统对比骁龙,性能与生态的... 你有没有想过,为什么你的手机里装的是安卓系统,而不是苹果的iOS呢?又或者,为什么你的安卓手机里搭载...
qt程序安卓系统运行,基于Qt... 你有没有想过,为什么有些手机上的程序运行得那么顺畅,而有些却总是卡得让人抓狂?今天,就让我来给你揭秘...
安卓系统免费应用推荐,助你畅享... 手机里的应用是不是越来越多,有时候都挑花眼了呢?别急,今天我就来给你推荐一些安卓系统上的免费应用,让...
安卓系统视频通话app,打造无... 你有没有发现,现在手机上的视频通话功能越来越强大了?尤其是安卓系统上的那些视频通话app,简直让人爱...
安卓系统发现高危病毒,守护手机... 亲爱的手机用户们,最近可是有个大消息在安卓系统用户群里炸开了锅!没错,就是安卓系统发现了一款高危病毒...
安卓系统疯狂弹广告,揭秘广告软... 你有没有遇到过这种情况?手机里突然弹出一个广告,让你瞬间心情大崩溃?没错,说的就是安卓系统那让人头疼...
ebook 10进入安卓系统 你有没有发现,最近你的安卓手机里多了一个新伙伴——那就是电子书(ebook)10!没错,就是那个我们...
安卓系统如何调听筒,安卓系统调... 手机听筒声音突然变小了?别急,让我来教你如何轻松调教安卓系统的听筒,让它重新恢复活力!一、检查音量设...
安卓系统是怎么手机,解锁智能生... 你有没有想过,我们每天不离手的安卓手机,它背后的安卓系统究竟是怎么一回事呢?今天,就让我带你一探究竟...
安卓系统能代替windows系... 你有没有想过,我们日常使用的安卓系统和Windows系统,哪个才是真正的霸主呢?是不是有时候觉得安卓...
lp108安卓系统,功能特点与... 你有没有听说最近LP108安卓系统火得一塌糊涂?没错,就是那个让无数手机用户都为之疯狂的新系统!今天...
安卓系统挂载u盘,轻松实现数据... 你有没有想过,你的安卓手机或平板电脑突然变成了一个移动的U盘?没错,就是那种可以随意存取文件的神奇设...
i5 安卓系统,引领智能终端新... 你有没有想过,为什么你的手机总是卡得要命,而别人的手机却能流畅如丝?是不是因为你的手机搭载了那个传说...
安卓手机系统没有升级,揭秘潜在... 你有没有发现,你的安卓手机系统好像好久没升级了呢?是不是觉得有点out了?别急,今天就来给你详细聊聊...
安卓14系统定制v,创新功能与... 你知道吗?最近安卓系统又出新花样了!安卓14系统定制版V,这名字听起来就让人兴奋不已。今天,就让我带...
手机安卓系统越高越好,探索最新... 你有没有发现,每次手机更新系统,你的手机就像脱胎换骨了一样?没错,说的就是你,那个安卓手机!今天,咱...
鸿蒙系统怎么用回安卓,轻松实现... 你是不是也和我一样,对鸿蒙系统的新鲜感还没过,却又忍不住想回到熟悉的安卓世界?别急,今天就来手把手教...
苹果7跟安卓系统,性能对决与用... 你有没有想过,为什么苹果7那么受欢迎,而安卓系统却有着庞大的用户群体?今天,我们就来聊聊这个话题,看...
安卓手机刷简化系统,轻松实现流... 你有没有想过,你的安卓手机其实可以变得更加轻快、流畅呢?没错,就是通过刷简化系统!今天,就让我带你一...
社保掌上通安卓系统,轻松掌握在... 你有没有发现,现在的生活越来越离不开手机了?无论是购物、聊天还是办公,手机都能轻松搞定。这不,今天就...