Как избежать «Blob-Systems» в системе компонентов объекта?

10

В настоящее время я сталкиваюсь со следующей проблемой:

Я пытаюсь написать клон понг с помощью системы компонентов сущности (ECS). Я написал "рамки" все сам. Таким образом, существует класс, который управляет объектами со всеми компонентами. Тогда есть сами классы компонентов. И, наконец, есть мои системы, которые просто получают все объекты, которые имеют компоненты, в которых нуждается система.

Так, например, моя система перемещения ищет все объекты, которые имеют компонент положения и компонент движения. Компонент позиции просто удерживает позицию, а компонент движения - скорость.

Но настоящая проблема - моя система столкновений. Этот класс похож на логический шарик. У меня так много особых случаев в этом классе.

Например: мои весла могут сталкиваться с границами. Если это происходит, их скорость устанавливается на ноль. Мой мяч также может столкнуться с границами. Но в этом случае его скорость просто отражается от нормали границы, поэтому она отражается. Для этого я дал мячу дополнительный физический компонент, который просто говорит: «Эй, эта вещь не останавливается, она отражает». Так что на самом деле физический компонент не имеет реальных данных. Это пустой класс, который просто сообщает системе, отражается ли объект или останавливается.

Затем приходит следующее: я хочу визуализировать некоторые частицы, когда шар сталкивается с веслами или границами. Поэтому я думаю, что шар должен получить еще один компонент, который говорит системе столкновений создавать частицы при столкновении.
Тогда я хочу иметь бонусы, которые могут сталкиваться с веслами, но не с границами. Если это произойдет, бонусы должны исчезнуть. Поэтому мне понадобится гораздо больше кейсов и компонентов (чтобы сообщить системе, что некоторые объекты могут сталкиваться только с определенными, а не со всеми, даже если некоторые действительно могут сталкиваться, более того, система столкновений должна была применять бонусы к весла и тд и тд и тп).

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

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

Конечно, я должен создать системы, которые на самом деле отвечают за «постколлизию», поэтому система коллизий говорит только «Да, у нас коллизия в последнем кадре», а затем есть куча «постколлизионных» систем, которые все требуют разных (комбинаций) компонентов и затем меняют компоненты. Например, была бы система постколлизионного движения, которая останавливает вещи, которые должны остановиться, когда происходит столкновение. Затем физическая постколлизионная система, которая отражает вещи и т. Д.

Но мне это тоже не кажется правильным решением, потому что, например:

  1. Моей системе постколлизионного перемещения потребуются объекты, имеющие компонент положения, компонент движения и компонент столкновения. Тогда он установит скорость объекта на ноль.
  2. Физической системе после столкновения потребуются объекты, которые имеют компонент положения, компонент движения, компонент столкновения и компонент физики. Тогда это будет отражать вектор скорости.

Проблема очевидна: движению после столкновения нужны объекты, которые являются подмножеством объектов в физике системы после столкновения. Таким образом, две системы после столкновения будут работать с одними и теми же данными, в результате чего: хотя у объекта есть физический компонент, его скорость будет равна нулю после столкновения.

Как эти проблемы решаются в целом в системе компонентов объекта? Эти проблемы вообще обычные или я что-то делаю не так? Если да, что и как должно быть сделано вместо этого?

M0rgenstern
источник

Ответы:

11

Да, вы думаете, слишком сложно.

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

Обмен сообщениями поможет вам с некоторыми аспектами, такими как запуск частиц, бонусы и так далее. Например, у вас может быть объект мира, который подписывается на события частиц и создает частицы в позиции, описанной в событии.

Фильтры вам очень помогут при столкновениях. Фильтры могут определять, сталкивается ли объект с другим, и как он будет реагировать. Вы добавляете некоторые атрибуты в свой физический компонент, который определяет, к какому типу физических тел это относится, с какими другими типами физических тел он сталкивается и каков должен быть ответ. Например, объект физики шара сталкивается с объектом физики весла и отвечает отражением и частицами.

Наконец, не будьте так строги в своей реализации. Если вы можете найти способ заставить его работать, но на самом деле это не система EC, сделайте это. Как и в моем примере выше, частицы не должны управляться системой или частью системы EC вообще. Более важно закончить игру, чем строго следовать методу, который уже довольно плохо определен.

MichaelHouse
источник
Большое спасибо. Я хотел создать игру, используя ECS, просто чтобы посмотреть, как она масштабируется и действительно ли она хороша в использовании, как я читал в статьях и руководствах. Моя проблема заключалась в том, что я подумал: «У меня сейчас ECS, и этим все должно управляться». Поэтому я также планировал написать систему частиц в связи с ECS. Кроме того, я читал в некоторых статьях, что каждый компонент должен иметь только некоторые базовые данные и ничего более. Это часто моя проблема ... Я думаю, что слишком сложно.
Mrrgenstern
Я хотел создать игру, используя ECS, просто чтобы посмотреть, как она масштабируется и действительно ли она хороша в использовании, как я читал в статьях и руководствах . Если это ваша цель, я рекомендую вам взглянуть на существующие системы компонентов / сущностей, а не создавать свои собственные. Загрузите Unity3D, который, вероятно, «настолько чист, насколько это возможно» и поиграйте там. Намного быстрее понимание, ИМХО.
Ими
3
@lmi: Unity не является системой компонентов Entity, хотя она основана на компонентах. У ECS есть более строгие правила ( никогда не думайте о шаблоне как о правилах), чем просто наличие и использование компонентов игровых объектов. Из-за серии статей ECS пользуется популярностью у некоторых сегментов разработчиков игр, поэтому есть много вопросов о ECS, а не о компонентном дизайне в целом.
Шон Мидлдич
12

Вы слишком усложняете вещи. Я бы сказал, что даже использование компонентного дизайна для такой простой игры просто излишне. Делайте то, что делает вашу игру быстрой и легкой в ​​разработке. Компоненты помогают с итерацией в больших проектах с огромным разнообразием поведений и конфигураций игровых объектов, но их польза от такой простой, четко определенной игры более сомнительна. В прошлом году я говорил об этом: вы можете создавать забавные маленькие игры за несколько часов, если сосредоточитесь на создании игры вместо того, чтобы придерживаться архитектуры . Наследование нарушается, когда у вас есть 100 или даже 20 различных типов объектов, но оно прекрасно работает, если у вас есть только несколько таких объектов.

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

Во-первых, не делайте ваши компоненты такими маленькими. Нет причин иметь мелкозернистые компоненты, такие как «движение». В вашей игре нет общего движения. У вас есть весла, движение которых тесно связано с вводом или ИИ (и на самом деле вы не используете скорость, ускорение, восстановление и т. Д.), И у вас есть мяч, у которого есть четко определенный алгоритм движения. Просто имейте компонент PaddleController и компонент BouncingBall или что-то в этом роде. Если / когда вы получаете более сложную игру, вы можете беспокоиться о наличии более общего компонента PhysicsBody (который в «реальных» движках - это просто связь между игровым объектом и любым внутренним объектом API, используемым Havok / PhysX / Bullet /). Box2D / и т. Д.), Который обрабатывает самые разные ситуации.

Даже компонент «позиция» сомнителен, хотя, конечно, не редкость. Физические движки обычно имеют свое внутреннее представление о том, где находится объект, графика может иметь интерполированное представление, а ИИ может иметь еще одно представление тех же данных в другом состоянии. Может быть полезным просто дать каждой системе возможность управлять собственным представлением о преобразовании в ее собственных компонентах, а затем обеспечить бесперебойную связь между системой. Смотрите сообщение в блоге BitSquid о потоках событий .

Для пользовательских физических движков помните, что вам разрешено иметь данные о ваших компонентах. Возможно, у общего компонента физики понга есть данные, указывающие, по каким осям он может двигаться (скажем, vec2(0,1)как множитель для лопастей, которые могут двигаться только по оси Y, и vec2(1,1)для шара, указывающего, что он может двигаться), флаг или поплавок, указывающий на бодрость ( мяч, как правило, на 1.0и весла на0.0), характеристики ускорения, скорость и т. д. Попытка разделить это на миллионы различных микрокомпонентов для каждого фрагмента данных с высокой степенью взаимосвязи противоречит тому, что изначально предполагалось сделать ECS. Храните вещи, которые используются вместе, в одном и том же компоненте, где это возможно, и разделяйте их только тогда, когда существует большая разница в том, как каждый игровой объект использует эти данные. Есть аргумент в пользу того, что для Понга физика между мячом и веслами достаточно различна, чтобы быть отдельными компонентами, но для более крупной игры нет особой причины пытаться сделать 20 компонентов, чтобы делать то, что отлично работает в 1-3.

Помните, что если / когда ваша версия ECS будет мешать, делайте то, что вам нужно, чтобы реально сделать свою игру, и забудьте о неуклонном следовании шаблону / архитектуре дизайна.

Шон Миддледич
источник
1
Большое спасибо! Я знаю, что ECS не очень хорошо масштабируется для такой маленькой игры, как понг. Но я использовал это только для того, чтобы увидеть, как такая вещь на самом деле реализована и как она работает. Я сделал компоненты настолько маленькими, потому что это было то, что я читал в основном в некоторых статьях. Иметь много компонентов, и каждый компонент содержит только элементарные данные. Итак, правильно ли я вас понимаю, что вы предлагаете использовать сочетание наследования и ECS? Как вы говорите, «шар и весла достаточно разные, чтобы быть отдельными компонентами». Так, например, я даю им оба компонента Движение / Положение (возможно, как один компонент) и
M0rgenstern
1
Что бы ни работало. Сосредоточиться на создании игры. Я бы буквально просто назвал компонент, Ballкоторый содержит всю логику для мяча, как движение, подпрыгивание и т. Д., И Paddleкомпонент, который принимает входные данные, но это я. Все, что имеет для вас наибольшее значение и мешает вам сделать игру, - это «правильный путь».
Шон Мидлдич
3
Я бы буквально просто имел компонент под названием Ball, который содержит всю логику для мяча, такую ​​как движение, подпрыгивание и т. Д., И компонент Paddle, который принимает данные, но это я. И поэтому у каждого программиста есть одно мнение о том, «что такое система компонентов». Я рекомендую НЕ делать это в соответствии с этим предложением, за исключением того, что вы полностью мыслите в классических системах Entity и вынуждены использовать систему компонентов, но не хотите смотреть, каковы различия на самом деле.
Ими
2
@lmi: поработав над несколькими крупными играми / движками с компонентами и увидев из первых рук, почему мы используем компоненты, нет, слишком гранулированные компоненты - это просто больше проблем, чем они того стоят. Компоненты не волшебная пуля; они являются одним из многих инструментов в наборе инструментов разработчика игр. Используйте их так, чтобы они помогли, а не таким образом, чтобы они просто добавляли больше умственных и временных затрат системе. Если единственной вещью, которая имеет физику шара, является шар, то нет никакого преимущества в отделении его от других свойств шара. Если и когда это изменится, разделите это тогда и только тогда.
Шон Мидлдич
1
Я согласен с принципом прагматичности и недопущения того, чтобы какой-то конкретный шаблон встал на их пути. НО, если ECS не в состоянии справиться с этой тривиальной игрой без отклонений, есть надежда на большую игру. Я тоже пытаюсь научиться эффективно использовать ECS, но я стараюсь максимально приблизиться к философии ECS, в противном случае, как только я начну делать исключения и особые случаи, я знаю, что получу неразрешимый беспорядок.
Кен
-2

На мой взгляд *), ваша самая большая проблема с компонентами заключается в следующем: компоненты не здесь, чтобы сказать кому-либо еще, что делать. Компоненты здесь, чтобы делать вещи. У вас нет компонента, который бы просто удерживал память о чем-то, а затем заставлял другие компоненты работать с этим. Вам нужны компоненты, которые ДОПУСКАЮТСЯ с данными, которые они получили.

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

  • Вы действительно хотите инвертировать зависимость: другой компонент должен прослушивать события / сообщения / широковещательные рассылки / hooks / howeveryounamethem для выполнения их логики в ответ на ваш текущий компонент. Текущий компонент даже не должен знать, что существует «другой» компонент. Чаще всего это происходит, если вы вызываете разные компоненты (даже в разных блоках else / case) с функциональностью, которая на самом деле не связана с вашим текущим методом. Подумайте обо всем этом Invalidate()или SetDirty()призывы к другим компонентам.
  • У вас может быть слишком много компонентов. Если два компонента просто не могут жить друг без друга и постоянно нужно извлекать данные и вызывать методы друг друга, то просто объедините их. Очевидно, что предоставляемые ими функции настолько запутаны, что на самом деле это только одна вещь.

Кстати, это относится ко всем видам систем, не только к системам Entity / Component, но и к классическому наследованию с простыми «GameObject» или даже библиотечными функциями.

*) На самом деле только мой . Мнения сильно различаются по поводу Whats Da Real Component Systemz (TM)

Imi
источник