MovePathItem.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. using Sirenix.OdinInspector;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. #if UNITY_EDITOR
  6. using UnityEditor;
  7. #endif
  8. using UnityEngine;
  9. [ExecuteInEditMode]
  10. public class MovePathItem : MonoBehaviour
  11. {
  12. public GameObject moveTarget;
  13. public float moveSpeed = 4;
  14. public float rotateSpeed = 4;
  15. public float waitTime = 0;
  16. public List<Transform> movePathPoints = new List<Transform>();
  17. public List<Transform> GetMovePathPoints(bool reverse = false)
  18. {
  19. List<Transform> tmpMovePathPoints = new List<Transform>();
  20. tmpMovePathPoints.AddRange(movePathPoints);
  21. if (reverse)
  22. {
  23. tmpMovePathPoints.Reverse();
  24. }
  25. return tmpMovePathPoints;
  26. }
  27. public void SetInitState(bool reverse)
  28. {
  29. int id = reverse ? (movePathPoints.Count - 1) : 0;
  30. moveTarget.transform.position = movePathPoints[id].position;
  31. moveTarget.transform.rotation = movePathPoints[id].rotation;
  32. }
  33. public void SetFinishedState(bool reverse)
  34. {
  35. int id = reverse ? 0 : (movePathPoints.Count - 1);
  36. moveTarget.transform.position = movePathPoints[id].position;
  37. moveTarget.transform.rotation = movePathPoints[id].rotation;
  38. }
  39. #if UNITY_EDITOR
  40. [Button("添加移动路径")]
  41. public void AddMovePath()
  42. {
  43. if (moveTarget == null)
  44. {
  45. Debug.LogError("未添加动画主体");
  46. return;
  47. }
  48. GameObject pathItem = new GameObject("MovePath");
  49. if (movePathPoints.Count == 0)
  50. {
  51. pathItem.transform.position = moveTarget.transform.position;
  52. pathItem.transform.rotation = moveTarget.transform.rotation;
  53. }
  54. else
  55. {
  56. pathItem.transform.position = movePathPoints[movePathPoints.Count - 1].position;
  57. pathItem.transform.rotation = movePathPoints[movePathPoints.Count - 1].rotation;
  58. }
  59. pathItem.transform.parent = this.transform;
  60. pathItem.transform.localScale = Vector3.one;
  61. pathItem.transform.SetAsLastSibling();
  62. movePathPoints.Add(pathItem.transform);
  63. Selection.activeGameObject = pathItem;
  64. if (isShowPose)
  65. {
  66. GameObject cloneItem = GameObject.Instantiate(moveTarget, pathItem.transform);
  67. cloneItem.transform.localPosition = Vector3.zero;
  68. cloneItem.transform.localRotation = Quaternion.identity;
  69. cloneItem.transform.localScale = moveTarget.transform.lossyScale;
  70. }
  71. else
  72. {
  73. ShowMovePos();
  74. }
  75. }
  76. [HideInInspector]
  77. public bool isShowPath = true;
  78. [HideInInspector]
  79. public bool isShowPose = false;
  80. public bool ShowPath { get { return isShowPath; } }
  81. public bool ClosePath { get { return !isShowPath; } }
  82. [Button("展示物体姿态")]
  83. [ShowIf("@!isShowPose")]
  84. public void ShowMovePos()
  85. {
  86. foreach (var item in movePathPoints)
  87. {
  88. GameObject cloneItem = GameObject.Instantiate(moveTarget, item);
  89. cloneItem.transform.localPosition = Vector3.zero;
  90. cloneItem.transform.localRotation = Quaternion.identity;
  91. cloneItem.transform.localScale = moveTarget.transform.lossyScale;
  92. }
  93. isShowPose = true;
  94. isShowPath = true;
  95. }
  96. [Button("关闭物体姿态")]
  97. [ShowIf("@isShowPose")]
  98. public void CloseMovePos()
  99. {
  100. foreach (var item in movePathPoints)
  101. {
  102. DestroyChild(item);
  103. }
  104. isShowPose = false;
  105. isShowPath = false;
  106. }
  107. [ContextMenu("反转排序")]
  108. public void ResevePathPoints()
  109. {
  110. movePathPoints.Reverse();
  111. }
  112. private void OnDrawGizmos()
  113. {
  114. DrawPathLine();
  115. }
  116. public void DrawPathLine()
  117. {
  118. if (!isShowPath) return;
  119. Gizmos.color = Color.white;
  120. for (int i = 0; i < movePathPoints.Count; i++)
  121. {
  122. if (i + 1 < movePathPoints.Count)
  123. {
  124. Gizmos.color = Color.yellow;
  125. Gizmos.DrawLine(movePathPoints[i].position, movePathPoints[i + 1].position);
  126. }
  127. }
  128. }
  129. /// <summary>
  130. /// 销毁所有子级信息
  131. /// </summary>
  132. /// <param name="item"></param>
  133. private void DestroyChild(Transform item)
  134. {
  135. if (item.childCount == 0) return;
  136. for (int i = item.childCount - 1; i >= 0; i--)
  137. {
  138. DestroyImmediate(item.GetChild(i).gameObject);
  139. }
  140. }
  141. [Button("Play")]
  142. public void Play()
  143. {
  144. index = 0;
  145. targetPoint = movePathPoints[index];
  146. moveTarget.transform.position = targetPoint.position;
  147. moveTarget.transform.rotation = targetPoint.rotation;
  148. isPlaying = true;
  149. }
  150. [HideInInspector]
  151. public bool isPlaying;
  152. private void OnEnable()
  153. {
  154. EditorApplication.update += EditorUpdate;
  155. Selection.selectionChanged += SelectionChanged;
  156. }
  157. private void OnDisable()
  158. {
  159. EditorApplication.update -= EditorUpdate;
  160. Selection.selectionChanged -= SelectionChanged;
  161. }
  162. private Transform targetPoint;
  163. private int index;
  164. void EditorUpdate()
  165. {
  166. if (!isPlaying) return;
  167. moveTarget.transform.position = Vector3.MoveTowards(moveTarget.transform.position, targetPoint.position, moveSpeed * Time.deltaTime);
  168. moveTarget.transform.rotation = Quaternion.Lerp(moveTarget.transform.rotation, targetPoint.rotation, rotateSpeed * Time.deltaTime);
  169. if (Vector3.Distance(moveTarget.transform.position, targetPoint.position) < 0.02f && Quaternion.Angle(moveTarget.transform.rotation, targetPoint.rotation) < 5)
  170. {
  171. moveTarget.transform.position = targetPoint.position;
  172. moveTarget.transform.rotation = targetPoint.rotation;
  173. index++;
  174. if (index < movePathPoints.Count)
  175. {
  176. targetPoint = movePathPoints[index];
  177. }
  178. else
  179. {
  180. index = 0;
  181. targetPoint = movePathPoints[0];
  182. moveTarget.transform.position = targetPoint.position;
  183. moveTarget.transform.rotation = targetPoint.rotation;
  184. isPlaying = false;
  185. }
  186. }
  187. }
  188. void SelectionChanged()
  189. {
  190. if (Selection.gameObjects.Contains(this.gameObject))
  191. {
  192. isShowPath = true;
  193. }
  194. else if (!isShowPose)
  195. {
  196. isShowPath = false;
  197. }
  198. }
  199. #endif
  200. }