协程作为异步、延时等待。还可以作为Update的解耦已读方案。
以一个UI淡进淡出为例。
不是用协程时,Lerp的更新都包含在Update方法中:
1 1 using UnityEngine; 2 2 using UnityEngine.UI; 3 3 4 4 namespace UI.MainMenu 5 5 { 6 6 public class FadeInOut : MonoBehaviour 7 7 { 8 8 [SerializeField]private Image fadeImage; 9 9 [SerializeField] private float fadeTime = 1f; 10 10 11 11 private float timer; 12 12 private bool isFadeOut = false; 13 13 private bool isFadeIn = false; 14 14 15 15 private void Awake() 16 16 { 17 17 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, 1); 18 18 isFadeIn = true; 19 19 isFadeOut = false; 20 20 timer = 0; 21 21 } 22 22 23 23 24 24 private void Update() 25 25 { 26 26 HandleFadeIn(); 27 27 HandleFadeOut(); 28 28 Debug.Log(fadeImage.color.a); 29 29 } 30 30 31 31 32 32 private void HandleFadeIn() 33 33 { 34 34 if (!isFadeIn) return; 35 35 if (timer > fadeTime) return; 36 36 timer = timer + Time.deltaTime; 37 37 // 让透明的从255 降低到 0 38 38 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, Mathf.Lerp(1, 0, timer / fadeTime)); 39 39 } 40 40 41 41 private void HandleFadeOut() 42 42 { 43 43 if (!isFadeOut) return; 44 44 if (timer > fadeTime) return; 45 45 timer = timer + Time.deltaTime; 46 46 // 让透明的从255 降低到 0 47 47 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, Mathf.Lerp(0, 1, timer / fadeTime)); 48 48 } 49 49 50 50 51 51 private void OnDestroy() 52 52 { 53 53 isFadeOut = true; 54 54 isFadeIn = false; 55 55 timer = 0; 56 56 } 57 57 } 58 58 }
使用协程后,可以分而治之
1 using System; 2 using System.Collections; 3 using UnityEngine; 4 using UnityEngine.UI; 5 6 namespace UI.MainMenu 7 { 8 public class FadeInOut : MonoBehaviour 9 { 10 [SerializeField] private Image fadeImage; 11 [SerializeField] private float fadeTime = 1f; 12 private float timer; 13 14 private void Awake() 15 { 16 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, 1); 17 StartCoroutine(FadeCoroutine(0, fadeTime, null)); 18 } 19 20 21 private void Update() 22 { 23 Debug.Log(fadeImage.color.a); 24 } 25 26 27 private void OnDestroy() 28 { 29 StartCoroutine(FadeCoroutine(1, fadeTime, null)); 30 } 31 32 33 IEnumerator FadeCoroutine(float targetAlpha, float duration, Action onComplete) 34 { 35 timer = 0; 36 while (timer < fadeTime) 37 { 38 timer = timer + Time.deltaTime; 39 // 让透明的从255 降低到 0 40 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, Mathf.Lerp(1, 0, timer / fadeTime)); 41 yield return null; 42 } 43 44 fadeImage.color = new Color(fadeImage.color.r, fadeImage.color.g, fadeImage.color.b, 0); 45 onComplete?.Invoke(); 46 } 47 } 48 }