Комментарии 31
transform уже давно кэшировать не надо . Ещё с Unity 5
Не знал. Спасибо за совет!
Там такой глубокий вьетнамский флешбек, что многие (и я) до сих пор кэшируют всё, что можно, чтобы лишний раз Unity не дёргать. Сегодня кэшируется, а в завтрашнем обновлении – нет. И то ли баг, то ли фича. То ли исправят, то ли нет. Увлекательная игра 😁
Если побенчмаркать, то кастомное кэширование всё равно немножечко, но всё же эффективнее. Хотя в Unity 6 может успели ещё докрутить этот момент.
Дошел до момента, про невозможность использования конструкторов. Это обычное дело при пулинге (переиспользовании) объектов в играх. Странно называть странностями то - что для игр обычная практика. Дальше не читал.
При AddComponent или добавлении компонента в редакторе никакой пуллинг не используется. При обычным пулинге в .NET(и в Unity с обычными C# классами) приложениях вам никто не запрещает использовать конструкторы. Все таки перед тем, как положить объект в пулл, его надо создать, и все здоровые люди делают это через конструкторы(явно или через DI).
Для пулла объекты скорее должны иметь некие Init
и Reset
, чем конструктор без конкретной пользы.
Безусловно. При большинстве кейсов использования пуллинга объектам нужны методы для переключения состояния при возвращении в пул и взятии из пула. Но конструкторы тут ни при чем. Концепция конструирования объектов в ООП никак не связана с пуллингом или его отсутствием. Отсутствие конструкторов для компонентов в Unity3d это сложный вопрос связанный с ограничениями архитектуры самого движка и сомнительными решениями в проектировании API, а не с тем, что разработчики привыкли использовать тот или иной паттерн. Это то, что я пытаюсь сказать.
Причина многих архитектурных решений в том что люди которые дизайнили Юнити на заре времен не понимали что такое .NET и C#, это был скриптовый движек в который прокинули кишки из С++. В итоге это непонимание никак не решалось более десяти лет, пока не появился IL2CPP и им пришлось "понять" как работает .NETчто бы воспроизвести его рантайм на С++. Но даже после этого мало что изменилось в дизайне их фич. Они всё еще воюют с .NET пытаясь делать "как в С++". И даже не в С++ в целом, а как в "их" варианте С++.
Ну уж я бы так не принижал архитекторов Unity=) Думаю в ООП они что-то да понимали, да и C# не со лба взяли скорее всего, а имея определенное представление о том, что это за язык. Ну тут даже правильнее будет сказать, что смотрели не на сам C#, а на Mono в те времена. Ну а получилось, что получилось. И получилось не так плохо. C# в Unity действительно пахнет плюсами больше, чем в .NET, преимущественно из-за более активного навязывания RAII-подобных конструкций. Но и в стандартной библиотеке C# IDisposable никто не отменял. Да и что уж там говорить... указатели, StructLayoutAttribute, маршалинг, Span... C# сам по себе не так уж далек от плюсов, если действительно остро встает вопрос о производительности. И даже в .NET мире можно найти код который будет в 1000 раз ближе к плюсам, чем среднестатистический код на Unity.
Кто-то ещё использует Юнити после обновления их лицензионного соглашения? Они же заставляют платить за каждое установленное приложение, даже если оно не принесло прибыли. Может быть мажорные студии ещё и согласятся с такими правилами, но обычному разработчику тупо не потянуть, особенно если игра популярная и установки исчисляются тысячами.
С самых первый версий юнити выбешивает полным игнором соглашений на c#. Ну вы если взяли ЯП под скрипты то хотя бы ознакомьтесь с существующими соглашениями в комьюнити, либами. А то transform - паблик переменная (чео?), магические соглашения на именах (прости госпади)... это апи, серьезно?
Есть такое=) Я бы, конечно, не драматизировал слишком сильно. Работать можно и даже часто удобно. Просто надо смириться, что C# для Unity это чуть-чуть не то же самое, что обычный C#. Не сильно. Просто надо знать о некоторых мисконсепшенах и подводных камнях. Я для этого и написал эту статью)
У меня раньше пригорало от этого. Но когда начал относится к программированию в Unity менее догматично и больше фокусироваться на том, как эффективнее и чище писать код именно с учетом того, что Unity не идеален, мне стало на много легче и приятнее работать с движком.
Юнити тем и хорош для начинающих, что можно написать transform.Translate а не заниматься бесполезной эквилибристикой с получением трансформа только потому что два деда 40 лет назад решили что нужно так и никак иначе обосновав это тем что код в таком случае верный и чистый а в любых других случаях неверный и нечистый.
Да, именно эту цель и преследовали разработчики Unity3d. Сделать минимальный порог входа в движок. По этой же причине в качестве скриптовых ЯП были выбраны C# и UnityScript(аналог JavaScript, который не прижился и ушел в небытие несколько лет назад), а не C++ на котором написан сам движок или Lua, который активно используется в геймдеве, но не так распространен на рынке IT.
Размышляя об этом я как раз таки вижу проблему UnityScript в том, что он был слишком уж далек от правил столетних дедов и не подходил для разработки даже небольших проектов(что уж говорить про серьезный энтерпрайз), так как предоставлял слишком много свободы для написания плохоподдрерживаемого кода. C# в свою очередь, с учетом того, что Unity Technologies действительно сделали его чуть ближе к скриптовым языкам с помощью приколов компиляции и очень свободного API попал в золотую середину. Писать на нем в Unity3d достаточно просто, чтобы решить большинство прикладных игровых задач без выстраивания какой-либо вменяемой архитектуры, которую можно и нужно будет поддерживать. При этом вся мощь построения архитектуры для больших и сложных масштабируемых систем тоже никуда не делась. Конечно пытаясь угодить противоречивым концепциям будут образовываться "швы" в архитектуре, но Unity Tech, как мне кажется, хорошо справились с задачей. Главное правильно определить какой тип проекта вы хотите делать. Микроприлагу на 1-2 разработчика, на которую забьете через год, или долгоиграющий проект на команду 100+ человек, или что-то по середине. От этого зависит какие правила взаимодействия с Unity API и поддержания качества кода выстраивать и нужны ли они вообще. Надеюсь не слишком душно ответил.
Статья очень удивила. В последнее время выходило очень мало интересных статей по Unity. Емкое и дельное представления о деталях использование языка в Unity. Новичкам самое то! И, одна помарка, transform кешировать не нужно, он уже кеширован за нас.
Спасибо за статью!
Спасибо! Да, про transform действительно не знал) Надо будет отредактировать
Хотел ещё написать насчет наследования.
Разве есть какая-то выгода наследования собственных классов от таких классов, как: Behaviour, Component? Их же не получится закрепить за определенным GameObject
Эх, а в параллельной вселенной кто-то написал статью, как Unity-разработчик, допустим, на ASP.NET решил пощупать)
А так-то статья интересная. За это спасибо автору.
методы Start и Update не оверрайдят никакие базовые методы, они не часть интерфейса, они даже не публичные. Тем не менее они вызываются third-party кодом. Я не встречал подобного подхода в .NET фреймворках.
Видимо, вы ASP.NET Core не щупали раньше. Там до появления современного шаблона приложения (на WebApplication) в .NET 6, стандарно использовались шаблоны (они и сейчас осталиь), в которых инициализация производилась в специальном Startup-классе. Так вот у Startup-класса были методы Configure (обязательный), ConfigureServices(необязательный) и ConfigureContainer(был редко, только при исполь сторонних DI-контейнеров), которые использовались для начальной настройки приложения, и эти методы разыскивали именно по их именам (там, кстати, возможны были варианты этих имен).
Ну и, в MVC привязка контроллеров и их методов действий по их именам была отродясь. Так что уж не такая это и редкость - вызов метода с именем "по соглашению".
Какая-либо специальная поддержка от компилятора для таких штук не требуется: всё делается через отражение.
PS Ну а статью эту для общего развития почитать мне было полезно: я хоть в геймдев и не стремлюсь, но мало ли, что в жизни пригодиться может.
Спасибо за полезную информацию! Да, с ConfigureServices и ConfigureContainer сталкивался, но не так много работал с ASP, чтобы отложилось в голове, что они тоже не оверрайдят и не имплиментируют ничего. Да, наверно я немного не так выразился. Конечно, есть рефлексия и Linq.Expressions, и они действительно активно используются в самых разных фреймворках. Наверно правильно бы было подчеркнуть более явно, что в Unity есть именно своя система для того, чтобы делать подобные вещи без рефлексии.
Очень информативно, спасибо
Большое спасибо за статью!
Как раз скачал Unity 6)
Возможно стоило добавить инфу о том, что у юнити свой сборщик мусора, который имеет отличия от обычного шарпового. Так же il2cpp емнип накладывает некоторые ограничения на рефлексию.
Отличная статья: полезный и хорошо приготовленный контент!
Отметил ряд моментов, о которых нечасто упоминают в статьях о Unity. В т.ч. про свою реализацию SyncronizationContext
. Такие мелочи важно знать и помнить.
Небольшая корректировка: у Unity и своя реализация GC, отличная от .NET. Могу подкинуть эту статью по этой теме.
Дополнение про UniTask: они полноценно работают в вебе.
Можно, наверное, можно ещё упомянуть про UI
на Canvas
'ах. Там уже вместо Transform
используется его наследник — RectTransform
. Порядок элементов на сцене влияет на порядок отрисовки. Ну и сам канвас имеет свою специфику в плане отрисовки.
И может будет интересно сравнить Unity UI Toolkit с упомянутым в статье WPF.
Как понять Unity3d, если ты .NET разработчик