using Sirenix.OdinInspector; using System.Collections; using System.Linq; using UnityEditor; using UnityEngine; namespace SK.Framework { [ExecuteInEditMode] public class SimpleBezierCurvePathAlonger : MonoBehaviour { public enum UpdateMode { FixedUpdate, Update, LateUpdate, } public Transform target; [SerializeField] private SimpleBezierCurvePath path; [SerializeField] private float speed = .1f; [SerializeField] private UpdateMode updateMode = UpdateMode.Update; private float normalized = 0f; private Vector3 lastPosition; private void FixedUpdate() { return; if (updateMode == UpdateMode.FixedUpdate && path != null) MoveAlongPath(); } private void Update() { return; if (updateMode == UpdateMode.Update && path != null) MoveAlongPath(); } private void LateUpdate() { return; if (updateMode == UpdateMode.LateUpdate && path != null) MoveAlongPath(); } private void MoveAlongPath() { float t = normalized + speed * Time.deltaTime; float max = path.Points.Count - 1 < 1 ? 0 : (path.Loop ? path.Points.Count : path.Points.Count - 1); normalized = (path.Loop && max > 0) ? ((t %= max) + (t < 0 ? max : 0)) : Mathf.Clamp(t, 0, max); target.position = path.EvaluatePosition(normalized); Vector3 forward = target.position - lastPosition; target.forward = forward != Vector3.zero ? forward : target.forward; lastPosition = target.position; } private void MoveTargetPointsPath() { float t = normalized + speed * Time.deltaTime; target.position = path.GetPos(normalized).position; Vector3 forward = target.position - lastPosition; target.forward = forward != Vector3.zero ? forward : target.forward; lastPosition = target.position; } [Button("Play")] public void Play() { isPlaying = true; meshPoint = path.GetPos(0); target.position = meshPoint.position; target.forward = meshPoint.normail; index = 0; } public bool isPlaying; public float normailFloor = 0.05f; public float index; public MeshPoint meshPoint; public GameObject toolObj; private GameObject toolPrefab; [ValueDropdown("GetAllToolModel")] [ShowInInspector] public GameObject ToolPrefab { get { return toolPrefab; } set { if (toolPrefab != value) { toolPrefab = value; if (toolObj != null) { DestroyImmediate(toolObj); } toolObj = GameObject.Instantiate(toolPrefab); if (target != null) { toolObj.transform.parent = target.transform; toolObj.transform.localPosition = Vector3.zero; toolObj.transform.localRotation = Quaternion.identity; } } } } #if UNITY_EDITOR private void OnEnable() { EditorApplication.update += EditorUpdate; } private void OnDisable() { EditorApplication.update -= EditorUpdate; } void EditorUpdate() { if (!isPlaying) return; index += speed * Time.deltaTime; meshPoint = path.GetPos(index); meshPoint.position = meshPoint.position + meshPoint.normail.normalized * normailFloor; target.position = Vector3.Lerp(target.position, meshPoint.position, 0.5f); target.forward = Vector3.Slerp(target.forward, meshPoint.normail, speed); if (index > 1) { index = 0; isPlaying = false; } } private static IEnumerable GetAllToolModel() { var root = "Assets/ChivaXR/SimulationToolDev/ToolManager/ToolModel"; return UnityEditor.AssetDatabase.GetAllAssetPaths() .Where(x => x.StartsWith(root)) .Select(x => x.Substring(root.Length)) .Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath(root + x))); } #endif } }