• 主页

  • 投资

  • IT

    🔥
  • 设计

  • 销售

  • 共151篇

    Unity - 游戏引擎

关闭

返回栏目

关闭

返回Unity - 游戏引擎栏目

90 - Loom.cs - 线程器 - 从子线程转到主线程

作者:

贺及楼

成为作者

更新日期:2023-09-17 10:57:18

作用:从子线程转到主线程

第一步创建Loom.cs

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. using System.Threading;
  6. using System.Linq;
  7. public class Loom : MonoBehaviour
  8. {
  9. public static int maxThreads = 8;
  10. static int numThreads;
  11. private static Loom _current;
  12. public static Loom Current
  13. {
  14. get
  15. {
  16. Initialize();
  17. return _current;
  18. }
  19. }
  20. //####去除Awake
  21. // void Awake()
  22. // {
  23. // _current = this;
  24. // initialized = true;
  25. // }
  26. static bool initialized;
  27. //####作为初始化方法自己调用,可在初始化场景调用一次即可
  28. public static void Initialize()
  29. {
  30. if (!initialized)
  31. {
  32. if(!Application.isPlaying)
  33. return;
  34. initialized = true;
  35. GameObject g = new GameObject("Loom");
  36. //####永不销毁
  37. DontDestroyOnLoad (g);
  38. _current = g.AddComponent<Loom>();
  39. }
  40. }
  41. private List<Action> _actions = new List<Action>();
  42. public struct DelayedQueueItem
  43. {
  44. public float time;
  45. public Action action;
  46. }
  47. private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
  48. List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
  49. public static void QueueOnMainThread(Action action)
  50. {
  51. QueueOnMainThread( action, 0f);
  52. }
  53. public static void QueueOnMainThread(Action action, float time)
  54. {
  55. if(time != 0)
  56. {
  57. if (Current != null)
  58. {
  59. lock (Current._delayed)
  60. {
  61. Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
  62. }
  63. }
  64. }
  65. else
  66. {
  67. if (Current != null)
  68. {
  69. lock (Current._actions)
  70. {
  71. Current._actions.Add(action);
  72. }
  73. }
  74. }
  75. }
  76. public static Thread RunAsync(Action a)
  77. {
  78. Initialize();
  79. while(numThreads >= maxThreads)
  80. {
  81. Thread.Sleep(1);
  82. }
  83. Interlocked.Increment(ref numThreads);
  84. ThreadPool.QueueUserWorkItem(RunAction, a);
  85. return null;
  86. }
  87. private static void RunAction(object action)
  88. {
  89. try
  90. {
  91. ((Action)action)();
  92. }
  93. catch
  94. {
  95. }
  96. finally
  97. {
  98. Interlocked.Decrement(ref numThreads);
  99. }
  100. }
  101. void OnDisable()
  102. {
  103. if (_current == this)
  104. {
  105. _current = null;
  106. }
  107. }
  108. // Use this for initialization
  109. void Start()
  110. {
  111. }
  112. List<Action> _currentActions = new List<Action>();
  113. // Update is called once per frame
  114. void Update()
  115. {
  116. lock (_actions)
  117. {
  118. _currentActions.Clear();
  119. _currentActions.AddRange(_actions);
  120. _actions.Clear();
  121. }
  122. foreach(var a in _currentActions)
  123. {
  124. a();
  125. }
  126. lock(_delayed)
  127. {
  128. _currentDelayed.Clear();
  129. _currentDelayed.AddRange(_delayed.Where(d=>d.time <= Time.time));
  130. foreach(var item in _currentDelayed)
  131. _delayed.Remove(item);
  132. }
  133. foreach(var delayed in _currentDelayed)
  134. {
  135. delayed.action();
  136. }
  137. }
  138. }

第二步:实例化

在GameFacade,初始化

  1. Loom.Initialize();//Loom线程控制初始化,把子线程调回主线程

第三步:使用

  1. Loom.QueueOnMainThread(do);//子线程回到主线程
  1. public void do()
  2. {
  3. //各种例如换场景或调用UnityAPI
  4. }