LeoECS Proto - иерархические связи между сущностями

Иногда бывает нужно организовывать связь сущностей в виде Родитель-Ребенок, когда при удалении Родителя все его Дети автоматически удаляются, либо еще как-то реагируют на это событие. Так же необходимо быстро узнавать Родителя у сущности и наоборот - список всех Детей. Теперь в LeoECS Proto для решения этой задачи есть готовый модуль.

Обычно реализация заключается в навешивании компонента Родитель на главную сущность и хранение в нем списка зависимых сущностей. Для связи в обратную сторону на каждую зависимую сущность вешается компонент Ребенок для хранения ссылки на сущность Родителя. Вся логика по валидации этих связей реализуется либо в виде сервиса, либо в виде системы.

Модуль Leopotam.EcsProto.Parenting реализует связывание сущностей тем же способом, но не требуя от пользователя явного управления компонентами. Скрытые компоненты Родитель и Ребенок добавляются и управляются автоматически через апи, предоставляемое в виде методов аспекта модуля, достаточно выполнить инъекцию этого аспекта в систему (или получить его из мира любым способом):

1
2
3
using Leopotam.EcsProto.Parenting;
// ...
[DI] ParentingAspect _parenting = default;

Апи предоставляет следующий функционал:

  • Создание связи между двумя сущностями:
    1
    _parenting.SetParent (childEntity, parentEntity);
  • Разрывание установленной связи между сущностями:
    1
    _parenting.ClearParent (childEntity);
  • Настройка поведения при удалении родительской сущности. По умолчанию все дочерние сущности автоматически удаляются при удалении родительской - это можно поменять, чтобы дочерние сущности сохранялись, а связи с удаленным Родителем оставались, но не считались валидными:
    1
    _parenting.KeepChildrenOnDead(parentEntity, true);
  • Проверка наличия связи:
    1
    bool isChild = _parenting.IsParented (childEntity);
  • Получение ссылки на активного родителя:
    1
    (ProtoEntity entity, bool ok) = _parenting.Parent (childEntity);
  • Получение списка активных дочерних сущностей:
    1
    2
    Slice<ProtoEntity> result = new ();
    _parenting.Children (parentEntity, result);
Актуальные версии пакетов доступны в закрытом discord-сервере для vk/boosty-подписчиков.
Оформить подписку можно здесь: