Find an Entity: paths and unique names
Relative paths, %Name and Owner scopes; renaming, reparenting and handling missing objects.
Choose a reference
| Need | Use |
|---|---|
| A known child in the current tree | GetEntity<T>("Panel/Label") |
| An optional object | GetEntityOrNull<T> and check null |
| An object moved within one saved tree | UniqueNameInOwner and %Name |
| A component's external dependency | An injected/exported reference when it does not own the path |
Paths use Entity names, not class names. EntityPath is an address value, not a reference retaining an object. asset:// and uid:// address assets rather than GetEntity targets. The absolute /root path starts at the main Viewport and requires an active tree.
Run the scope check
First create Assets/BadgeStyle.rdata and Actors/Badge.rprefab from the complete example. Add UniqueLookupDemo.cs, attach it to an Entity in a test level, build and press F6. Two separate prefabs appear; Output reports three True values: different objects, %Pivot survives reparenting and the old direct path is absent.
UniqueLookupDemo.cs
using Reckfell;
public partial class UniqueLookupDemo : Entity
{
public Entity2D Left { get; private set; } = null!;
public Entity2D Right { get; private set; } = null!;
public Marker2D LeftPivot { get; private set; } = null!;
public Marker2D RightPivot { get; private set; } = null!;
public override void _Ready()
{
var packed = ResourceLoader.Load<PackedEntity>("asset://Actors/Badge.rprefab");
Left = packed.Instantiate<Entity2D>();
Right = packed.Instantiate<Entity2D>();
Left.Name = "Left";
Right.Name = "Right";
Left.Position = new Vector2(100, 190);
Right.Position = new Vector2(350, 190);
AddChild(Left);
AddChild(Right);
LeftPivot = Left.GetEntity<Marker2D>("%Pivot");
RightPivot = Right.GetEntity<Marker2D>("%Pivot");
LeftPivot.Reparent(Left.GetEntity<Entity2D>("Mount"));
ReckfellApi.Print("Different instances: " + (LeftPivot != RightPivot));
ReckfellApi.Print("Unique lookup survives reparent: " + (Left.GetEntity<Marker2D>("%Pivot") == LeftPivot));
ReckfellApi.Print("Old direct path missing: " + (Left.GetEntityOrNull("Pivot") is null));
}
}Each instance's Pivot has UniqueNameInOwner = true and its own owner. Left.GetEntity("%Pivot") and Right.GetEntity("%Pivot") therefore return different objects. The outer root gains no global %Pivot: explicitly cross through Left/%Pivot or a Left reference.
Changes a unique name survives
Reparenting Pivot under Mount within the same Owner retains %Pivot lookup, though the direct Pivot path stops working. Renaming Pivot to Aim requires %Aim: a unique name does not make a string independent of the name. Moving outside its owner's hierarchy can clear Owner and remove the scope entry.
Two different descendants cannot simultaneously claim one unique key in one Owner scope. In the checked source, the new claimant loses uniqueness and produces a warning. Separate prefab instances can each have the same scoped name.
The editor source exposes Access as Unique Name for this flag. Its mouse workflow was not tested here; the example sets the saved prefab flag and verifies actual lookup.
Diagnose lookup
GetEntityOrNull<T> returns null for a missing path and an incompatible type: check name, scope and expected class separately. GetEntity<T> helps reveal a broken required dependency sooner, but an exception does not repair the level structure. Do not traverse the entire project with FindChild every frame instead of keeping an explicit reference.
C# has no $ shorthand for GetEntity. Use the exact SDK methods. For a cached reference after QueueFree, check native object validity rather than only comparing against null.