using UnityEngine; using UnityEngine.Playables; using UnityEditor; using System.Collections.Generic; using UnityEngine.Timeline; using System.Linq; public class TimelineBindingCopier : Editor { private const string SourcePlayableDirectorKey = "SourcePlayableDirector"; // EditorPrefs 存储源 PlayableDirector 的键 [MenuItem("CONTEXT/PlayableDirector/Copy Bindings")] public static void CopyBindings() { PlayableDirector source = Selection.activeGameObject?.GetComponent(); if (source == null) { Debug.LogError("Please select a PlayableDirector to copy bindings from."); return; } // 保存当前选择的 PlayableDirector 到 EditorPrefs EditorPrefs.SetString(SourcePlayableDirectorKey, source.gameObject.name); Debug.Log($"Source PlayableDirector '{source.name}' saved. Now select the target PlayableDirector."); } [MenuItem("CONTEXT/PlayableDirector/Paste Bindings")] public static void PasteBindings() { PlayableDirector target = Selection.activeGameObject?.GetComponent(); if (target == null) { Debug.LogError("Please select a PlayableDirector to paste bindings to."); return; } string sourceObjectName = EditorPrefs.GetString(SourcePlayableDirectorKey, ""); if (string.IsNullOrEmpty(sourceObjectName)) { Debug.LogError("No source PlayableDirector saved. Please use 'Copy Bindings' first."); return; } GameObject sourceObject = GameObject.Find(sourceObjectName); if (sourceObject == null) { Debug.LogError($"Source PlayableDirector '{sourceObjectName}' not found. Please copy bindings again."); return; } PlayableDirector source = sourceObject.GetComponent(); if (source == null) { Debug.LogError($"Source PlayableDirector '{sourceObjectName}' does not have a PlayableDirector component."); return; } var sourceAsset = source.playableAsset as TimelineAsset; var targetAsset = target.playableAsset as TimelineAsset; if (sourceAsset == null || targetAsset == null) { Debug.LogError("Source or Target PlayableDirector does not contain a valid Timeline."); return; } // Paste bindings based on track indices PasteBindingsInternal(source, target, sourceAsset, targetAsset); } private static void PasteBindingsInternal(PlayableDirector source, PlayableDirector target, TimelineAsset sourceAsset, TimelineAsset targetAsset) { var sourceTracks = sourceAsset.GetOutputTracks().ToArray(); // Convert to array var targetTracks = targetAsset.GetOutputTracks().ToArray(); // Convert to array if (sourceTracks.Length != targetTracks.Length) { Debug.LogError("Source and Target timelines have different number of tracks."); return; } for (int i = 0; i < sourceTracks.Length; i++) { TrackAsset sourceTrack = sourceTracks[i]; TrackAsset targetTrack = targetTracks[i]; if (sourceTrack == null || targetTrack == null) { Debug.Log($"Skipping track at index {i} because it is null."); continue; } var sourceBinding = source.GetGenericBinding(sourceTrack); if (sourceBinding != null) { // Set the binding for the target PlayableDirector target.SetGenericBinding(targetTrack, sourceBinding); Debug.Log($"Binding pasted for track '{sourceTrack.name}' (Index {i})."); } else { Debug.Log($"No binding found for track '{sourceTrack.name}' (Index {i}), skipping..."); } } } }