SimpleBezierCurvePathAlonger.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using Sirenix.OdinInspector;
  2. using System.Collections;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. namespace SK.Framework
  7. {
  8. [ExecuteInEditMode]
  9. public class SimpleBezierCurvePathAlonger : MonoBehaviour
  10. {
  11. public enum UpdateMode
  12. {
  13. FixedUpdate,
  14. Update,
  15. LateUpdate,
  16. }
  17. public Transform target;
  18. [SerializeField] private SimpleBezierCurvePath path;
  19. [SerializeField] private float speed = .1f;
  20. [SerializeField] private UpdateMode updateMode = UpdateMode.Update;
  21. private float normalized = 0f;
  22. private Vector3 lastPosition;
  23. private void FixedUpdate()
  24. {
  25. return;
  26. if (updateMode == UpdateMode.FixedUpdate && path != null)
  27. MoveAlongPath();
  28. }
  29. private void Update()
  30. {
  31. return;
  32. if (updateMode == UpdateMode.Update && path != null)
  33. MoveAlongPath();
  34. }
  35. private void LateUpdate()
  36. {
  37. return;
  38. if (updateMode == UpdateMode.LateUpdate && path != null)
  39. MoveAlongPath();
  40. }
  41. private void MoveAlongPath()
  42. {
  43. float t = normalized + speed * Time.deltaTime;
  44. float max = path.Points.Count - 1 < 1 ? 0 : (path.Loop ? path.Points.Count : path.Points.Count - 1);
  45. normalized = (path.Loop && max > 0) ? ((t %= max) + (t < 0 ? max : 0)) : Mathf.Clamp(t, 0, max);
  46. target.position = path.EvaluatePosition(normalized);
  47. Vector3 forward = target.position - lastPosition;
  48. target.forward = forward != Vector3.zero ? forward : target.forward;
  49. lastPosition = target.position;
  50. }
  51. private void MoveTargetPointsPath()
  52. {
  53. float t = normalized + speed * Time.deltaTime;
  54. target.position = path.GetPos(normalized).position;
  55. Vector3 forward = target.position - lastPosition;
  56. target.forward = forward != Vector3.zero ? forward : target.forward;
  57. lastPosition = target.position;
  58. }
  59. [Button("Play")]
  60. public void Play()
  61. {
  62. isPlaying = true;
  63. meshPoint = path.GetPos(0);
  64. target.position = meshPoint.position;
  65. target.forward = meshPoint.normail;
  66. index = 0;
  67. }
  68. public bool isPlaying;
  69. public float normailFloor = 0.05f;
  70. public float index;
  71. public MeshPoint meshPoint;
  72. public GameObject toolObj;
  73. private GameObject toolPrefab;
  74. [ValueDropdown("GetAllToolModel")]
  75. [ShowInInspector]
  76. public GameObject ToolPrefab
  77. {
  78. get
  79. {
  80. return toolPrefab;
  81. }
  82. set
  83. {
  84. if (toolPrefab != value)
  85. {
  86. toolPrefab = value;
  87. if (toolObj != null)
  88. {
  89. DestroyImmediate(toolObj);
  90. }
  91. toolObj = GameObject.Instantiate(toolPrefab);
  92. if (target != null)
  93. {
  94. toolObj.transform.parent = target.transform;
  95. toolObj.transform.localPosition = Vector3.zero;
  96. toolObj.transform.localRotation = Quaternion.identity;
  97. }
  98. }
  99. }
  100. }
  101. #if UNITY_EDITOR
  102. private void OnEnable()
  103. {
  104. EditorApplication.update += EditorUpdate;
  105. }
  106. private void OnDisable()
  107. {
  108. EditorApplication.update -= EditorUpdate;
  109. }
  110. void EditorUpdate()
  111. {
  112. if (!isPlaying) return;
  113. index += speed * Time.deltaTime;
  114. meshPoint = path.GetPos(index);
  115. meshPoint.position = meshPoint.position + meshPoint.normail.normalized * normailFloor;
  116. target.position = Vector3.Lerp(target.position, meshPoint.position, 0.5f);
  117. target.forward = Vector3.Slerp(target.forward, meshPoint.normail, speed);
  118. if (index > 1)
  119. {
  120. index = 0;
  121. isPlaying = false;
  122. }
  123. }
  124. private static IEnumerable GetAllToolModel()
  125. {
  126. var root = "Assets/ChivaXR/SimulationToolDev/ToolManager/ToolModel";
  127. return UnityEditor.AssetDatabase.GetAllAssetPaths()
  128. .Where(x => x.StartsWith(root))
  129. .Select(x => x.Substring(root.Length))
  130. .Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.GameObject>(root + x)));
  131. }
  132. #endif
  133. }
  134. }