Не знаю насколько в атомарном подходе остаётся жива инкапсуляция, мы же вроде данные и логику разделили, и добавили возможность получать переменные напрямую из объекта, что как-то с инкапсуляцией не вяжется. Логика данными тоже не владеет, мы данные прокидываем извне, и данными по факту владеет сам объект переменной, который их никак не защищает и про который могут знать разные куски логики.
Полиморфизм легко достигается в ECS через компоненты, ну либо в крайнем случае можно также использовать интерфейсы, если реализаций много. Конструкция объектБезТипа.Is("Хилка") ничем по факту от полиморфизма в ECS не отличается, кроме того, что ECS быстрее, типобезопаснее и поддерживает фильтры/группы/query.
Вкатывание в ECS сильно много времени не занимает. Включиться в работу и делать фичи можно с первых дней. Так зачем использовать неоптимальный, урезанный и не самый простой подход, когда есть зарекомендовавшая себя альтернатива?
Несмотря на опыт в пару лет всё равно часто думаю, а как "удобно" организовывать логику в ООП подходе. В ECS всё как правило просто и понятно, а в ООП либо Unity-way, который трудно поддерживать в долгую, либо бесконечное множество способов сделать что-то ещё в ООП стиле. И это пока один из вариантов лучших, что я видел. Выглядит достаточно просто, логика раздроблена, каши из множества монобехов нет, и параметры в инспекторе в рантайме покрутить можно, потому что ссылочная обёртка. Прям есть что перенять и запомнить для своих проектов) Больше спасибо за статью.
Я не согласен касательно MVC и разделения сущностей.
Объекты имеет смысл делить, даже если повторное использование не требуется. При разработке стоит проблема сложности логики, высокая сложность усложняет поддержку кода и повышает количество багов. Когда мы делим классы или методы на несколько маленьких (без фанатизма и с умом), то сложность снижается и код становится гибче.
Логика "меньше сущностей - лучше" выглядит как попытка свести всё к большим объектам по 500-1000 строк кода, хотя я думаю автор статьи и не имел это в виду, но чем больше проект, тем вероятнее такое будет происходить, если не делить код на сущности и не создавать между сущностями связи. Такие вещи как low coupling и high cohesion не просто так были придуманы, как и правила по количеству строк в классе/методе. Всё это напрямую связано со сложностью кода, поддержке, рефакторингу, расширению и т.д.
Если у меня большая игра, то мне так или иначе придётся делать логику на модель и визуализацию. Даже если и то и другое будет лежать в компонентах на монобехах. Когда люди делают монобех с логикой, а дальше извне подвязывают звук, анимации и эффекты, то это тот же самый принцип с разбиением, что и в MVC, и делать так желательно.
Ну и касательно создания абстракций над Unity и вынос модели в отвязанный от Unity код. Это тоже имеет смысл. Часто не хочется чтобы цикл жизни каких-то объектов был привязан к визуальным объектам на сцене. Если у меня есть режим игры, либо игровая валюта игрока и т.п., то мне абсолютно не нужен объект на сцене на такие вещи. Я хочу поставить какой-то главный объект на сцену, который внутри себя создаст то, что нужно будет для работы любой игровой сцены, либо меню.
Изучать новое и самообразовываться нужно во многих других профессиях. Не нужно прибедняться мол "надо же фреймворки учить, а это время, целых несколько недель или даже несколько месяцев". Скажи это врачам или кому-нибудь ещё, чья работа сложнее, требует более длительного и сложного обучения, а зарплата в несколько раз меньше. И я уже молчу про возможность устроиться программистом имея 9 классов + 1 год самообучения.
В ООП могут быть ошибки, когда у методов неправильный порядок вызова, но это проблема конкретного объекта, и решается она индивидуально в рамках конкретного объекта без большой боязни затронуть что-то ещё. Ты просто открываешь Player.Update() и меняешь вызовы методов местами, пока оно не станет работать правильно.
В ECS одна и та же система может работать для разных сущностей, и шанс сломать другие фичи выше.
Даже в рамках одной фичи в ECS могут возникнуть различные баги. Чтобы узнать порядок нужно лезть в место, где системы регистрируются, то есть быстренько прокликать откуда вызывается каждый метод или заглянуть в Update конкретного объекта не получится.
Лучшая статья по ECS что я видел. Из недостатков, сам натыкался и на порядок систем, и на слабую связность когда надо неудобно проверять наличие компонентов если сущность получена не из фильтра, и про неудобство в дебаге, но абсолютно нигде не видел, чтобы про это кто-то писал.
Все либо говорят про то, какой ECS быстрый, либо про абсолютное удобство без минусов, а здесь очень объективный и всесторонний обзор, от которого даже как-то спокойно на душе стало, что не я один на различные неудобные моменты натыкался.
Не знаю насколько в атомарном подходе остаётся жива инкапсуляция, мы же вроде данные и логику разделили, и добавили возможность получать переменные напрямую из объекта, что как-то с инкапсуляцией не вяжется. Логика данными тоже не владеет, мы данные прокидываем извне, и данными по факту владеет сам объект переменной, который их никак не защищает и про который могут знать разные куски логики.
Полиморфизм легко достигается в ECS через компоненты, ну либо в крайнем случае можно также использовать интерфейсы, если реализаций много.
Конструкция объектБезТипа.Is("Хилка") ничем по факту от полиморфизма в ECS не отличается, кроме того, что ECS быстрее, типобезопаснее и поддерживает фильтры/группы/query.
Вкатывание в ECS сильно много времени не занимает. Включиться в работу и делать фичи можно с первых дней.
Так зачем использовать неоптимальный, урезанный и не самый простой подход, когда есть зарекомендовавшая себя альтернатива?
Несмотря на опыт в пару лет всё равно часто думаю, а как "удобно" организовывать логику в ООП подходе.
В ECS всё как правило просто и понятно, а в ООП либо Unity-way, который трудно поддерживать в долгую, либо бесконечное множество способов сделать что-то ещё в ООП стиле. И это пока один из вариантов лучших, что я видел. Выглядит достаточно просто, логика раздроблена, каши из множества монобехов нет, и параметры в инспекторе в рантайме покрутить можно, потому что ссылочная обёртка.
Прям есть что перенять и запомнить для своих проектов)
Больше спасибо за статью.
А что плохого в статике для получения индекса типа (EcsComponentType<T>.TypeIndex)? Есть какая-то проблема?
Про ключевое слово "final" и "checked/unchecked exceptions". Подобное разве есть в C#? Это скорее вопросы для джавистов.
Я не согласен касательно MVC и разделения сущностей.
Объекты имеет смысл делить, даже если повторное использование не требуется. При разработке стоит проблема сложности логики, высокая сложность усложняет поддержку кода и повышает количество багов. Когда мы делим классы или методы на несколько маленьких (без фанатизма и с умом), то сложность снижается и код становится гибче.
Логика "меньше сущностей - лучше" выглядит как попытка свести всё к большим объектам по 500-1000 строк кода, хотя я думаю автор статьи и не имел это в виду, но чем больше проект, тем вероятнее такое будет происходить, если не делить код на сущности и не создавать между сущностями связи. Такие вещи как low coupling и high cohesion не просто так были придуманы, как и правила по количеству строк в классе/методе. Всё это напрямую связано со сложностью кода, поддержке, рефакторингу, расширению и т.д.
Если у меня большая игра, то мне так или иначе придётся делать логику на модель и визуализацию. Даже если и то и другое будет лежать в компонентах на монобехах. Когда люди делают монобех с логикой, а дальше извне подвязывают звук, анимации и эффекты, то это тот же самый принцип с разбиением, что и в MVC, и делать так желательно.
Ну и касательно создания абстракций над Unity и вынос модели в отвязанный от Unity код. Это тоже имеет смысл. Часто не хочется чтобы цикл жизни каких-то объектов был привязан к визуальным объектам на сцене. Если у меня есть режим игры, либо игровая валюта игрока и т.п., то мне абсолютно не нужен объект на сцене на такие вещи. Я хочу поставить какой-то главный объект на сцену, который внутри себя создаст то, что нужно будет для работы любой игровой сцены, либо меню.
Изучать новое и самообразовываться нужно во многих других профессиях. Не нужно прибедняться мол "надо же фреймворки учить, а это время, целых несколько недель или даже несколько месяцев". Скажи это врачам или кому-нибудь ещё, чья работа сложнее, требует более длительного и сложного обучения, а зарплата в несколько раз меньше. И я уже молчу про возможность устроиться программистом имея 9 классов + 1 год самообучения.
В ООП могут быть ошибки, когда у методов неправильный порядок вызова, но это проблема конкретного объекта, и решается она индивидуально в рамках конкретного объекта без большой боязни затронуть что-то ещё. Ты просто открываешь Player.Update() и меняешь вызовы методов местами, пока оно не станет работать правильно.
В ECS одна и та же система может работать для разных сущностей, и шанс сломать другие фичи выше.
Даже в рамках одной фичи в ECS могут возникнуть различные баги. Чтобы узнать порядок нужно лезть в место, где системы регистрируются, то есть быстренько прокликать откуда вызывается каждый метод или заглянуть в Update конкретного объекта не получится.
Лучшая статья по ECS что я видел. Из недостатков, сам натыкался и на порядок систем, и на слабую связность когда надо неудобно проверять наличие компонентов если сущность получена не из фильтра, и про неудобство в дебаге, но абсолютно нигде не видел, чтобы про это кто-то писал.
Все либо говорят про то, какой ECS быстрый, либо про абсолютное удобство без минусов, а здесь очень объективный и всесторонний обзор, от которого даже как-то спокойно на душе стало, что не я один на различные неудобные моменты натыкался.