From 46602803dcfeb62763d14acb0d6e6cdf62c605a7 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Thu, 16 Jul 2026 18:49:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A8=E7=94=BB=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=AC=AC=E4=BA=94=E9=98=B6=E6=AE=B5=EF=BC=88=E6=9C=AA=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FrameAnimationGraphAuthoringServices.cs | 64 ++ .../FrameAnimationGraphEditor.uss | 72 ++ .../FrameAnimationGraphEditor.uss.meta | 9 + .../FrameAnimationGraphEditorWindow.cs | 616 ++++++++++++++++-- .../FrameAnimation/FrameAnimationGraphView.cs | 144 +++- .../FrameAnimation/FrameAnimationPreview.cs | 593 +++++++++++++++++ .../FrameAnimationPreview.cs.meta | 2 + .../FrameAnimationPreviewElement.cs | 163 +++++ .../FrameAnimationPreviewElement.cs.meta | 2 + .../FrameAnimationPreviewSampleBuilder.cs | 142 ++++ ...FrameAnimationPreviewSampleBuilder.cs.meta | 2 + .../Import/FrameAnimationGraph.asset | 39 +- .../Test/FrameAnimation/Preview.meta | 8 + .../Preview/PreviewSampleGraph.asset | 243 +++++++ .../Preview/PreviewSampleGraph.asset.meta | 8 + .../Runtime/FrameAnimationPlaybackSession.cs | 64 +- .../Runtime/FrameAnimationResolver.cs | 53 ++ .../FrameAnimationGraphAuthoringTests.cs | 134 ++++ .../EditMode/FrameAnimationPreviewTests.cs | 248 +++++++ .../FrameAnimationPreviewTests.cs.meta | 2 + Docs/帧动画系统第五阶段手动测试.md | 79 +++ Docs/帧动画系统第五阶段手动测试.md.meta | 7 + Docs/帧动画系统第四阶段手动测试.md | 13 +- 23 files changed, 2591 insertions(+), 116 deletions(-) create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss.meta create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreview.cs create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreview.cs.meta create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreviewElement.cs create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreviewElement.cs.meta create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreviewSampleBuilder.cs create mode 100644 Assets/Editor/FrameAnimation/FrameAnimationPreviewSampleBuilder.cs.meta create mode 100644 Assets/GameContent/Test/FrameAnimation/Preview.meta create mode 100644 Assets/GameContent/Test/FrameAnimation/Preview/PreviewSampleGraph.asset create mode 100644 Assets/GameContent/Test/FrameAnimation/Preview/PreviewSampleGraph.asset.meta create mode 100644 Assets/Tests/FrameAnimation/EditMode/FrameAnimationPreviewTests.cs create mode 100644 Assets/Tests/FrameAnimation/EditMode/FrameAnimationPreviewTests.cs.meta create mode 100644 Docs/帧动画系统第五阶段手动测试.md create mode 100644 Docs/帧动画系统第五阶段手动测试.md.meta diff --git a/Assets/Editor/FrameAnimation/FrameAnimationGraphAuthoringServices.cs b/Assets/Editor/FrameAnimation/FrameAnimationGraphAuthoringServices.cs index bd562cbe7..aa2216769 100644 --- a/Assets/Editor/FrameAnimation/FrameAnimationGraphAuthoringServices.cs +++ b/Assets/Editor/FrameAnimation/FrameAnimationGraphAuthoringServices.cs @@ -6,6 +6,70 @@ using UnityEngine; namespace AibisDream.FrameAnimation.Editor { + internal static class FrameAnimationFlowFocusPolicy + { + public static AnimationFlow FindFocusedFlow(FrameAnimationGraph graph, string focusedFlowId) + { + return graph?.Flows.FirstOrDefault(flow => flow != null && flow.Id == focusedFlowId); + } + + public static bool Contains( + FrameAnimationGraph graph, + string focusedFlowId, + FrameAnimationEditorSelection selection) + { + var flow = FindFocusedFlow(graph, focusedFlowId); + if (flow == null) + { + return false; + } + var reachable = new FrameAnimationGraphTopology(graph).GetReachable(flow.EntryNodeId); + return selection.Value switch + { + AnimationNode node => reachable.Nodes.Contains(node), + AnimationEdge edge => reachable.Edges.Contains(edge), + AnimationFlow selectedFlow => selectedFlow == flow, + _ => false + }; + } + + public static bool ShouldExitForSelection( + FrameAnimationGraph graph, + string focusedFlowId, + FrameAnimationEditorSelection selection) + { + if (string.IsNullOrEmpty(focusedFlowId)) + { + return false; + } + return selection.Kind switch + { + FrameAnimationEditorSelectionKind.None => false, + FrameAnimationEditorSelectionKind.Flow => false, + FrameAnimationEditorSelectionKind.Node => !Contains(graph, focusedFlowId, selection), + FrameAnimationEditorSelectionKind.Edge => !Contains(graph, focusedFlowId, selection), + _ => true + }; + } + + public static bool ShouldExitForSelectionSet( + FrameAnimationGraph graph, + string focusedFlowId, + IEnumerable selections) + { + if (string.IsNullOrEmpty(focusedFlowId)) + { + return false; + } + var items = (selections ?? Array.Empty()).ToArray(); + return items.Length > 0 && items.Any(item => + (item.Kind == FrameAnimationEditorSelectionKind.Node || + item.Kind == FrameAnimationEditorSelectionKind.Edge) + ? !Contains(graph, focusedFlowId, item) + : ShouldExitForSelection(graph, focusedFlowId, item)); + } + } + internal sealed class FrameAnimationGraphImpact { public IReadOnlyList Flows { get; } diff --git a/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss new file mode 100644 index 000000000..0bfb16281 --- /dev/null +++ b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss @@ -0,0 +1,72 @@ +.fa-preview { + position: relative; + overflow: hidden; + border-left-width: 1px; + border-right-width: 1px; + border-top-width: 1px; + border-bottom-width: 1px; + border-left-color: rgb(25, 25, 25); + border-right-color: rgb(25, 25, 25); + border-top-color: rgb(25, 25, 25); + border-bottom-color: rgb(25, 25, 25); +} + +.fa-preview__image { + position: absolute; +} + +.fa-preview__empty { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + -unity-text-align: middle-center; + color: rgb(190, 190, 190); +} + +.fa-node__preview { + height: 82px; + margin-top: 5px; +} + +.fa-node--preview-current { + border-left-color: rgb(55, 174, 240); + border-right-color: rgb(55, 174, 240); + border-top-color: rgb(55, 174, 240); + border-bottom-color: rgb(55, 174, 240); +} + +.fa-node--preview-passed { + border-left-color: rgb(83, 154, 113); +} + +.fa-node--preview-upcoming { + opacity: 0.72; +} + +.fa-clip-preview-panel { + flex-shrink: 0; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 5px; + border-bottom-width: 1px; + border-bottom-color: rgb(28, 28, 28); +} + +.fa-clip-preview-panel .fa-preview { + height: 190px; + margin-bottom: 4px; +} + +.fa-preview-controls { + flex-direction: row; + align-items: center; +} + +.fa-preview-status { + font-size: 10px; + color: rgb(185, 185, 185); + margin-top: 2px; +} diff --git a/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss.meta b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss.meta new file mode 100644 index 000000000..37c3f50ed --- /dev/null +++ b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditor.uss.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a38dd39c699e42348667cc1264ea9076 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/FrameAnimation/FrameAnimationGraphEditorWindow.cs b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditorWindow.cs index 85e254869..e556ccf70 100644 --- a/Assets/Editor/FrameAnimation/FrameAnimationGraphEditorWindow.cs +++ b/Assets/Editor/FrameAnimation/FrameAnimationGraphEditorWindow.cs @@ -33,6 +33,8 @@ namespace AibisDream.FrameAnimation.Editor private Label canvasLabel; private FrameAnimationGraphView graphView; private PopupField flowFocusField; + private Label flowFocusStatusLabel; + private ToolbarButton exitFlowFocusButton; private string focusedFlowId = string.Empty; private IReadOnlyList multiSelectedNodes = Array.Empty(); private AnimationNode lastSelectedNode; @@ -64,6 +66,21 @@ namespace AibisDream.FrameAnimation.Editor private SerializedObject clipSerializedObject; private FrameClip frameListClip; private ReorderableList frameList; + private readonly FrameAnimationPreviewCoordinator previewCoordinator = new FrameAnimationPreviewCoordinator(); + private readonly List previewTimelineSliders = new List(); + private readonly List