MRTK-Solver

作者:追风剑情 发布于:2023-7-5 18:50 分类:Unity3d

所有解算器要从中派生的抽象基类。参见 求解器概述 - MRTK2

  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Serialization;
  4.  
  5. namespace Microsoft.MixedReality.Toolkit.Utilities.Solvers
  6. {
  7. [RequireComponent(typeof(SolverHandler))]
  8. public abstract class Solver : MonoBehaviour
  9. {
  10. //如果为true,将计算位置和方向,但不应用于其他组件。
  11. private bool updateLinkedTransform = false;
  12. //移动插值时间,值越大移动越缓慢
  13. //参见:UpdateWorkingPositionToGoal()
  14. private float moveLerpTime = 0.1f;
  15. //旋转插值时间,值越大旋转越缓慢
  16. //参见:UpdateWorkingRotationToGoal()
  17. private float rotateLerpTime = 0.1f;
  18. //缩放插值时间,值越大缩放越缓慢
  19. //参见:UpdateWorkingScaleToGoal()
  20. private float scaleLerpTime = 0;
  21. //true:初始化时保持transform的localScale值不变。
  22. //参见 Awake()
  23. private bool maintainScaleOnInitialization = true;
  24. //是否采用平滑插值。
  25. //参见: UpdateWorkingPositionToGoal()、UpdateWorkingRotationToGoal()、UpdateWorkingScaleToGoal()
  26. private bool smoothing = true;
  27. //解算器生命周期,0:无限
  28. //参见: SolverUpdateEntry()
  29. private float lifetime = 0;
  30. //参见: Awake()
  31. protected SolverHandler SolverHandler;
  32.  
  33. /// <summary>
  34. /// 最终坐标,由GameObject上所有解算器共同计算所得。
  35. /// </summary>
  36. protected Vector3 GoalPosition
  37. {
  38. get { return SolverHandler.GoalPosition; }
  39. set { SolverHandler.GoalPosition = value; }
  40. }
  41.  
  42. /// <summary>
  43. /// 最终旋转,由GameObject上所有解算器共同计算所得。
  44. /// </summary>
  45. protected Quaternion GoalRotation
  46. {
  47. get { return SolverHandler.GoalRotation; }
  48. set { SolverHandler.GoalRotation = value; }
  49. }
  50.  
  51. /// <summary>
  52. /// 最终缩放,由GameObject上所有解算器共同计算所得。
  53. /// </summary>
  54. protected Vector3 GoalScale
  55. {
  56. get { return SolverHandler.GoalScale; }
  57. set { SolverHandler.GoalScale = value; }
  58. }
  59.  
  60. /// <summary>
  61. /// 当前坐标
  62. /// </summary>
  63. public Vector3 WorkingPosition
  64. {
  65. get
  66. {
  67. return updateLinkedTransform ? GoalPosition : transform.position;
  68. }
  69. protected set
  70. {
  71. if (updateLinkedTransform)
  72. {
  73. GoalPosition = value;
  74. }
  75. else
  76. {
  77. transform.position = value;
  78. }
  79. }
  80. }
  81.  
  82. /// <summary>
  83. /// 当前旋转
  84. /// </summary>
  85. public Quaternion WorkingRotation
  86. {
  87. get
  88. {
  89. return updateLinkedTransform ? GoalRotation : transform.rotation;
  90. }
  91. protected set
  92. {
  93. if (updateLinkedTransform)
  94. {
  95. GoalRotation = value;
  96. }
  97. else
  98. {
  99. transform.rotation = value;
  100. }
  101. }
  102. }
  103.  
  104. /// <summary>
  105. /// 当前缩放
  106. /// </summary>
  107. public Vector3 WorkingScale
  108. {
  109. get
  110. {
  111. return updateLinkedTransform ? GoalScale : transform.localScale;
  112. }
  113. protected set
  114. {
  115. if (updateLinkedTransform)
  116. {
  117. GoalScale = value;
  118. }
  119. else
  120. {
  121. transform.localScale = value;
  122. }
  123. }
  124. }
  125.  
  126. #region MonoBehaviour Implementation
  127.  
  128. protected virtual void Awake()
  129. {
  130. if (SolverHandler == null)
  131. {
  132. SolverHandler = GetComponent<SolverHandler>();
  133. }
  134.  
  135. if (updateLinkedTransform && SolverHandler == null)
  136. {
  137. Debug.LogError("No SolverHandler component found on " + name +
  138. " when UpdateLinkedTransform was set to true! Disabling UpdateLinkedTransform.");
  139. updateLinkedTransform = false;
  140. }
  141.  
  142. GoalScale = maintainScaleOnInitialization ? transform.localScale : Vector3.one;
  143. }
  144.  
  145. protected virtual void OnEnable()
  146. {
  147. if (SolverHandler != null)
  148. {
  149. SnapGoalTo(GoalPosition, GoalRotation, GoalScale);
  150. }
  151.  
  152. currentLifetime = 0;
  153. }
  154.  
  155. protected virtual void Start()
  156. {
  157. if (SolverHandler != null)
  158. {
  159. //注册解算器
  160. SolverHandler.RegisterSolver(this);
  161. }
  162. }
  163. protected virtual void OnDestroy()
  164. {
  165. if (SolverHandler != null)
  166. {
  167. //注销解算器
  168. SolverHandler.UnregisterSolver(this);
  169. }
  170. }
  171.  
  172. #endregion MonoBehaviour Implementation
  173.  
  174. /// <summary>
  175. /// 由子类实现,更新游戏内容变换。
  176. /// </summary>
  177. public abstract void SolverUpdate();
  178.  
  179. /// <summary>
  180. /// 此方法在SolverHandler类的LateUpdate()中被每帧调用。
  181. /// </summary>
  182. public void SolverUpdateEntry()
  183. {
  184. currentLifetime += SolverHandler.DeltaTime;
  185. //判断解算器的生命周期是否结束
  186. if (lifetime > 0 && currentLifetime >= lifetime)
  187. {
  188. enabled = false;
  189. return;
  190. }
  191.  
  192. SolverUpdate();
  193. UpdateWorkingToGoal();
  194. }
  195.  
  196. /// <summary>
  197. /// 更新解算器的变换值
  198. /// </summary>
  199. public virtual void SnapTo(Vector3 position, Quaternion rotation, Vector3 scale)
  200. {
  201. SnapGoalTo(position, rotation, scale);
  202.  
  203. WorkingPosition = position;
  204. WorkingRotation = rotation;
  205. WorkingScale = scale;
  206. }
  207.  
  208. /// <summary>
  209. /// 更新解算器的最终变换值
  210. /// </summary>
  211. public virtual void SnapGoalTo(Vector3 position, Quaternion rotation, Vector3 scale)
  212. {
  213. GoalPosition = position;
  214. GoalRotation = rotation;
  215. GoalScale = scale;
  216. }
  217.  
  218. /// <summary>
  219. /// 坐标偏移
  220. /// </summary>
  221. public virtual void AddOffset(Vector3 offset)
  222. {
  223. GoalPosition += offset;
  224. }
  225.  
  226. /// <summary>
  227. /// 更新Transform
  228. /// </summary>
  229. protected void UpdateTransformToGoal()
  230. {
  231. if (smoothing)
  232. {
  233. Vector3 pos = transform.position;
  234. Quaternion rot = transform.rotation;
  235. Vector3 scale = transform.localScale;
  236.  
  237. pos = SmoothTo(pos, GoalPosition, SolverHandler.DeltaTime, moveLerpTime);
  238. rot = SmoothTo(rot, GoalRotation, SolverHandler.DeltaTime, rotateLerpTime);
  239. scale = SmoothTo(scale, GoalScale, SolverHandler.DeltaTime, scaleLerpTime);
  240.  
  241. transform.position = pos;
  242. transform.rotation = rot;
  243. transform.localScale = scale;
  244. }
  245. else
  246. {
  247. transform.position = GoalPosition;
  248. transform.rotation = GoalRotation;
  249. transform.localScale = GoalScale;
  250. }
  251. }
  252.  
  253. public void UpdateWorkingToGoal()
  254. {
  255. UpdateWorkingPositionToGoal();
  256. UpdateWorkingRotationToGoal();
  257. UpdateWorkingScaleToGoal();
  258. }
  259.  
  260. public void UpdateWorkingPositionToGoal()
  261. {
  262. WorkingPosition = smoothing ? SmoothTo(WorkingPosition, GoalPosition, SolverHandler.DeltaTime, moveLerpTime) : GoalPosition;
  263. }
  264.  
  265. public void UpdateWorkingRotationToGoal()
  266. {
  267. WorkingRotation = smoothing ? SmoothTo(WorkingRotation, GoalRotation, SolverHandler.DeltaTime, rotateLerpTime) : GoalRotation;
  268. }
  269.  
  270. public void UpdateWorkingScaleToGoal()
  271. {
  272. WorkingScale = smoothing ? SmoothTo(WorkingScale, GoalScale, SolverHandler.DeltaTime, scaleLerpTime) : GoalScale;
  273. }
  274.  
  275. // 向量平滑插值
  276. public static Vector3 SmoothTo(Vector3 source, Vector3 goal, float deltaTime, float lerpTime)
  277. {
  278. return Vector3.Lerp(source, goal, lerpTime.Equals(0.0f) ? 1f : deltaTime / lerpTime);
  279. }
  280.  
  281. // 四元数平滑插值
  282. public static Quaternion SmoothTo(Quaternion source, Quaternion goal, float deltaTime, float lerpTime)
  283. {
  284. return Quaternion.Slerp(source, goal, lerpTime.Equals(0.0f) ? 1f : deltaTime / lerpTime);
  285. }
  286. }
  287. }

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号