107 lines
3.9 KiB
C#
107 lines
3.9 KiB
C#
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<PlayableDirector>();
|
|
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<PlayableDirector>();
|
|
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<PlayableDirector>();
|
|
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...");
|
|
}
|
|
}
|
|
}
|
|
}
|