- При установке в Unity через package manager или manifest.json теперь необходимо указывать дополнительно ?path=Scellecs.Morpeh. Ссылка на установку обновлена в
README.md
. - Максимальное количество активных
World
теперь ограничено до 256. Если у вас более 256 миров одновременно, постарайтесь объеденить что-то в один мир. Entity
теперь является структурой вместо класса и больше не имеет модификатора partial.default(Entity)
зарезервирована как невалидная сущность. Если у вас есть внешние плагины или код, использующий уже несуществующий функционал, возможно, потребуется их обновить. Некоторые данные (например, для плагинов, расширений и т.д.) всё ещё могут быть доступны через internal часть (такие какEntityData
вWorld
или классArchetype
). ПулингEntity
также больше не имеет смысла.- Поскольку
Entity
теперь структура и может использоваться в jobs,EntityId
иWorld.TryGetEntity
были удалены - нативное API теперь напрямую используетEntity
. - Методы
EntityExtensions
(Entity.Add<T>()
и т.д.) помечены как устаревшие из-за возможного удаления в будущих версиях Morpeh. Они будут доступны в текущей версии Morpeh (2024), но могут быть удалены в релизе Morpeh 2025. Рекомендуется использоватьStash
API, которое гарантированно останется и работает быстрее. Installer
,UpdateSystem
,FixedSystem
и другие системы на основе ScriptableObject теперь помечены как устаревшие из-за возможного удаления в будущих версиях Morpeh. Они доступны в текущей версии Morpeh (2024), но могут быть удалены в релизе Morpeh 2025. Рекомендуется использовать APISystemGroup
+ISystem
(IFixedSystem
и т.д.) для более легкой миграции в будущем.- Функционал для изменения начального размера
Stash<T>
теперь является частьюComponentId
. ИспользуйтеComponentId<T>.StashSize
перед первым вызовомWorld.GetStash<T>()
(включая API EntityExtensions и различные провайдеры / внешний код). ComponentId
иExtendedComponentId
теперь разделены. С целью уменьшения размера метаданных IL2CPP.ExtendedComponentId
теперь вырезается из не-UnityEditor сборок, если не указанMORPEH_GENERATE_ALL_EXTENDED_IDS
.ExtendedComponentId
может потребоваться для кода на основе рефлексии, где интерфейсаIStash
недостаточно.- Удален
UniversalProvider
. Рекомендуется использоватьMonoProvider
.UniversalProvider
может вернуться в форме сгенерированного класса с компонентами, в будущих версиях (т.е. "MonoProvider
но с несколькими компонентами"). - Удален
BitMap<T>
. При необходимости используйтеIntHashMap<T>
или перенеситеBitMap<T>
из Morpeh 2023.1 в свой проект. - Удален
UnmanagedList<T>
. Поскольку он и так был сломан, это не повлияет на существующие проекты. - Удален
UnmanagedArray<T>
. Поскольку он и так был сломан, это это не повлияет на существующие проекты. - Удален
Stash<T>.Empty()
. Использовалось для внутренних целей и не должно повлиять на проекты. Если вы где-то это использовали, поменяйте наdefault(T)
для того же эффекта. FastList<T>
и несколько других коллекций были исправлены для большей надежности и меньшей подверженности ошибкам. Это может повлиять на проекты, которые полагались на предыдущее поведение этих коллекций. Пожалуйста, адаптируйте использование к переименованным методам или новым перегрузкам. Имейте в виду, что HashMaps всё ещё не работают с отрицательными значениями в качестве ключей внутри вызововforeach
.bool Stash<T>.Add(Entity entity, in T value)
теперь является методомvoid
и выбрасывает исключение, если у сущности уже есть компонент. Это решение было принято из-за множества проектов, использующихAdd
и игнорирующих возвращаемое значение, что приводило к очень сложно обнаруживаемым ошибкам.- Все методы
Stash<T>
теперь всегда выбрасывают исключение, если сущность невалидна или операция не имеет смысла (например,Get
, если у сущности нет такого компонента), как в Debug, так и в Release режимах. Это может увеличить количество исключений в вашем проекте вместо их тихого игнорирования, как было раньше. Эти исключения должны быть обработаны и исправлены в коде проекта.
- Ознакомьтесь с Changelog для полного списка изменений.
Мы оцениваем возможность активного использования сорс генераторов в будущих версиях Morpeh, потенциально даже в релизе 2025 года. Это может наложить больше ограничений на то, что мы сможем или не сможем поддерживать.
Одним из вероятных изменений является возможное введение tag стешей (нон-дженерик) для компонентов-тегов, что уменьшило бы накладные расходы IL2CPP, использование памяти и повысило бы общую производительность. Мы хотим сделать это независимым от пользователя, чтобы пользователю не нужно было беспокоиться о конкретной реализации стеша, если это возможно. Из-за этого, возможно, стоит избегать итерации по стешам с компонентами-тегами, так как эта операция может замедлиться из-за необходимости трейлинга нулей, если в качестве типа хранения будет выбран битсет. Это может быть или не быть битсетом (например, если мы используем хэшсет или что-то еще), но общая идея заключается в том, чтобы быть осторожным при итерации по большим стешам с тегами.
Одним из наиболее вероятных изменений является удаление API EntityExtensions
в пользу
Stash
API. Мы признаем, что EntityExtensions
- это очень удобное API, но оно имеет
большие накладные расходы (как CPU, так и объем метаданных IL2CPP) и не является очень гибким,
особенно в контексте реализации стешей для компонентов-тегов, описанных выше.
Мы уже продолжительное время используем в наших проектах совершенно отдельный раннер для систем,
и он хорошо работает, позволяя нам избегать виртуальных вызовов для методов обновления систем,
улучшая общую производительность за счет снижения затрат на неактивные системы (системы, которые не имеют сущностей для обработки, но метод обновления всё равно вызывается).
Это может привести к полному удалению систем на основе ScriptableObject в пользу сгенерированных систем, а также сгенерированных "фичей",
которые заменят SystemGroup
. Для более легкой миграции в будущем мы рекомендуем
придерживаться чистых C# систем, реализующих интерфейс ISystem
, вместо
систем на основе ScriptableObject.
Провайдеры (EntityProvider
/MonoProvider
) также могут быть изменены в
будущих версиях. Мы рассматриваем возможность объединения их в один
сгенерированный класс, который позволил бы определять сразу несколько компонентов в одном
провайдере. Это также позволило бы нам создать более прозрачный пайплайн удаления сущностей, так как в настоящее время EntityProvider
на самом деле
не удаляет сущности из мира, а просто удаляет с нее свои компоненты.
Это иногда приводит к путанице и неожиданному поведению, когда у сущности есть компоненты, установленные извне провайдеров,
потенциально приводя к утечке неиспользуемых сущностей.
Все описанные выше изменения определенно повлияют на внешние плагины, расширения и другой код, который полагается на внутренности Morpeh или даже некоторые публичные API.
Обратите внимание, что это только планы, и они могут быть или не быть реализованы в будущем. Список также может быть неполным и может не охватывать все планируемые изменения.
- Инициализацию
Filter
необходимо заканчивать методомBuild()
, напримерWorld.Filter.With<Component>().Build()
. - Удален
ComponentProvider
, если вы им пользовались, то можно скопировать его из старых версий или написать свой аналог.
- Как альтернатива Odin Inspector пришел Tri Inspector. Теперь у фреймворка нет платных зависимостей. Вы можете использовать оба варианта на выбор.
- Добавлены аспекты. Это вспомогательные структуры, которые помогают делать срез из набора компонентов на сущностях. Подробнее в ридми.
- Теперь можно полностью очистить стеш от компонентов вызвав
stash.RemoveAll()
. Удобно когда вы делаете OneFrame Components и уверены, что в какой-то момент никаких компонентов определенного типа не должно существовать в мире. - Для провайдеров добавлены методы деинициализации по аналогии с инициализацией.
World.JobHandle
позволяет связывать джобы в рамках однойSystemsGroup
. Подробнее в ридми.- Добавлены метрики для профайлера, которые позволяют следить за количеством сущностей, количеством архетипов и прочим. Подробнее в ридми.
- Добавлен флаг и метод для проверки, что мир уже удален и он в невалидном состоянии.
World.IsDisposed
иWorld.IsNullOrDisposed()
соответственно. - Добавлен дефайн
MORPEH_DISABLE_SET_ICONS
, чтобы отключать назначение иконок в редакторе у наследников провайдеров, систем и прочего. - Теперь метод
World.Commit()
проверяет, что не вызван внутри итерации по фильтру, потому что иначе это приведет к изменению фильтра. - Добавлен флаг
World.DoNotDisableSystemOnException
который позволяет не отключать системы, когда они выкидывают исключения в режиме отладки. На релизную версию никак не влияет. - Добавлен метод
Filter.IsNotEmpty()
.
Вы можете продолжать использовать Odin Inspector или перейти на Tri Inspector.
Для этого вам необходимо добавить Tri Inspector по Git URL.
Удалить Odin, и удалить Odin Inspector дефайны из Player Settings.
- Минимальная версия Unity поднята до 2020.3.* LTS
- Неймспейсы изменены с
Morpeh
наScellecs.Morpeh
,Scellecs.Morpeh.Systems
,Scellecs.Morpeh.Providers
. - Глобалы выделены в отдельный пакет по ссылке https://github.com/scellecs/morpeh.globals.
- Метод
World.UpdateFilters()
переименован вWorld.Commit()
. - Класс
ComponentsCache<>
переименован вStash<>
. Все методы для стешей утратили приставкуComponent
, теперь простоAdd, Get, Set, Has, Remove
. - Фильтры валидируют, что в них нет повторяющих типов. Например на
Filter.With<A>().With<A>()
будет выведена ошибка. - Из систем удалено проперти
Filter
, вместо этого нужно использоватьWorld.Filter
.
- Добавлены
ICleanupSystem
подходящие для логики отчистки. По умолчанию вызываются самыми последними в LateUpdate. - Переработан механизм отчистки компонентов. Теперь компонент должен имплементировать
IDisposable
, и необходимо единожды вызвать у стеша методAsDisposable
, чтобы отчистка происходила. Например самый короткий вариантWorld.GetStash<T>().AsDisposable()
. - У
World
добавлен методGetReflectionStash
, чтобы получать стеш не через дженерик аргумент, а поSystem.Type
. - Добавлен дефайн
MORPEH_THREAD_SAFETY
, который заставляет ядро валидировать, что все вызовы идут из того же потока в котором мир был создан. Привязку к треду можно изменить через методыWorld.GetThreadId(), World.SetThreadId()
. - Добавлено API для плагинов. Для использования нужно имплементировать
IWorldPlugin
.
- Асмдеф и ссылки изменены с
XCrew.Morpeh
наScellecs.Morpeh
. Неймспейсы те же, что и были. - Все глобалы утратили метод
NextFrame
. Вместо него теперь необходимо использовать методPublish
, который отправляет событие не в этот кадр, а в следующий как ранее делалNextFrame
. Отправить событие в текущем кадре теперь невозможно, оно всегда отложенное. Это изменение связано с тем, что на всех проектах использовалась связка Publish + NextFrame, либо только NextFrame. Entity.ID
теперь возвращает неint
, а структуру типаEntityID
в которой содержаться поляid
иgen
. Это необходимое изменение для работы с Jobs и Burst. Так же добавлен методWorld.TryGetEntity(EntityId entityId, out Entity entity)
, который позволяет проверить наличие сущности без прямой ссылки на нее.Filter.Length
удален полностью. Его заменила связкаFilter.GetLengthSlow()
иFilter.IsEmpty()
. Это изменение связано с тем, что обновление кешированного значения длины для каждого фильтра давало большую нагрузку, а учитывая, что большинству фильтров не требовалось проверка на длину, то это была пустая нагрузка. Важный момент, что длина чаще всего использовалась для проверки на пустоту фильтра. Теперь получение длины дорогая операция, но проверка на пустоту такая же быстрая как и раньше. Это позволило сильно ускорить проекты с большим количеством фильтров.- Кеши компонентов теперь чистят данные после вызова
entity.RemoveComponent()
и читать данные по ref из компонента после его удаления теперь нельзя. - Итерирование по
Filter
теперь не гарантирует очередность. Если раньше ваша логика в проекте могла зависеть от того в каком порядке сущности попадают и удаляются из фильтра, то теперь необходимо от этого избавится. - Удален
ComponentsBag
. На его замену пришел полный публичный доступ к кешам компонентовComponentsCache
.
- Добавлены новые интерфейсы для компонентов
IValidatable
,IValidatableWithGameObject
. Позволяет вызывать стандартный юнитевский методOnValidate
на компонентах, чтобы, например, проинициализровать поля в редакторе. Работает только для компонентов, добавленных через MonoProvider. - Добавлено нативное апи для работы с Job и Burst. Подробно о его работе можно прочитать в ридми. Теперь есть методы
AsNative()
для:- Archetype (NativeArchetype)
- ComponentsCache (NativeCache)
- FastList (NativeFastList)
- IntFastList (NativeIntFastList)
- Filter (NativeFilter)
- IntHashMap (NativeIntHashMap)
- World (NativeWorld)
- Добавлен интерфейс
IMorpehLogger
и статический классMLogger
. Они позволяют переопределить логирование для Morpeh. Console.WriteLine для окружений кроме Unity по дефолту. - Добавлен дефайн
MORPEH_PROFILING
. Добавление его в Player Settings позволяет профилировать нагрузку от систем без Deep Profile. - Теперь
Entity.Dispose()
стал публичным методом. Это позволяет уничтожить энтити без прямого доступа к миру. - Отображение нескольких миров в World Browser