当前位置:   article > 正文

Unitask学习记录-附工程文件

Unitask学习记录-附工程文件

工程文件下载

  1. using Cysharp.Threading.Tasks;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. using UnityEngine.Networking;
  7. using UnityEngine.SceneManagement;
  8. public class UniTaskTest : MonoBehaviour
  9. {
  10. private UniTaskSys uniTaskSys;
  11. public Image img_Test;
  12. //百度一张图片:右击,在新标签页中打开图像,复制url
  13. private string url;
  14. private bool isO_Down;
  15. private bool isP_Down;
  16. private void Awake()
  17. {
  18. uniTaskSys = new UniTaskSys();
  19. url = "https://n.sinaimg.cn/sinacn18/600/w1920h1080/20180508/2a45-haichqy4087272.jpg";
  20. }
  21. private void Start()
  22. {
  23. //AsyncLoadTextAsset("1");
  24. LoadScene("Demo");
  25. //AsyncWebRequestTexture(url);
  26. //uniTaskSys.DelayTest(this);
  27. WhenAllTest();
  28. WhenAnyTest();
  29. }
  30. private void Update()
  31. {
  32. if (Input.GetKeyDown(KeyCode.O))
  33. {
  34. isO_Down = true;
  35. }
  36. if (Input.GetKeyDown(KeyCode.P))
  37. {
  38. isP_Down = true;
  39. }
  40. }
  41. private async void AsyncLoadTextAsset(string path)
  42. {
  43. TextAsset textAsset = await uniTaskSys.AsyncLoad<TextAsset>(path) as TextAsset;
  44. Debug.Log(textAsset.text);
  45. }
  46. private void LoadScene(string sceneName)
  47. {
  48. uniTaskSys.AsyncLoadScene(sceneName);
  49. }
  50. public async void AsyncWebRequestTexture(string url)
  51. {
  52. var webRequest = UnityWebRequestTexture.GetTexture(url);
  53. var asyncOperation = await webRequest.SendWebRequest();
  54. Texture2D texture2D = ((DownloadHandlerTexture)asyncOperation.downloadHandler).texture;
  55. img_Test.sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), new Vector2(0.5f, 0.5f));
  56. img_Test.SetNativeSize();
  57. }
  58. /// <summary>
  59. /// 当两个条件都符合了才执行后面操作
  60. /// </summary>
  61. public async void WhenAllTest()
  62. {
  63. var firstOperation = UniTask.WaitUntil(() => isO_Down);
  64. var secondOperation = UniTask.WaitUntil(() => isP_Down);
  65. await UniTask.WhenAll(firstOperation, secondOperation);
  66. // 注意,whenAll可以用于平行执行多个资源的读取,非常有用!
  67. // var (a, b, c) = await UniTask.WhenAll(
  68. //LoadAsSprite("foo"),
  69. //LoadAsSprite("bar"),
  70. //LoadAsSprite("baz"));
  71. Debug.Log("条件01、02都符合条件了");
  72. }
  73. /// <summary>
  74. /// 当其中一个按钮点击了就执行后面操作
  75. /// </summary>
  76. private async void WhenAnyTest()
  77. {
  78. var firstOperation = UniTask.WaitUntil(() => isO_Down);
  79. var secondOperation = UniTask.WaitUntil(() => isP_Down);
  80. await UniTask.WhenAny(firstOperation, secondOperation);
  81. Debug.Log(isO_Down ? "O被按下" : "P被按下");
  82. }
  83. }
  84. public class UniTaskSys
  85. {
  86. public int count = 0;
  87. public async UniTask<Object> AsyncLoad<T>(string path) where T : Object
  88. {
  89. // 加载资源
  90. var asyncOperation = Resources.LoadAsync<T>(path);
  91. return (await asyncOperation);
  92. }
  93. public async void AsyncLoadScene(string sceneName)
  94. {
  95. // 加载场景
  96. await SceneManager.LoadSceneAsync(sceneName).ToUniTask
  97. (Progress.Create<float>((p) =>
  98. {
  99. Debug.Log($"加载进度为{p * 100:F2}%");
  100. }));
  101. }
  102. public async void DelayTest(MonoBehaviour mono = null)
  103. {
  104. Debug.Log(Time.realtimeSinceStartup);
  105. //性能最好,可以设置等待时机,PlayerLoopTiming 对应Unity中playerloop的更新时机
  106. //await UniTask.Yield(PlayerLoopTiming.LastUpdate);
  107. //等待1秒,类似 yield return new WaitForSeconds(1),可以设置 ignoreTimeScale
  108. //await UniTask.Delay(System.TimeSpan.FromSeconds(1), false);
  109. //执行在下一帧的update之后,类似 yield return null,和 UniTask.Yield() 效果一样
  110. //await UniTask.NextFrame();
  111. //这一帧的最后,类似 yield return new WaitForEndOfFrame(),this是一个MonoBehaviour
  112. //await UniTask.WaitForEndOfFrame(mono);
  113. //类似 yield return new WaitForFixedUpdate,和 await UniTask.Yield(PlayerLoopTiming.FixedUpdate)效果一样
  114. //await UniTask.WaitForFixedUpdate();
  115. //延迟5
  116. //await UniTask.DelayFrame(5);
  117. //类似 yield return new WaitUntil(() => count > 10),当count > 10时才执行后面逻辑
  118. await UniTask.WaitUntil(() => count > 10);
  119. Debug.Log(Time.realtimeSinceStartup);
  120. }
  121. }
  1. using Cysharp.Threading.Tasks;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. public class UniTaskCancel : MonoBehaviour
  9. {
  10. public Transform FirstTransform;
  11. public Transform SecondTransform;
  12. public Button FirstRunButton;
  13. public Button SecondRunButton;
  14. public Button FirstCancelButton;
  15. public Button SecondCancelButton;
  16. //做取消时需要创建这个对象
  17. private CancellationTokenSource _firstCancelToken;
  18. private CancellationTokenSource _secondCancelToken;
  19. private CancellationTokenSource _linkedCancelToken;
  20. private void Start()
  21. {
  22. FirstRunButton.onClick.AddListener(OnClickFirstMove);
  23. SecondRunButton.onClick.AddListener(OnClickSecondMove);
  24. FirstCancelButton.onClick.AddListener(OnClickFirstCancel);
  25. SecondCancelButton.onClick.AddListener(OnClickSecondCancel);
  26. _firstCancelToken = new CancellationTokenSource();
  27. // 注意这里可以直接先行设置多久以后取消
  28. // _firstCancelToken = new CancellationTokenSource(TimeSpan.FromSeconds(1.5f));
  29. _secondCancelToken = new CancellationTokenSource();
  30. //用两个token创建新的linkedCancelToken,当其中一个取消后,linkedCancelToken也会取消,
  31. _linkedCancelToken =
  32. CancellationTokenSource.CreateLinkedTokenSource(_firstCancelToken.Token, _secondCancelToken.Token);
  33. }
  34. /// <summary>
  35. /// 移动first,使用try catch监听取消信号
  36. /// </summary>
  37. private async void OnClickFirstMove()
  38. {
  39. try
  40. {
  41. await MoveTransform(FirstTransform, _firstCancelToken.Token);
  42. }
  43. catch (OperationCanceledException e)
  44. {
  45. //发出取消信号,这里会抛异常
  46. Debug.Log("first已经被取消");
  47. }
  48. }
  49. /// <summary>
  50. /// 移动second,忽略异常的抛出,返回一个值元组,这种方式性能更好
  51. /// </summary>
  52. private async void OnClickSecondMove()
  53. {
  54. //第一个参数表示是否取消,第二个参数时await的返回值
  55. var (cancelled, _) = await MoveTransform(SecondTransform, _secondCancelToken.Token).SuppressCancellationThrow();
  56. // 使用LinkedToken,当first取消后,second也会取消
  57. // var (cancelled, _) = await MoveTransform(SecondTransform, _linkedCancelToken.Token).SuppressCancellationThrow();
  58. if (cancelled)
  59. {
  60. Debug.Log("second已经被取消");
  61. }
  62. }
  63. private async UniTask<int> MoveTransform(Transform tf, CancellationToken cancellationToken)
  64. {
  65. float totalTime = 10;
  66. float timeElapsed = 0;
  67. while (timeElapsed <= totalTime)
  68. {
  69. timeElapsed += Time.deltaTime;
  70. await UniTask.NextFrame(cancellationToken);
  71. tf.transform.localPosition += Vector3.right * Time.deltaTime * 3;
  72. }
  73. return 0;
  74. }
  75. /// <summary>
  76. /// 取消first移动,Token使用后就不能再次使用,得创建新的Token
  77. /// </summary>
  78. private void OnClickFirstCancel()
  79. {
  80. _firstCancelToken.Cancel();
  81. _firstCancelToken.Dispose();
  82. _firstCancelToken = new CancellationTokenSource();
  83. _linkedCancelToken =
  84. CancellationTokenSource.CreateLinkedTokenSource(_firstCancelToken.Token, _secondCancelToken.Token);
  85. }
  86. private void OnClickSecondCancel()
  87. {
  88. _secondCancelToken.Cancel();
  89. _secondCancelToken.Dispose();
  90. _secondCancelToken = new CancellationTokenSource();
  91. _linkedCancelToken =
  92. CancellationTokenSource.CreateLinkedTokenSource(_firstCancelToken.Token, _secondCancelToken.Token);
  93. }
  94. private void OnDestroy()
  95. {
  96. _firstCancelToken.Dispose();
  97. _secondCancelToken.Dispose();
  98. _linkedCancelToken.Dispose();
  99. }
  100. }
  1. using System;
  2. using System.Threading;
  3. using Cysharp.Threading.Tasks;
  4. using Cysharp.Threading.Tasks.Linq;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. /// <summary>
  8. /// UI事件模板
  9. /// </summary>
  10. public class UIEventsSample : MonoBehaviour
  11. {
  12. public Transform trans_Sphere;
  13. public Button SphereButton;
  14. public Button DoubleClickButton;
  15. public Button CoolDownButton;
  16. public float DoubleClickCheckTime = 0.5f;
  17. public float CooldownTime = 3f;
  18. void Start()
  19. {
  20. CheckSphereClick(SphereButton.GetCancellationTokenOnDestroy()).Forget();
  21. CheckDoubleClickButton(DoubleClickButton, this.GetCancellationTokenOnDestroy()).Forget();
  22. CheckCooldownClickButton(this.GetCancellationTokenOnDestroy()).Forget();
  23. }
  24. /// <summary>
  25. /// 球体连点
  26. /// </summary>
  27. private async UniTaskVoid CheckSphereClick(CancellationToken token)
  28. {
  29. //将按钮的点击转换为异步可迭代器
  30. var asyncEnumerable = SphereButton.OnClickAsAsyncEnumerable();
  31. //ForEachAsync处理每一次点击时的操作,index表示第几次点击,Take(3)表示只处理前三次点击
  32. await asyncEnumerable.Take(3).ForEachAsync((_, index) =>
  33. {
  34. if (token.IsCancellationRequested) return;
  35. if (index == 0)
  36. {
  37. //第一次点击,放大
  38. SphereTweenScale(2, trans_Sphere.localScale.x, 5, token).Forget();
  39. }
  40. else if (index == 1)
  41. {
  42. //第二次点击,缩小
  43. SphereTweenScale(2, trans_Sphere.localScale.x, 2, token).Forget();
  44. }
  45. else if (index == 2)
  46. {
  47. //第三次点击销毁
  48. }
  49. }, token);
  50. GameObject.Destroy(trans_Sphere.gameObject);
  51. //三次点击后,await完成,可以进行后面的逻辑
  52. Debug.LogError("done");
  53. }
  54. private async UniTaskVoid SphereTweenScale(float totalTime, float from, float to, CancellationToken token)
  55. {
  56. var trans = trans_Sphere;
  57. float time = 0;
  58. while (time < totalTime)
  59. {
  60. time += Time.deltaTime;
  61. if (trans)
  62. {
  63. trans.localScale = (from + (time / totalTime) * (to - from)) * Vector3.one;
  64. }
  65. await UniTask.Yield(PlayerLoopTiming.Update, token);
  66. }
  67. }
  68. /// <summary>
  69. /// 双击按钮
  70. /// </summary>
  71. private async UniTaskVoid CheckDoubleClickButton(Button button, CancellationToken token)
  72. {
  73. while (true)
  74. {
  75. //将点击转换为异步的UniTask,然后等待第一次点击
  76. var clickAsync = button.OnClickAsync(token);
  77. await clickAsync;
  78. Debug.Log($"按钮被第一次点击");
  79. var secondClickAsync = button.OnClickAsync(token);
  80. //第二次点击和等待时间谁先到,WhenAny返回那个先执行
  81. int resultIndex = await UniTask.WhenAny(secondClickAsync,
  82. UniTask.Delay(TimeSpan.FromSeconds(DoubleClickCheckTime), cancellationToken: token));
  83. Debug.Log(resultIndex == 0 ? $"按钮被双击了" : $"超时,按钮算单次点击");
  84. }
  85. }
  86. /// <summary>
  87. /// 按钮冷却时间
  88. /// </summary>
  89. private async UniTaskVoid CheckCooldownClickButton(CancellationToken token)
  90. {
  91. var asyncEnumerable = CoolDownButton.OnClickAsAsyncEnumerable();
  92. await asyncEnumerable.ForEachAwaitAsync(async (_) =>
  93. {
  94. Debug.Log("被点击了,冷却中……");
  95. //Delay过程中不会再响应点击操作
  96. await UniTask.Delay(TimeSpan.FromSeconds(CooldownTime), cancellationToken: token);
  97. Debug.Log("冷却好了,可以点了……");
  98. }, cancellationToken: token);
  99. }
  100. }
  1. using Cysharp.Threading.Tasks;
  2. using System;
  3. using System.Threading;
  4. using UnityEngine;
  5. using UnityEngine.Networking;
  6. using UnityEngine.UI;
  7. /// <summary>
  8. /// 超时操作
  9. /// </summary>
  10. public class TimeoutTest : MonoBehaviour
  11. {
  12. public Button TestButton;
  13. private void Start()
  14. {
  15. //使用UniTask.UnityAction包装了OnClickTest
  16. TestButton.onClick.AddListener(UniTask.UnityAction(OnClickTest));
  17. }
  18. private async UniTaskVoid OnClickTest()
  19. {
  20. var res = await GetRequest("https://www.baidu.com/", 2f);
  21. //var res = await GetRequest("https://www.google.com/", 2f);
  22. Debug.LogError(res);
  23. }
  24. private async UniTask<string> GetRequest(string url, float timeout)
  25. {
  26. //这个token会在timeout之后发出取消信号
  27. var cts = new CancellationTokenSource();
  28. cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout));
  29. var (failed, result) = await UnityWebRequest.Get(url).SendWebRequest().
  30. WithCancellation(cts.Token).SuppressCancellationThrow();
  31. if (!failed)
  32. {
  33. //成功了返回网页内容的开头
  34. return result.downloadHandler.text.Substring(0, 100);
  35. }
  36. return "超时";
  37. }
  38. }
  1. using Cysharp.Threading.Tasks;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. /// <summary>
  8. /// 切换到主线程
  9. /// </summary>
  10. public class ThreadSample : MonoBehaviour
  11. {
  12. public Button btn_StandardRun;
  13. public Button btn_YieldRun;
  14. private void Start()
  15. {
  16. btn_StandardRun.onClick.AddListener(UniTask.UnityAction(OnClickStandardRun));
  17. btn_YieldRun.onClick.AddListener(UniTask.UnityAction(OnClickYieldRun));
  18. }
  19. public async UniTaskVoid OnClickStandardRun()
  20. {
  21. int result = 0;
  22. //切换到其他线程
  23. await UniTask.RunOnThreadPool(()=> { result = 1; });
  24. //切换到主线程
  25. await UniTask.SwitchToMainThread();
  26. Debug.Log($"计算结束,当前结果为:{result}");
  27. }
  28. /// <summary>
  29. /// 线程中读取文件
  30. /// </summary>
  31. private async UniTaskVoid OnClickYieldRun()
  32. {
  33. string fileName = Application.streamingAssetsPath + "/Test.txt";
  34. await UniTask.SwitchToThreadPool();
  35. string fileContent = await File.ReadAllTextAsync(fileName);
  36. //调用 UniTask.Yield 会自动切换会主线程
  37. await UniTask.Yield(PlayerLoopTiming.Update);
  38. Debug.LogError(fileContent);
  39. }
  40. }
  1. using Cysharp.Threading.Tasks;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. public class ForgetSample : MonoBehaviour
  7. {
  8. public Button StartButton;
  9. public GameObject Target;
  10. public const float G = 9.8f;
  11. public float FallTime = 0.5f;
  12. private void Start()
  13. {
  14. StartButton.onClick.AddListener(OnClickStart);
  15. }
  16. /// <summary>
  17. /// 同步方法中调用异步方法
  18. /// </summary>
  19. private void OnClickStart()
  20. {
  21. //不需要等待时候就调用Forget
  22. FallTarget(Target.transform).Forget();
  23. }
  24. /// <summary>
  25. /// 使目标掉落,async UniTaskVoid是async UniTask的轻量级版本
  26. /// </summary>
  27. private async UniTaskVoid FallTarget(Transform targetTrans)
  28. {
  29. Vector3 startPosition = targetTrans.position;
  30. float fallTime = 1f;
  31. float elapsedTime = 0;
  32. while (elapsedTime <= fallTime)
  33. {
  34. elapsedTime += Time.deltaTime;
  35. float fallY = 0.5f * G * elapsedTime * elapsedTime;
  36. targetTrans.position = startPosition + Vector3.down * fallY;
  37. //GetCancellationTokenOnDestroy 表示获取一个依赖对象生命周期的Cancel句柄,
  38. //当对象被销毁时,将会调用这个Cancel句柄,从而实现取消的功能
  39. await UniTask.Yield(this.GetCancellationTokenOnDestroy());
  40. }
  41. }
  42. }
  1. using Cysharp.Threading.Tasks;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. public class CallbackSample : MonoBehaviour
  8. {
  9. public Button CallbackButton;
  10. public GameObject Target;
  11. public const float G = 9.8f;
  12. public event EventHandler OneSecondHandler;
  13. private void Start()
  14. {
  15. CallbackButton.onClick.AddListener(UniTask.UnityAction(OnClickCallback));
  16. OneSecondHandler += CallbackSample_OneSecondHandler;
  17. }
  18. private void CallbackSample_OneSecondHandler(object sender, EventArgs e)
  19. {
  20. Debug.Log("1S 事件被触发");
  21. }
  22. private async UniTaskVoid OnClickCallback()
  23. {
  24. float time = Time.time;
  25. UniTaskCompletionSource source = new UniTaskCompletionSource();
  26. FallTarget(Target.transform, source).Forget();
  27. await source.Task;// UniTaskCompletionSource产生的UnitTask是可以复用的
  28. Debug.Log($"耗时 {Time.time - time}秒");
  29. }
  30. /// <summary>
  31. /// UniTask运行中执行回调
  32. /// UniTaskCompletionSource是对UniTask和CancellationToken的封装
  33. /// </summary>
  34. private async UniTask FallTarget(Transform targetTrans, UniTaskCompletionSource source)
  35. {
  36. Vector3 startPosition = targetTrans.position;
  37. float fallTime = 2f;
  38. float elapsedTime = 0;
  39. while (elapsedTime <= fallTime)
  40. {
  41. elapsedTime += Time.deltaTime;
  42. //当下落时间超过1秒时设置操作
  43. if (elapsedTime > 1f)
  44. {
  45. OneSecondHandler?.Invoke(this,EventArgs.Empty);
  46. // 表示操作完成
  47. source.TrySetResult();
  48. // 失败
  49. // source.TrySetException(new SystemException());
  50. // 取消
  51. // source.TrySetCanceled(someToken);
  52. // 泛型类UniTaskCompletionSource<T> SetResult是T类型,返回UniTask<T>
  53. }
  54. float fallY = 0.5f * G * elapsedTime * elapsedTime;
  55. targetTrans.position = startPosition + Vector3.down * fallY;
  56. await UniTask.Yield(this.GetCancellationTokenOnDestroy());
  57. }
  58. }
  59. private void OnDestroy()
  60. {
  61. OneSecondHandler -= CallbackSample_OneSecondHandler;
  62. }
  63. }
  1. using Cysharp.Threading.Tasks;
  2. using Cysharp.Threading.Tasks.Linq;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. public class AsyncReactivePropertySample : MonoBehaviour
  9. {
  10. public int maxHp = 100;
  11. public float totalChangeTime = 1f;
  12. public Text ShowHpText;
  13. public Text StateText;
  14. public Text ChangeText;
  15. public Slider HpSlider;
  16. public Image HpBarImage;
  17. public Button HealButton;
  18. public Button HurtButton;
  19. private AsyncReactiveProperty<string> currentHpStr;
  20. private AsyncReactiveProperty<int> currentHp;
  21. private int maxHeal = 10;
  22. private int maxHurt = 10;
  23. private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
  24. private CancellationTokenSource _linkedTokenSource;
  25. private void Start()
  26. {
  27. // 设置AsyncReactiveProperty
  28. currentHpStr = new AsyncReactiveProperty<string>($"当前血量:{maxHp}/{maxHp}");
  29. currentHp = new AsyncReactiveProperty<int>(maxHp);
  30. HpSlider.maxValue = maxHp;
  31. HpSlider.value = maxHp;
  32. currentHp.Subscribe(OnHpChange);
  33. CheckHpChange(currentHp).Forget();
  34. CheckFirstLowHp(currentHp).Forget();
  35. currentHpStr.BindTo(ShowHpText);
  36. HealButton.onClick.AddListener(OnClickHeal);
  37. HurtButton.onClick.AddListener(OnClickHurt);
  38. _linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token,
  39. this.GetCancellationTokenOnDestroy());
  40. }
  41. private void OnClickHeal()
  42. {
  43. ChangeHp(Random.Range(0, maxHeal));
  44. }
  45. private void OnClickHurt()
  46. {
  47. ChangeHp(-Random.Range(0, maxHurt));
  48. }
  49. private void ChangeHp(int deltaHp)
  50. {
  51. currentHp.Value = Mathf.Clamp(currentHp.Value + deltaHp, 0, maxHp);
  52. currentHpStr.Value = $"当前血量:{currentHp.Value}/{maxHp}";
  53. }
  54. /// <summary>
  55. /// currentHp变化时修改提示信息
  56. /// </summary>
  57. private async UniTaskVoid CheckHpChange(AsyncReactiveProperty<int> hp)
  58. {
  59. int hpValue = hp.Value;
  60. // WithoutCurrent 忽略初始值
  61. await hp.WithoutCurrent().ForEachAsync((_, index) =>
  62. {
  63. ChangeText.text = $"血量发生变化 第{index}次 变化{hp.Value - hpValue}";
  64. hpValue = hp.Value;
  65. }, this.GetCancellationTokenOnDestroy());
  66. }
  67. /// <summary>
  68. /// currentHp低于临界值,显示提示信息
  69. /// </summary>
  70. private async UniTaskVoid CheckFirstLowHp(AsyncReactiveProperty<int> hp)
  71. {
  72. await hp.FirstAsync((value) => value < maxHp * 0.4f, this.GetCancellationTokenOnDestroy());
  73. StateText.text = "首次血量低于界限,请注意!";
  74. }
  75. private async UniTaskVoid OnHpChange(int hp)
  76. {
  77. _cancellationTokenSource.Cancel();
  78. _cancellationTokenSource = new CancellationTokenSource();
  79. _linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token,
  80. this.GetCancellationTokenOnDestroy());
  81. await SyncSlider(hp, _linkedTokenSource.Token);
  82. }
  83. /// <summary>
  84. /// 同步血条
  85. /// </summary>
  86. private async UniTask SyncSlider(int hp, CancellationToken token)
  87. {
  88. var sliderValue = HpSlider.value;
  89. float needTime = Mathf.Abs((sliderValue - hp) / maxHp * totalChangeTime);
  90. float useTime = 0;
  91. while (useTime < needTime)
  92. {
  93. useTime += Time.deltaTime;
  94. bool result = await UniTask.Yield(PlayerLoopTiming.Update, token)
  95. .SuppressCancellationThrow();
  96. if (result)
  97. {
  98. return;
  99. }
  100. var newValue = (sliderValue + (hp - sliderValue) * (useTime / needTime));
  101. SetNewValue(newValue);
  102. }
  103. }
  104. private void SetNewValue(float newValue)
  105. {
  106. if (!HpSlider) return;
  107. HpSlider.value = newValue;
  108. HpBarImage.color = HpSlider.value / maxHp < 0.4f ? Color.red : Color.white;
  109. }
  110. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/87442
推荐阅读
相关标签
  

闽ICP备14008679号