feat: 帧动画系统Timeline兼容

This commit is contained in:
2026-07-22 02:32:04 +08:00
parent 9b2caf64c9
commit c6c76666ef
48 changed files with 2947 additions and 31 deletions
@@ -68,6 +68,7 @@ namespace AibisDream.FrameAnimation.Editor
private SerializedObject clipSerializedObject;
private FrameClip frameListClip;
private ReorderableList frameList;
private bool frameListEditable;
private readonly FrameAnimationPreviewCoordinator previewCoordinator = new FrameAnimationPreviewCoordinator();
private readonly List<Slider> previewTimelineSliders = new List<Slider>();
private readonly List<Label> previewTimeLabels = new List<Label>();
@@ -1419,7 +1420,10 @@ namespace AibisDream.FrameAnimation.Editor
}
EnsureFrameList(clip);
clipSerializedObject.Update();
EditorGUILayout.LabelField(clip.IsImported ? "Imported Clip" : "Manual Clip", EditorStyles.boldLabel);
EditorGUILayout.LabelField(
clip.IsImported ? "Graph Imported Clip" :
clip.HasStandaloneImportSource ? "Source-linked External Clip" : "Manual Clip",
EditorStyles.boldLabel);
using (new EditorGUI.DisabledScope(true))
{
EditorGUILayout.PropertyField(clipSerializedObject.FindProperty("id"));
@@ -1440,14 +1444,29 @@ namespace AibisDream.FrameAnimation.Editor
EditorGUILayout.LabelField("Source Tag", clip.ImportInfo.SourceTagName);
EditorGUILayout.LabelField("Missing", clip.ImportInfo.IsMissingFromSource ? "Yes" : "No");
}
else if (clip.HasStandaloneImportSource)
{
EditorGUILayout.LabelField("Source Tag",
string.IsNullOrEmpty(clip.StandaloneImportSource.LastImportedTagName)
? "<all frames>"
: clip.StandaloneImportSource.LastImportedTagName);
if (GUILayout.Button("Open Standalone Clip Editor"))
{
FrameClipEditorWindow.Open(clip);
}
}
if (clipSerializedObject.ApplyModifiedProperties())
{
EditorUtility.SetDirty(clip);
}
if (!clip.IsImported)
if (!clip.IsImported && !clip.HasStandaloneImportSource)
{
frameList.DoLayoutList();
if (clipSerializedObject.ApplyModifiedProperties())
{
EditorUtility.SetDirty(clip);
}
if (frameList.index >= 0 && GUILayout.Button("Duplicate Selected Frame"))
{
DuplicateFrame(clipSerializedObject.FindProperty("frames"), frameList.index);
@@ -1476,6 +1495,13 @@ namespace AibisDream.FrameAnimation.Editor
});
}
}
else if (clip.HasStandaloneImportSource)
{
using (new EditorGUI.DisabledScope(true))
{
frameList.DoLayoutList();
}
}
if (GUILayout.Button("Rename Clip ID"))
{
@@ -1493,17 +1519,20 @@ namespace AibisDream.FrameAnimation.Editor
private void EnsureFrameList(FrameClip clip)
{
if (frameListClip == clip && frameList != null)
var editable = !clip.IsImported && !clip.HasStandaloneImportSource;
if (frameListClip == clip && frameList != null && frameListEditable == editable)
{
return;
}
frameListClip = clip;
frameListEditable = editable;
clipSerializedObject = new SerializedObject(clip);
var frames = clipSerializedObject.FindProperty("frames");
frameList = new ReorderableList(clipSerializedObject, frames, !clip.IsImported, true, !clip.IsImported, !clip.IsImported)
frameList = new ReorderableList(clipSerializedObject, frames, editable, true, editable, editable)
{
elementHeight = 72f,
drawHeaderCallback = rect => EditorGUI.LabelField(rect, "Frames (frameName/sourceIndex are read-only)"),
drawHeaderCallback = rect => EditorGUI.LabelField(rect,
editable ? "Frames (frameName/sourceIndex are read-only)" : "Frames (source-managed, read-only)"),
drawElementCallback = (rect, index, active, focused) => DrawFrameElement(frames, rect, index),
onAddCallback = list => AddFrame(frames),
onRemoveCallback = list =>
@@ -2472,6 +2501,11 @@ namespace AibisDream.FrameAnimation.Editor
}
if (asset is FrameClip clip)
{
if (!AssetDatabase.IsSubAsset(clip))
{
FrameClipEditorWindow.Open(clip);
return true;
}
var owners = FrameAnimationAssetReferenceIndex.FindGraphsReferencing(clip);
if (owners.Count == 1)
{