Множество источников движения в системе сущностей


9

Я довольно новичок в идее систем сущностей, прочитав кучу вещей (наиболее полезно, этот отличный блог и этот ответ ).

Хотя у меня возникли небольшие проблемы с пониманием, как что-то столь же простое, как возможность манипулировать положением объекта с помощью неопределенного числа источников.

То есть у меня есть моя сущность, которая имеет компонент позиции. Затем в игре есть какое-то событие, которое сообщает этой сущности, чтобы она прошла определенное расстояние в данное время.

Эти события могут произойти в любое время и будут иметь разные значения для позиции и времени. В результате они будут составлены вместе.

В традиционном ОО-решении у меня был бы какой-то MoveByкласс, который содержит расстояние / время и массив из них внутри моего класса игровых объектов. В каждом кадре я бы перебрал все MoveByи применил его к позиции. Если a MoveByдостиг времени окончания, удалите его из массива.

С системой сущностей меня немного смущает то, как я должен воспроизводить такое поведение.

Если бы одновременно было только одно из них, вместо того, чтобы соединять их вместе, это было бы довольно просто (я считаю) и выглядело бы примерно так:

PositionComponent содержащий x, y

MoveByComponent содержащий x, y, time

Entityкоторый имеет как PositionComponentиMoveByComponent

MoveBySystemкоторый ищет сущность с обоими этими компонентами и добавляет значение MoveByComponentк PositionComponent. Когда timeдостигается, он удаляет компонент из этой сущности.

Я немного сбит с толку относительно того, как бы я делал то же самое со многими движениями.

Мои первоначальные мысли таковы:

PositionComponentтак MoveByComponentже, как и выше

MoveByCollectionComponentкоторый содержит массив MoveByComponentс

MoveByCollectionSystemкоторый ищет сущность с a PositionComponentи a MoveByCollectionComponent, перебирает MoveByComponents внутри него, применяя / удаляя при необходимости.

Я предполагаю, что это более общая проблема: иметь много одинаковых компонентов и хотеть, чтобы соответствующая система воздействовала на каждый. Мои сущности содержат свои компоненты внутри хеша типа компонента -> компонента, поэтому строго имеют только 1 компонент определенного типа для каждой сущности.

  1. Это правильный способ смотреть на это?

  2. Должна ли сущность иметь только один компонент данного типа за все время?


1
Похоже, что MoveByфункциональность - это просто скорость? Похоже, вы на правильном пути. Что касается вашего второго вопроса, существует множество различных реализаций систем сущностей / компонентов. Описанный в моем ответе, который вы связали, будет иметь только один компонент данного типа.
MichaelHouse

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

Я делаю это так: у меня есть PlayerInputComponent и AIInputComponent (или системы), которые сообщают MobileBehaviorComponent, что при нажатии на клавиатуре или AI, думающих, что мобильное устройство должно куда-то двигаться, MobileBehaviorComponent будет хранить, что оно должно куда-то перемещаться (в нем есть FSM для мобильных действий) и некоторая система переместит это. Ваша гранулярность слишком велика, с компонентами более высокого уровня, такими как Transform, Model, Light, Mob, все работает так же хорошо. Также мне никогда не нужно было удалять компоненты - я думаю о них больше как о чем-то, что описывает игровой объект, поэтому он не может просто исчезнуть.
Кикаймару

Этот конкретный пример MoveBy был просто примером. Вопрос был больше о том, как вы складываете вещи вместе. Если мне нужно конкретно сказать «двигаться на x = 5 и y = 6 за 5 секунд», «двигаться на x = 10 y = 2 за 10 секунд», то в то же время я так поступил бы?
Липкий

Что ты имеешь в виду под "составленным вместе"? Как добавить скорости? Так что, если вы усугубите move x by 10 in 2 secondsи move x by -10 in 2 secondsсущность будет стоять на месте?
Том Даллинг

Ответы:


6

Для вашего сценария мы обычно добавляем три компонента к игровому объекту:

  1. TransformComponent (положение, ориентация, масштаб)
  2. VelocityComponent (скорость, направление)
  3. ControllerComponent

Когда игровые объекты нуждаются в некотором типе функций ИИ, таких как перемещение по пути, как вы описали, мы назначаем AIController для его списка компонентов. Контроллеры AIC на самом деле не более чем оболочка, которая шагает по Поведенческому Дереву. Дерево поведения - это то, где мы проектируем реальную функциональность, которую мы хотим, чтобы игровой объект выполнял, например:

BehaviorTree* tree(new SequentialNode());
tree->addChild(new MoveToNode(x,y,z));
tree->addChild(new WaitNode(30));
tree->addChild(new MoveToNode(a,b,c));
tree->addChild(new WaitNode(30));
gameObject->addComponent(new AIController(tree));

Подсистема AI управляет контроллерами AIC, поэтому подсистема выбирает контроллер, который, в свою очередь, шагает по дереву поведения. MoveToNode () просматривает текущую позицию / ориентацию, вычисляет вектор направления и скорость, к которой вы хотите переместиться на основе аргументов конструктора, и устанавливает значения для компонента скорости. Система движения отвечает за чтение компонентов движения со значениями и применение физики, соответственно обновляя положение / ориентацию.

Приведенный выше код просто перемещает игровой объект из локации появления в x, y, z в мировом пространстве, затем ждет минимум 30 секунд, затем перемещает игровой объект в локации a, b, c и затем ждет еще 30 секунд. Как только ожидание закончено, последовательность действий завершена, поэтому она повторяется с самого начала.

Это позволяет вам легко определить, какие функциональные возможности AI вам нужны, и все это содержится в подсистеме AI с минимальным воздействием на вашу подсистему Entity. Это также позволяет вам поддерживать список компонентов вашей системы сущностей без особой детализации.


1

Можно добавить контроллеры в свой дизайн. Объекты владеют данными для представления положения (в случае с моим двигателем у них есть данные, которые также запоминают предыдущие положения, поэтому я могу знать вектор скорости, а также, перемещаются ли они или телепортируются), но они ничего не знают о физике или AI. Контроллеры перемещают объекты, и вы можете иметь много контроллеров, влияющих на один и тот же объект, или один контроллер, влияющий на различные объекты.

Например: создайте базовый класс Controller с помощью метода run () или, если вам не нравится имя, вызовите think (), update () или tick (). Затем вы наследуете его и создаете MoveController, NPCController, PlayerInputController (для сущности игрока), PhysicController; Затем вы реализуете метод run (). Я бы поместил ваш MoveByComponent в MoveController, а не в Entity.

Эти контроллеры могут быть созданы каждым объектом, если они содержат данные, специфичные для объекта. Они могут быть уничтожены или сброшены для последующего использования. Также вы можете использовать контроллер для перемещения группы сущностей, например, в игре RTE, если вам нужно перемещать различные юниты как группу, если контроллер для каждого юнита может ухудшить производительность игры, тогда вы можете просто назначить все юниты в GroupController или LegionController и позволить ему перемещать единицы как часть организованной группы. В бою, если игра допускает поведение отдельных юнитов, и, вероятно, большинство игр делают это, вам придется переключиться на UnitController, но лучше делать это только тогда, когда это необходимо, чем с самого начала.

В моей развивающей игре у меня есть MoveController, который перемещает объекты по пути, один MoveController существует для каждого NPC и персонажа игрока. Иногда один создается для коробок или рок, которые игрок может толкнуть. PhysicController, только один экземпляр, который будет проверять позиции всех назначенных ему объектов, если какой-то объект сталкивается с другим назначенным объектом, вычисляется результирующая позиция обоих (на самом деле он делает больше, но вы понимаете). NPCController - это ИИ, один экземпляр на каждого NPC. Он проверяет ситуацию с NPC и решает, куда двигаться, а затем указывает путь к MoveController, который фактически перемещает NPC. Контроллеры имеют приоритет, поэтому я могу заранее определить их порядок, PhysicController выполняется последним.

Я выступаю за контроллеров, но это не единственный «правильный» вариант. Например, я помню интерфейс Entity в движке Cafu, который имеет метод think () в самом Entity, пользователь класса должен наследовать от Entity и реализовывать think (), я помню производный класс с именем CompanyBot (который поставляется с примером игра), которые выполняют некоторую проверку столкновений в этом методе, так как он называется «думаю», мы можем предположить, что AI-код, как ожидается, также будет там. В то время как движок NeoAxis (в прошлый раз я изучал его) разделял ИИ и физику от сущностей.

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


Это в основном ОО дизайн, который у нас уже есть. Компания, с производными (Персонаж, Монстр) и т. Д., Я возглавлял команду из нас, которая работала над этой игрой полный рабочий день почти 2 года, и с каждым, кто что-то меняет по своему желанию, это становится ужасно, ужасно Codebase - и начинает занимать много времени, чтобы получить новые функции. Идея Entity System, кажется, именно то, что я ищу, поэтому, хотя ваш ответ не совсем актуален, вы должны прочитать ссылки в верхней части вопроса самостоятельно, посмотреть, могут ли они помочь вам :)
Липкий

@ Стильная Я должен признать, что Node System plus Entity, созданная из компонентов, - это умный способ представления различных необходимых систем, чем мой предложенный подход к контроллерам, который похож на менее развитую версию. Тебе действительно не нужен мой ответ.
Hatoru Hansou

Не беспокойся. У ОО-пути есть свои преимущества, но все становится ужасно, быстро
Липкий
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.