Компонентна система сутності - Як реалізувати перетворення об'єкта?


11

Розробляючи систему-компонент сутності для мого двигуна, я натрапив на невеликий корч у способі зберігання та пошуку певного типу компонента.

По-перше, дозвольте мені встановити трохи термінології, яку я буду використовувати в цьому питанні:

  • Я називаю " Компонент " структурою даних, яка зберігає відповідні дані для певної системи.
  • Я називаю " Система " сукупністю методів та структур даних, яка використовує компоненти для оновлення ігрового стану / інтерфейсу з користувачем.
  • " Сутність " - це в основному лише ідентифікатор, який використовується для отримання конкретних компонентів та зміни їх даних в логіці гри.

Кожна система володіє масивом (накреслений по ID) свого типу компонентів (наприклад, Physics-> PhysicsComponent, AI-> AIComponent, Rendering-> RenderingComponent), щоб вона могла ефективно повторювати дані.

Однак не всі компоненти спеціально належать системі. Наприклад, компонент Transform зберігає положення, обертання та масштаб об'єкта. Це одна з найважливіших частин суб'єкта (Єдність робить його обов'язковим навіть), оскільки його використовують багато систем, наприклад фізика, AI, візуалізація тощо.

Це в значній мірі проблема, з якою я стикаюся. Оскільки Transform використовується в багатьох інших системах, то як я можу взятись із пошуком однієї для використання для кожного компонента? Я бачу одне з можливих рішень - зробити кожен компонент зберігати свій ідентифікатор особи. Буде легко отримати будь-який подібний компонент, але це було б не настільки ефективно, і це також би суперечило концепції Компонента як ізольованого та незалежного набору даних, що не знає жодного іншого.

Чи є правильний спосіб вирішити цю проблему? Чи повинен Трансформація навіть бути складовою?


3
+1 для "По-перше, дозвольте мені встановити трохи термінології, яку я буду використовувати в цьому питанні:"
Vaillancourt

Я хотів би бачити цей тип питань більше на цьому сайті. +1
S. Tarık Çetin

Просто зберігайте всі компоненти як глобальні змінні
Miles Rout

Відповіді:


2

Це досить широке запитання, відповідь на яке сильно залежить від вашої архітектури. Однак я спробую дати вам загальну відповідь.

Ваші фізичні та візуалізаційні системи, безумовно, потребують перетворення, однак система AI не буде. Тому має сенс інкапсулювати перетворення у власний клас компонентів. Усі такі зацікавлені системи використовували б однакові дані, тому для об'єкта має сенс мати вказівник на об'єкт трансформації або ідентифікатор для об'єкта трансформації, який зберігається в іншому місці.

Якщо ви виберете останнє рішення, то кожна система, яка зацікавлена ​​в перетворенні, потребуватиме доступу туди, де зберігається об'єкт перетворення.

Якщо ви обираєте першу, тоді потрібно зробити кожну систему, щоб отримати доступ до самої сутності та подати запит на перетворення.

У першому випадку проблемою стає те, як надати доступ до сховища для перетворень для кожної системи, не порушуючи правил OOP, якщо вам важливі такі речі.

Останній випадок не має таких проблем, але вимагає змінити ваш об'єктний дизайн об'єкта, щоб зберігати покажчики на об’єкти, а не ідентифікатори компонентних об'єктів.

Моє особисте уподобання - створити клас особи для зберігання покажчиків на складові об'єкти, оскільки це спрощує багато проблем із дизайном. Таким чином, кожна система, яка потребує перетворення, може вимагати її від сутності та ігнорувати її, якщо вона цього не робить. Однак це несе обчислювальні витрати, притаманні покажчикам, тому що витрати на кеш пропускають.

Перегляньте цей Огляд ECS для отримання додаткової інформації про це.

Зрештою, вирішувати, що для вас важливіше: простота розробки чи продуктивності.

Нарешті, я зазначив би, що ваше запитання є прекрасним прикладом дизайнерських питань, про які думають прихильники ECS, і немає остаточного рішення срібної кулі.


Дякуємо за ваші пропозиції. Однак у мене виникає питання: чому система AI не потребує позиції об'єкта?
CRefice

Ви плутаєте положення (вектор з 3 плавців) з перекладом (матриця перетворення, побудована з вектора позиції). Матриця перетворення побудована з перетворень, обертання та масштабних перетворень. Це набагато більше інформації, ніж знадобиться системі AI, хоча ви, безумовно, можете витягти з неї вектор позиції. Хоча я особисто розділив положення, орієнтацію та розміри на свій власний компонент і використав би їх для створення та оновлення Трансформації.
Ян Янг

@IanYoung Розмежування їх може принести більше шкоди, ніж користі, можливо, якщо ви вважаєте, що вам потрібні положення та орієнтація разом частіше, ніж ви займаєте положення чи орієнтацію окремо. У цьому випадку розміщення атрибутів даних про позицію та орієнтацію в одному компоненті може покращити продуктивність кешу.
Нарос

1
Я вважаю за краще поєднувати всі три, позицію, орієнтацію та масштаб в єдиний компонент, і у тих випадках, коли певному субсистему потрібна лише позиція чи орієнтація, я б закликав дублювати дані та синхронізувати їх у чітко визначених точках ігрового циклу. .
Нарос

@Naros так, це саме те, що я мав на увазі: Дві компоненти, перетворення та (в моїх рамках) просторових даних, що містить положення, швидкість, орієнтацію та кутову швидкість. Положення та орієнтація використовуються для побудови та оновлення Перетворення.
Ян Янг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.