Некоторые мысли о ECS

Часть 1: Unity ECS - кратко об ecs
Часть 2: Unity ECS - дизайн проекта
Часть 3: Unity ECS - операции с сущностями
Часть 4: Unity ECS - ECS и рабочие места

Эмпирическое объяснение

Как часто выглядит ComponentSystem:

Давайте сначала посмотрим на это:

Что такое группа?

Группа - это фильтр всех сущностей в активном мире, у которых есть компоненты Foo и Bar. Это как массив совпадающих сущностей со ссылками на все конкретные заданные компоненты. Итак, группа похожа на EntityArray, но со ссылками на компоненты, EntityArray сама по себе представляет собой просто массив сущностей (а сущность - это просто индекс). Группа построена с набором требуемых компонентов, вычитающих компонентов. Он также синхронизируется.

Почему у нас есть поле Длина? Разве Foos.Length не то же самое?

Да ты прав! Они такие же. Length - это длина EntityArray, а также длина Foos и Bars, потому что каждая сущность имеет компоненты Foo и Bar.

В этом случае это более очевидно

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

Как управлять индексацией? Магия инъекций.

Как управлять сроком службы систем?

Что ж, на самом деле это и не нужно! Об этом позаботится Unity. Системы отслеживают внедренные группы и будут отключены, если нет подходящих объектов, и будут включены, если они появятся. Но если вы действительно хотите, посмотрите вверх, см. OnStartRunning и OnStopRunning? Я упомянул ComponentSystemBase.Enabled = true, который, вероятно, именно то, что вы ищете. Это свойство, позволяющее активировать / отключать систему вручную.

Системы не обновляются в том порядке, в котором я хочу

Атрибуты удобства для спасения! Поскольку все системы обновляются в основном потоке, вам нужно подумать о порядке обновлений, есть несколько атрибутов, которые помогут вам в этом: [UpdateAfter (typeof (OtherSystem))] , [UpdateBefore (typeof (OtherSystem))], а также [UpdateInGroup (typeof (UpdateGroup))] , где UpdateGroup - пустой класс. Вы даже можете управлять обновлением до / после этапов Unity с помощью typeof (UnityEngine.Experimental.PlayerLoop.FixedUpdate) или других этапов в том же пространстве имен.

Как я могу получить доступ к нужной мне системе?

Вы можете просто ввести его так же просто, как [Inject] private YourSystem yourSystem;. Вы также можете использовать World.Active.GetExistingManager ‹YourSystem› () или, если вы не уверены, существует ли он, но должен, использовать World .Active.GetOrCreateManager ‹YourSystem› ()

Зачем использовать EntityArray в системе? Что я могу делать с этим индексом?

Поскольку системы чаще всего работают с компонентами, а не непосредственно с объектами, возникает вопрос: «Зачем мне вообще нужен этот индекс». Сказать «это просто и индексировать» не означает, что его вообще нельзя использовать. Это очень важное целое число. Если вы не пробовали реализовать ECS в Unity, вы, вероятно, не знаете, где это нужно. Он необходим среди прочего для функциональности EntityManager, который содержит EntityData и управляет добавлением / удалением (и многим другим) компонентов из данной сущности. Но на самом деле вы не хотите добавлять / удалять компоненты через EntityManager. Лучше сделать это после обновления, чтобы не разбить группу (вы получите ошибку при доступе к освобожденному собственному массиву), поэтому вы хотите использовать PostUpdateCommands (EntityCommandBuffer). Подробнее об этом в одной из фьючерсных частей статьи.

Мир против EntityManager

EntityManager - это не странный магический класс, это ScriptBehaviourManager, который «объединяет» сущности и их компоненты. В ECS много менеджеров. ComponentSystem также является ScriptBehaviourManager! Мир объединяет всех менеджеров в единое целое. В просторечии можно сказать, что он управляет менеджерами. Я знаю, в чем ваш вопрос - да, мы можем создавать несколько миров, звучит интересно, не так ли? Может быть, мы еще рассмотрим это в будущем.

ComponentData и SharedComponentData. Какая разница?

Разница тривиальна, ComponentData - это просто компонент, SharedComponentData, как говорится, компонент, совместно используемый разными объектами. Очень хорошее объяснение, которое вы можете прочитать в документации:

IComponentData подходит для данных, которые различаются между Сущностями, например для сохранения положения в мире. ISharedComponentData полезен, когда у многих сущностей есть что-то общее, например, в демонстрации boid мы создаем экземпляры многих сущностей из одного и того же префаба, и, таким образом, MeshInstanceRenderer между многими boid-сущностями точно такой же.

Таким образом, с теми же IComponentData (например, Position) изменения с Entity0 не изменят Position с Entity1, но с тем же SharedComponent (например, Renderer), если вы измените материал из Entity0, он изменит также материал из Entity1. Однако на самом деле вы не хотите сильно менять SharedComponents, на самом деле очень редко. Подробнее ЗДЕСЬ. Что ж, есть еще одно отличие - ComponentData должен быть непреобразуемым.

Идем дальше: Часть 2: Unity ECS - дизайн проекта

Оставьте отзыв в разделе комментариев, не волнуйтесь, я не возненавижу вас, если вы покажете мне какую-нибудь «аномалию» в моей статье. Если вам понравилась моя статья - ставьте лайк и подписывайтесь на меня. Это побудит меня написать больше статей. Увидимся.

Первоначально опубликовано на странице https://connect.unity.com/p/part-1-unity-ecs-briefly-about-ecs