using Sirenix.OdinInspector; using System.Collections; using System.Collections.Generic; using System.Linq; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; [ExecuteInEditMode] public class MovePathItem : MonoBehaviour { public GameObject moveTarget; public float moveSpeed = 4; public float rotateSpeed = 4; public float waitTime = 0; public List movePathPoints = new List(); public List GetMovePathPoints(bool reverse = false) { List tmpMovePathPoints = new List(); tmpMovePathPoints.AddRange(movePathPoints); if (reverse) { tmpMovePathPoints.Reverse(); } return tmpMovePathPoints; } public void SetInitState(bool reverse) { int id = reverse ? (movePathPoints.Count - 1) : 0; moveTarget.transform.position = movePathPoints[id].position; moveTarget.transform.rotation = movePathPoints[id].rotation; } public void SetFinishedState(bool reverse) { int id = reverse ? 0 : (movePathPoints.Count - 1); moveTarget.transform.position = movePathPoints[id].position; moveTarget.transform.rotation = movePathPoints[id].rotation; } #if UNITY_EDITOR [Button("添加移动路径")] public void AddMovePath() { if (moveTarget == null) { Debug.LogError("未添加动画主体"); return; } GameObject pathItem = new GameObject("MovePath"); if (movePathPoints.Count == 0) { pathItem.transform.position = moveTarget.transform.position; pathItem.transform.rotation = moveTarget.transform.rotation; } else { pathItem.transform.position = movePathPoints[movePathPoints.Count - 1].position; pathItem.transform.rotation = movePathPoints[movePathPoints.Count - 1].rotation; } pathItem.transform.parent = this.transform; pathItem.transform.localScale = Vector3.one; pathItem.transform.SetAsLastSibling(); movePathPoints.Add(pathItem.transform); Selection.activeGameObject = pathItem; if (isShowPose) { GameObject cloneItem = GameObject.Instantiate(moveTarget, pathItem.transform); cloneItem.transform.localPosition = Vector3.zero; cloneItem.transform.localRotation = Quaternion.identity; cloneItem.transform.localScale = moveTarget.transform.lossyScale; } else { ShowMovePos(); } } [HideInInspector] public bool isShowPath = true; [HideInInspector] public bool isShowPose = false; public bool ShowPath { get { return isShowPath; } } public bool ClosePath { get { return !isShowPath; } } [Button("展示物体姿态")] [ShowIf("@!isShowPose")] public void ShowMovePos() { foreach (var item in movePathPoints) { GameObject cloneItem = GameObject.Instantiate(moveTarget, item); cloneItem.transform.localPosition = Vector3.zero; cloneItem.transform.localRotation = Quaternion.identity; cloneItem.transform.localScale = moveTarget.transform.lossyScale; } isShowPose = true; isShowPath = true; } [Button("关闭物体姿态")] [ShowIf("@isShowPose")] public void CloseMovePos() { foreach (var item in movePathPoints) { DestroyChild(item); } isShowPose = false; isShowPath = false; } [ContextMenu("反转排序")] public void ResevePathPoints() { movePathPoints.Reverse(); } private void OnDrawGizmos() { DrawPathLine(); } public void DrawPathLine() { if (!isShowPath) return; Gizmos.color = Color.white; for (int i = 0; i < movePathPoints.Count; i++) { if (i + 1 < movePathPoints.Count) { Gizmos.color = Color.yellow; Gizmos.DrawLine(movePathPoints[i].position, movePathPoints[i + 1].position); } } } /// /// 销毁所有子级信息 /// /// private void DestroyChild(Transform item) { if (item.childCount == 0) return; for (int i = item.childCount - 1; i >= 0; i--) { DestroyImmediate(item.GetChild(i).gameObject); } } [Button("Play")] public void Play() { index = 0; targetPoint = movePathPoints[index]; moveTarget.transform.position = targetPoint.position; moveTarget.transform.rotation = targetPoint.rotation; isPlaying = true; } [HideInInspector] public bool isPlaying; private void OnEnable() { EditorApplication.update += EditorUpdate; Selection.selectionChanged += SelectionChanged; } private void OnDisable() { EditorApplication.update -= EditorUpdate; Selection.selectionChanged -= SelectionChanged; } private Transform targetPoint; private int index; void EditorUpdate() { if (!isPlaying) return; moveTarget.transform.position = Vector3.MoveTowards(moveTarget.transform.position, targetPoint.position, moveSpeed * Time.deltaTime); moveTarget.transform.rotation = Quaternion.Lerp(moveTarget.transform.rotation, targetPoint.rotation, rotateSpeed * Time.deltaTime); if (Vector3.Distance(moveTarget.transform.position, targetPoint.position) < 0.02f && Quaternion.Angle(moveTarget.transform.rotation, targetPoint.rotation) < 5) { moveTarget.transform.position = targetPoint.position; moveTarget.transform.rotation = targetPoint.rotation; index++; if (index < movePathPoints.Count) { targetPoint = movePathPoints[index]; } else { index = 0; targetPoint = movePathPoints[0]; moveTarget.transform.position = targetPoint.position; moveTarget.transform.rotation = targetPoint.rotation; isPlaying = false; } } } void SelectionChanged() { if (Selection.gameObjects.Contains(this.gameObject)) { isShowPath = true; } else if (!isShowPose) { isShowPath = false; } } #endif }