Files
GhostEngine/Ghost.Editor.Core/SceneGraph/SceneNode.cs
Misaki fdf831630b feat: implement complete scene graph system with hierarchical editor support
- Add SceneNode and EntityNode classes for editor-only metadata storage
- Implement SceneGraph view-model with O(1) entity lookup via internal caching
- Create IdRemapTable for file-local to global entity ID remapping on load
- Implement SceneSerializationContext for load/save operation tracking
- Add JSON-serializable SceneAssetData, EntityData, and ComponentData models
- Implement SceneSerializer for save/load with validation and reference remapping
- Add comprehensive documentation: README.md, IMPLEMENTATION_GUIDE.md, SYSTEM_SUMMARY.md
- Update Ghost.Editor.Core.csproj to reference Ghost.Entities assembly
- Support parent-child relationships via Hierarchy component
- Enforce no cross-scene entity references
- Keep runtime minimal: only SceneID, Hierarchy, LocalToWorld components
- All editor metadata (names, UI state) stored in editor-only SceneNode/EntityNode classes

This implements the architecture from SceneGraph Plan.md with clean separation of concerns,
minimal runtime footprint, and AOT compatibility.
2026-01-25 21:42:03 +09:00

51 lines
1.4 KiB
C#

using System.Collections.ObjectModel;
using Ghost.Entities;
namespace Ghost.Editor.Core.SceneGraph;
/// <summary>
/// Represents a Scene node in the editor hierarchy.
/// Contains editor-only metadata like name and display state.
/// The actual scene data (entities, components) is stored as SceneID in the runtime ECS world.
/// </summary>
public class SceneNode
{
public string Name { get; set; }
public short SceneId { get; private set; }
public Guid SceneGuid { get; private set; }
/// <summary>
/// Child entity nodes belonging to this scene.
/// </summary>
public ObservableCollection<EntityNode> Children { get; }
public SceneNode(string name, short sceneId, Guid? sceneGuid = null)
{
Name = name;
SceneId = sceneId;
SceneGuid = sceneGuid ?? Guid.NewGuid();
Children = new ObservableCollection<EntityNode>();
}
/// <summary>
/// Finds an entity node by its global entity ID.
/// Searches recursively through the hierarchy.
/// </summary>
public EntityNode? FindEntityNode(Entity entityId)
{
foreach (var child in Children)
{
if (child.EntityId == entityId)
return child;
var found = child.FindRecursive(entityId);
if (found != null)
return found;
}
return null;
}
public override string ToString() => $"Scene: {Name} (ID: {SceneId})";
}