using UnityEngine; using UnityEditor; using UnityEngine.Playables; using System.Collections.Generic; [ExecuteAlways] public class EditorTimelinePathTracker : MonoBehaviour { public Color pathColor = Color.green; public int maxPoints = 1000; private List pathPoints = new List(); private List timeStamps = new List(); private Vector3 lastPosition; private PlayableDirector director; private void OnEnable() { director = GetComponent(); #if UNITY_EDITOR EditorApplication.update += EditorUpdate; #endif pathPoints.Clear(); timeStamps.Clear(); lastPosition = transform.position; pathPoints.Add(lastPosition); timeStamps.Add(GetTimelineTime()); } private void OnDisable() { #if UNITY_EDITOR EditorApplication.update -= EditorUpdate; #endif } private float GetTimelineTime() { if (director != null && director.playableGraph.IsValid()) { return (float)director.time; } return Time.realtimeSinceStartup; // fallback 时间戳 } private float GetTimelineDuration() { return director != null ? (float)director.duration : -1f; } private void EditorUpdate() { if (Application.isPlaying) return; Vector3 currentPosition = transform.position; float currentTime = GetTimelineTime(); if (Vector3.Distance(currentPosition, lastPosition) > 0.01f) { lastPosition = currentPosition; pathPoints.Add(currentPosition); timeStamps.Add(currentTime); if (pathPoints.Count > maxPoints) { pathPoints.RemoveAt(0); timeStamps.RemoveAt(0); } SceneView.RepaintAll(); } } private void OnDrawGizmos() { if (pathPoints == null || pathPoints.Count < 2) return; float timelineDuration = GetTimelineDuration(); bool useTimeline = director != null && timelineDuration > 0; Gizmos.color = pathColor; for (int i = 1; i < pathPoints.Count; i++) { // 若启用Timeline,仅绘制在时间范围内的轨迹 if (useTimeline && (timeStamps[i - 1] > timelineDuration || timeStamps[i] > timelineDuration)) continue; Gizmos.DrawLine(pathPoints[i - 1], pathPoints[i]); } } }