Найти Entity: пути и уникальные имена
Относительный путь, %Name и область Owner; переименование, перемещение и проверка отсутствующего объекта.
Выбрать вид ссылки
| Нужна | Используйте |
|---|---|
| Известный ребёнок в текущем дереве | GetEntity<T>("Panel/Label") |
| Необязательный объект | GetEntityOrNull<T> с проверкой null |
| Объект, который перемещают внутри одного сохраняемого дерева | UniqueNameInOwner и путь %Name |
| Внешняя зависимость компонента | Переданную/экспортированную ссылку, если путь ему не принадлежит |
Путь использует имена Entity, а не имена классов. EntityPath — значение адреса, не ссылка, удерживающая объект. asset:// и uid:// адресуют ассеты и не заменяют пути GetEntity. Абсолютный путь /root начинается с главного Viewport и требует активного дерева.
Запустить проверку области
Сначала создайте Assets/BadgeStyle.rdata и Actors/Badge.rprefab из полного примера. Добавьте UniqueLookupDemo.cs, прикрепите к Entity тестового уровня, соберите и нажмите F6. Два префаба появляются отдельно; Output выводит три True: объекты различны, %Pivot пережил перенос, старый прямой путь отсутствует.
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));
}
}В каждом экземпляре Pivot имеет UniqueNameInOwner = true и своего владельца. Поэтому Left.GetEntity("%Pivot") и Right.GetEntity("%Pivot") находят разные объекты. Внешний корень не получает глобального %Pivot: переходите явно через Left/%Pivot или через ссылку на Left.
Что переживает уникальное имя
Перемещение Pivot под Mount внутри прежнего Owner сохраняет доступ по %Pivot, хотя прямой путь Pivot уже не работает. Переименование Pivot в Aim требует пути %Aim: уникальное имя не делает строку независимой от имени. Перенос за пределы владельца может очистить Owner и убрать запись из его области.
Два разных потомка с одним именем не могут одновременно занять один уникальный ключ одного Owner. В проверенном коде при конфликте новый претендент не получает уникальность и выводится предупреждение. У разных экземпляров префаба области могут содержать одинаковое имя.
В исходнике редактора команда Access as Unique Name меняет этот флаг. Кнопочный сценарий здесь не проверялся; пример задаёт флаг в сохранённом префабе и проверяет реальный поиск.
Диагностика
GetEntityOrNull<T> возвращает null и для отсутствующего пути, и при несовместимом типе: проверьте отдельно имя, область и ожидаемый класс. Для обязательного объекта GetEntity<T> помогает заметить ошибку раньше, но исключение не исправляет структуру уровня. Не обходите весь проект через FindChild каждый кадр вместо явной ссылки.
В C# нет сокращения с символом $ для GetEntity. Используйте точные методы SDK. Если ссылка закэширована, после QueueFree проверяйте native-жизнь объекта, а не только отличие от null.