Обнаружение столкновений и реагирование в Entity System

12

Больше веселья с ES ...

В настоящее время у меня есть несколько систем:

  • Renderer (атрибут Renderable, атрибут Transform)
  • Движение (атрибут «Подвижный», атрибут «Преобразование», атрибут «Renderable» [для ограничительных рамок и т. Д.])
  • Input (атрибут InputReceiver)
  • и т.п.

Я добавляю обнаружение столкновений. Моей первой мыслью было добавить новую систему, которая выполняет столкновение. Это имеет смысл для меня , чтобы держать это изолировано от Motionсистемы , так как не все, что движение или анимированы обязательно участвуют в обнаружении столкновения - камеры, туман и т.д. - но, кажется, Collisionи Motionявляются взаимозависимыми.

Когда Motionперемещается объект, трансформация должна быть подтверждена с помощью Collision, а движение либо отменено, либо скорректировано (подпрыгивание, остановка у стены и т. Д.).

Альтернативой может быть создание атрибута Collidable, который поддерживает ссылку на объект столкновения - kd-tree, octree и т. Д., Который совместно используется объектами, которые могут сталкиваться друг с другом. Затем Motionсистема проверит этот атрибут и использует его для проверки или корректировки движения.

С точки зрения кода это приемлемое решение. Однако, с точки зрения архитектуры ECS, кажется, что она проталкивает логику в Motionсистему, которая не применяется ко всем объектам, которые имеют Movableатрибут.

Я мог бы также хранить вектор движения в Movableатрибуте, и есть Colliderсистема регулировки по Transformмере необходимости, но это будет включать в себя дублирование функциональных возможностей между Motionи Collider, или обратного вызова от Colliderк Motionс некоторыми данными о местоположении столкновений и поверхностных данных для отскока / отражения, и т.д. ,

Это может подпадать под заголовок «взломать особый случай», но я хотел бы получить некоторую информацию от тех, кто обрабатывал это раньше, без создания тонны краевого кода случая.

Вопрос Какой хороший способ избежать тесной связи между системами движения и столкновения, когда кажется, что они требуют знания друг друга?

3Dave
источник
1
В чем вопрос?
Jcora
@Bane, что является хорошим местом, чтобы поместить логику обнаружения столкновений, сохраняя как можно более раздельное столкновение + движение и сводя к минимуму взаимозависимости между системами. Мой пост был немного
странным
1
Отлично, теперь поставьте это в своем вопросе, смело . :)
Jcora

Ответы:

7

Вы переосмысливаете это. В моем движке, который также использует систему компонентов, каждый GameObjectможет иметь указатель на ModuleCollision.

Что происходит при обновлении игры:

  • Сцена обновляет все объекты, которые она содержит. Он вызывает Updateфункцию для каждого GameObject.
  • Внутри Updateфункции каждый обновляет GameObject только свою скорость и направление, а не свою позицию.
  • GameObjectзагружает свою текущую позицию, скорость и направление на нее ModuleCollision, если таковая имеется.
  • Сцена делает проверку столкновения на ModuleCollisionоснове.
  • Сцена вызывает UpdatePostфункцию на каждом GameObject. Если у объекта есть модуль столкновения, он выбирает обновленную позицию, скорость и направление из модуля столкновения. Положение обновляется со скоростью и направлением.
  • GameObjectСоздает конечную матрицу 3х3 из своего положения и курса.

Да, есть некоторое дублирование состояния, но это нормально. Обработка столкновений на a ModuleCollision- лучший способ сделать это, потому что в противном случае вам придется проверять каждый из них, GameObjectчтобы увидеть, есть ли у него ModuleCollisionдескриптор.

knight666
источник
2
Таким образом, вместо того, чтобы беспокоиться о положении возврата в случае столкновения, вы разделяете скорость / ускорение от перевода, изменяя те, которые основаны на любых обнаруженных столкновениях, и затем эти изменения распространяются во втором специализированном обновлении в том же кадре? Кажется, довольно чисто. Благодарю.
3Dave
3

Я бы сделал это так ...

Есть три системы:

  1. Система движения
  2. Система ускорения
  3. Система столкновений

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

Например, вы можете рассчитать угол между столкновениями, используя atan2 , а затем использовать его, чтобы применить правильные силы / скорости тел.

Если необходимо, имейте также широковещательные сообщения системы обнаружения столкновений.

jcora
источник