diff --git a/FModel/ViewModels/AnimGraphViewModel.cs b/FModel/ViewModels/AnimGraphViewModel.cs
index 746212e8..4da8f3bc 100644
--- a/FModel/ViewModels/AnimGraphViewModel.cs
+++ b/FModel/ViewModels/AnimGraphViewModel.cs
@@ -239,8 +239,8 @@ public class AnimGraphViewModel
///
/// Renames state machine internal layers with a parent path prefix
- /// (e.g., "AnimGraph > Locomotion") to avoid name collisions with
- /// linked anim layer sub-graphs that may share the same base name.
+ /// (e.g., "AnimGraph > Locomotion" for the overview, or
+ /// "AnimGraph > Locomotion > Idle" for per-state sub-graphs).
///
private static void PrefixStateMachineLayerNames(AnimGraphViewModel vm)
{
@@ -272,7 +272,14 @@ public class AnimGraphViewModel
if (string.IsNullOrEmpty(smName))
continue;
- if (smParentLayer.TryGetValue(smName, out var parentName))
+ if (!smParentLayer.TryGetValue(smName, out var parentName))
+ continue;
+
+ // Per-state layers have a name different from the machine name
+ // (named after the StateResult node's Name property)
+ if (!layer.Name.Equals(smName, StringComparison.OrdinalIgnoreCase))
+ layer.Name = $"{parentName}{SubGraphPathSeparator}{smName}{SubGraphPathSeparator}{layer.Name}";
+ else
layer.Name = $"{parentName}{SubGraphPathSeparator}{smName}";
}
}
@@ -421,7 +428,8 @@ public class AnimGraphViewModel
private static string GetLayerName(List nodes, int index)
{
var rootNode = nodes.FirstOrDefault(n =>
- n.ExportType.EndsWith("_Root", StringComparison.OrdinalIgnoreCase) &&
+ (n.ExportType.EndsWith("_Root", StringComparison.OrdinalIgnoreCase) ||
+ n.ExportType.EndsWith("_StateResult", StringComparison.OrdinalIgnoreCase)) &&
n.AdditionalProperties.TryGetValue("Name", out _));
if (rootNode != null &&
rootNode.AdditionalProperties.TryGetValue("Name", out var rootName) &&
diff --git a/FModel/Views/AnimGraphViewer.xaml.cs b/FModel/Views/AnimGraphViewer.xaml.cs
index 3b9ce7aa..d4375367 100644
--- a/FModel/Views/AnimGraphViewer.xaml.cs
+++ b/FModel/Views/AnimGraphViewer.xaml.cs
@@ -563,10 +563,10 @@ public partial class AnimGraphViewer
}
else if (node.IsStateMachineState)
{
- // State nodes within an overview: try to open internal per-state layer
- // Internal layers share the state machine's path prefix name
- // (future: individual state layers could be opened here)
- return;
+ // State nodes within an overview: open the per-state internal sub-graph
+ // Per-state layers are named "overviewPath > stateName"
+ var overviewName = _currentLayerState?.Layer.Name ?? string.Empty;
+ layerName = $"{overviewName}{AnimGraphViewModel.SubGraphPathSeparator}{node.Name}";
}
else if (node.ExportType.Contains("StateMachine", StringComparison.OrdinalIgnoreCase))
{