Пройдя несколько шаблонов игрового дизайна, я выбрал Entity-Component-System (ES System) для моего игрового движка. Я читаю статьи (в основном T = Machine ) и рассматриваю некоторый исходный код, и я думаю, что получил достаточно, чтобы начать.
Есть только одна основная идея, с которой я борюсь. Как мне работать с группами объектов, которые зависят друг от друга?
Позвольте мне использовать пример:
Предположим, я делаю стандартный верхний шутер (например, Джеймстаун ) и хочу создать «босс-сущность» с несколькими различными, но соединенными частями. Разбивка может выглядеть примерно так:
- Тело корабля: движение, рендеринг
- Пушка: Положение (заблокировано относительно корпуса корабля), Отслеживание \ Огонь у героя, Получение урона до отключения
- Ядро: Положение (заблокировано относительно корпуса корабля), Отслеживание \ Огонь героя, Получение урона до отключения, Отключение (э-э ... уничтожение) всех других объектов в группе корабля.
Моей целью было бы то, что можно было бы идентифицировать (и манипулировать) в качестве отдельного игрового элемента без необходимости переписывать подсистему с нуля каждый раз, когда я хочу построить новый агрегатный элемент.
Как мне реализовать этот вид дизайна в ES System?
- Реализую ли я какие-то отношения сущности родитель-потомок (сущности могут иметь детей)? Это, кажется, противоречит методологии, согласно которой сущности являются просто пустым контейнером, и заставляет их чувствовать себя более ООП.
- Реализую ли я их как отдельные сущности, с каким-то связующим компонентом (BossComponent) и связанной системой (BossSubSystem)? Я не могу не думать, что это будет сложно реализовать, поскольку взаимодействие компонентов кажется большой медвежьей ловушкой.
- Реализую ли я их как один объект с набором компонентов (ShipComponent, CannonComponents, CoreComponent)? Похоже, что это отклоняется от намерения системы ES (компоненты здесь кажутся слишком похожими на объекты с большим весом), но я знаю об этом, поэтому я решил, что я это изложу.
- Я реализую их как что-то еще, что я упомянул?
Я знаю, что это очень легко реализовать в ООП, но я остановлюсь на выборе ES вместо ООП. Если мне потребуется порвать с чистой теорией ES для реализации этого дизайна, я сделаю это (не то чтобы раньше мне не приходилось ставить под угрозу чистый дизайн), но я бы предпочел сделать это по соображениям производительности, а не начинать с плохого дизайна.
Для дополнительного кредита, подумайте о том же дизайне, но каждая из «сущностей босса» фактически была связана с более крупной «сущностью BigBoss», состоящей из основного корпуса, основного ядра и 3 «боссовых сущностей». Это позволило бы мне увидеть решение по крайней мере для 3 измерений (дедушка-родитель-ребенок) ... которого должно быть более чем достаточно для меня.
источник
Ответы:
Если бы я был в такой ситуации, я бы создал каждую часть босса как отдельную сущность. Эти «суб-сущности» будут включать в себя некоторый вид
AttachmentPoint
илиParentEntity
компонент. Этот компонент будет включать ссылку на родительскую сущность и смещение от родительской позиции. При обновлении позиции они проверяют родительскую позицию и применяют смещение для создания своей собственной позиции. Кроме того, он может выполнять проверки, чтобы гарантировать, что родительский объект все еще существует. Кроме того, вы можете иметьSubEntity
компонент, который отслеживает существование дочерних объектов для родительского объекта. Это позволяет вам делать такие вещи, как только сделать ядро босса уязвимым, когда оружие со щитами уничтожено.В настоящее время я использую
TargetEntity
компонент в своей игре, который используется для отслеживания турелей и когда гоблины собирают ресурсы. Он может проверить позицию целевой сущности и соответственно изменить ее поведение. Объекты, у которых нет позиции, никогда не добавляются в качестве цели, поэтому здесь нет никаких проблем. Тем не менее, когда вы углубляетесь в детали, например, проверяете здоровье родительского или дочернего объекта, щит, запасы мощности или что-то еще, вы должны убедиться, что родительский или дочерний объект действительно имеет связанный компонент.Делая каждую часть своей собственной сущностью, вы поддерживаете гибкость структуры сущности / компонента, позволяя вам добавлять дополнительные и разные компоненты к каждой части начальника. Например, одна часть босса может иметь компонент оружия и компонент здоровья, а другая - компонент щита и компонент здоровья.
Я нашел другое обсуждение по этой теме здесь . В котором пользователи обсуждают добавление нескольких компонентов одного типа к одной сущности (что для меня кажется плохой идеей). Это кажется полезным разговором, хотя я не прочитал всю дискуссию.
источник
Не зная слишком много подробностей о ваших существующих системах, я бы смоделировал это (и в некоторой степени в своей собственной системе сущностей), чтобы иметь такой компонент, как AttachedTo (parentEntity). Любому из потомков может быть присвоен компонент AttachedTo (boss).
Затем система рендеринга (или что-то еще) захватывает объекты с компонентами: Position, AttachedTo и т. Д. И формирует правильные иерархии.
источник
Если вы хотите, чтобы сущность была представлена только идентификатором, то удержание сущностей может быть сделано через специальный компонент. Вы можете назвать его CompositeComponent, и он содержит список идентификаторов дочерних объектов и интерфейсы для добавления / удаления дочерних элементов из этого списка.
Очевидно, что любые компоненты, которые зависят от положения и т. Д., Должны будут работать с этим, чтобы правильно разместить объект. Как это реализовать, будет зависеть от того, как вы реализуете позиционирование в настоящее время.
Между прочим, не существует «чистой теории ES» - создание сущностей из компонентов является популярным подходом, но точный метод еще не стандартизирован.
источник