Фишки в C# и Unity, о которых ты не слышал!
Вставка
- Опубліковано 9 лип 2024
- Всех с первым днём лета :)
Салют, ты на канале Night Train Code 😎
Давно не было видео и пора исправлять ситуацию. Ловите сразу крупный ролик про полезные фишки и трюки в C# и Unity, о которых вы, возможно, не знали
Продвинутый C#. В этом видео много интересного про инкапсуляцию, nullable safety и многое другое
• 🖤 GitHub: github.com/MeeXaSiK
• 🖤 VK: nighttraincode
• 🖤 Telegram: t.me/nighttraincode
• 🖤 Instagram: / the.meps_
• EventValue:
github.com/NickKhalow/EventValue
• Singleton:
github.com/MeeXaSiK/NightSing...
• MonoCache 2.0:
github.com/MeeXaSiK/MonoCache
• Таймлайн:
00:00 ► Вступление
00:52 ► TOP MOMENT
01:53 ► Грамотное использование Instantiate
02:26 ► using static
03:00 ► using Object = System.Object;
03:34 ► ExpressionBody и Лямбда выражения
04:59 ► Выражение nameof
05:28 ► IfNotNull(Action)
06:31 ► return x = y;
06:39 ► Оператор объединения с null (??=)
07:28 ► Оператор объединения с null (??)
08:11 ► Тернарная операция
09:02 ► Оператор безопасной навигации (?)
09:24 ► Интерполированные строки
09:41 ► Ключ event
10:14 ► CanBeNull
11:06 ► Статический конструктор
12:01 ► is и as
13:02 ► Передача класса в аргументы
13:40 ► Сериализация свойств в инспекторе Unity
14:11 ► Модификатор sealed
14:30 ► Инверсия списка ~
14:56 ► return, continue, break
15:37 ► Минус перед числовой переменной
15:52 ► return x switch { };
16:15 ► Аргументы метода
16:32 ► IEnumerable (IReadOnlyList)
16:56 ► Пробел при поиске
17:09 ► Lock инспектора
17:25 ► Alt + клик по иерархии
17:32 ► Лайфхак с добавлением в коллекцию
17:40 ► С первым днём лета :)
• Спасибо за поддержку:
Макс - попросил не указывать ссылку на сайт. Просто знайте, что есть один крутой Senior C# программист :) github.com/Sligerr
Никита - alexko.ltd/
• Поддержка канала:
www.donationalerts.com/r/nigh...
Для коллекций только для чтения, которые являются листом, лучше использовать IReadOnlyList, в который так же входит IEnumerable, это даст возможность обращаться через индекс, а не только через foreach в случае IEnumerable
Верно подмечено, благодарю)
Тем более, что доступ через foreach вызывает боксинг на IEnumerable
Я в шоке, не думал, что такую годноту кто-то будет выгружать на ютуб.
Спасибо, бро, за такие классные видосы!
Как же круто что нашел этот канал) спасибо.
И тебе спасибо)
Ты вернулся!) Шикарные видео, да и слушать тебя очень приятно) Жду с нетерпением новых видео)
Спасибо)
С возвращением!)
Смотрел все ролики и могу сказать, что все они хороши!
Буду дальше ждать новых видео от тебя!
Привет, спасибо за тёплые слова. Ради этого и делаю упор на качество)
По плану целых 10 видосов уже есть. Вопрос только в том, как бы время на всё это найти
Сахар ? и ?? с проверкой на null нужно юзать очень осторожно, потому что они внутри используют неперегруженный оператор ==, поэтому с монобехами, например, их юзать категорически нельзя. Вроде в новых версиях C# это собираются поправить.
Тоже хотел написать об этом
16:50 есть ещё такое) ireadonlylist ireadonlydictionary ireadonlycollection
Погуглите там не сложно)
17:20 вместо замочка можно ПКМ по названию компонента, и там Properties. Работает как отдельное залоченое окно для данного компонента. Как в инспекторе, так и в Project табе.
Пользуйтесь! 😉
поставил лайк и, конечно же, оставил комментарий, потому что вай-вай-вай. спасибо за контент)
Благодарю! 😎
Долгожданное возвращение))
Как всегда очень круто. С возвращением)))
Спасибо)
Хороший канал, очень удобная подача материала.
Прошлое видео которое я смотрел про Leoecs. Несмотря на то что сам leoecs уже изменился, объяснено всё очень доходчиво и видео не теряет актуальности (даже можно для других ecs применять). Как только возникали вопросы тут же получал на них ответ (например про связь сущности со объектами на сцене и в обратную сторону).
Успехов !)
Спасибо большое, всегда рад помочь)
Музыка из начала видео: "скачать бесплатно металл без авторских прав")))
Реально узнал много нового. По некоторым темам искал долго инфу в интернете так и не нашёл, но потом нашёл это видео. Это видео не из тех самых стандартных обучалок где расскажут про разве что атрибуты.
Спасибо)
Отличная информация и подача, желаю успехов с каналом!
Контент вышка!
Спасибо большое)
Сижу, нифига не понимаю,но так внимательно наблюдаю и слушаю..
Благодарю тебя, за твои видео, всегда нахожу то, что я не знал, ты ещё один из тех, кто дарует мне знания, короче, спасибо, благодарю, продолжай так же, хорошо получается 👍
Спасибо, броу!)
Спасибо! Узрел несколько внезапных фишек, типа "field:" и "Alt+Click на папку в проекте". А вот объяснять про return/continue/break - это, кмк, уже за гранью добра и зла :))
Ахах, на здоровье)
За гранью то за гранью, но, оказывается, не для всех очевидно
"Пжлста помедленнее!! Я записыую!" (с)
Спасибо за видео, а теперь, пожалуйста, почините меня обратно))
На здоровье)
Отличный ролик! Спасибо)
Спасибо, на здоровье)
жесть,
видео ОЧЕНЬ богато на полезные вещи!
аж голова лопается с первого раза
Мне понравилось, продолжай в том же духе.
Благодарю)
11:05 спасибо!) Была такая штука) пришлось все ID итемов сдвинуть направо)
Не понял когда ты рассказывал про сериализацию свойств, достаточно было сделать сет приватным, чтобы его нельзя было менять. Еще кстати прикольно если бы ты добавил, что при поиске есть возможность отфильтровать по типу. Например нужно найти сцену с названием level1. ты можешь так написать t:scene level1. В окне иерархии тоже это работает например мне нужно найти все объекты на которых висит скрипт Enemy. Можно вот так сделать t:Enemy
С поиском годный лайфхак ты вспомнил)
Про сериализацию: да, можно просто private сделать, но если в свойство добавить какие-то действия в get или set, то оно тоже перестанет отображаться в инспекторе. Поэтому и показал второй способ на такой случай
Развивайся дружище, желаю тебе поскорее получить монетизацию и выпустить много качественного контента. Также успехов с игрой тебе.
Спасибо большое)
С первой секунды начало резать слух произношением. В скобках указал как правильно читается
геймАбджект (но читаешь потом Обджект пул)
инстанТиэйт (инстанШиейт)
гет кАмпанент ([kəmˈpəʊnənt])
юнити Инжин (Энжайн)
Канал не брасай, очень качественный контент
Спасибо, не собираюсь)
Оч много полезного, крутяк
Очень круто, спасибо!
На здоровье)
Прекрасные советы. Многими фишками сам пользуюсь.
Спасибо)
Большинство фишек я и так знал, но было и что-то новенькое
классные фишки) очень полезный видос получился) спасибо!
На здоровье, спасибо)
Половина видео сводится к фразе: Используйте Rider вместо богомерзкого Visual Studio
Пхахах. После Rider'а как-то зашёл в Visual Studio спустя год. В общем... как зашёл, так и вышел...
Ключ брик, да, если бы я так сказал на собесе, то меня бы точно ушатали бриком
Резонно)
Огромное спасибо за годные советы!
На здоровье)
ОГО, НОВЫЙ ВИДОС. ТЫ ЖИВОЙ!
Конечно, ахах, привет)
@@NightTrainCode не хочешь сделать видос по DOTween ?
@@user-wv4cz4ls4l Есть в списке)
Это все так интересно, но все еще так непонятно. Надеюсь, наступит момент, когда я буду смотреть подобные видео без сильного напряжения извилин! Спасибо за видео.
Если будешь заниматься этим делом каждый день, то наступит)
@@NightTrainCode а ты случайно репетиторством по юнити не занимаешься? 😀
@@mistertwink Иногда занимаюсь)
Напиши мне вк / в тг, если интересно
Топово!
Спасибо)
13:03 сильно!
Супер годно, буду скидывать этот видос все джунам перед началом работы, да и некоторым мидлам не помешало бы)
Ахах, спасибо большое, рад помочь)
Потом мой курс от нуля до джуна, как выйдет, можешь так же распространять 😹
12:25. Проверяя на null оператор is является самым производительным. Попробуйте взять бенчмарки
Ну, как-то тестил я "==" и "is" в профайлере ради интереса и "==" был пошустрее
@@NightTrainCode стало интересно. Проверил и оказалось, что is все же быстрее в 2 раза. При том, что == как раз производит всякую магию в методе Object.CompareBaseObjects. Вначале идет апкаст в тип object и проверяется уже object == null, а после еще проверяет Object.IsNativeObjectAlive, где под капотом все равно все сводится к оператору is). Замеры проводил через Perfomance Test Report библиотеку
Красава продолжай ,тащи канал ,очень полезно ,выручаешь оч хорошо, я как раз начинаю делать игру ,и твои уроки кстати
На здоровье, спасибо за коммент)
using Random = UnityEngine.Random;
А что так можно было? Ура! Спасибо!
Да! На здоровье)
Лучший просто
Есть ещё одна удобная штука.
Обычный метод
void Start() { }
Можно заменить на
IEnumerator Start() {}
Юнити запустит его как обычный старт. Но как корутину. Можно использовать для инициализаций.
IEnumerator Start()
{
while( Game.IsInit == false)
{
yield return null;
{
{
IEnumerator - зло, никогда его не юзаем, только асинки
А про то, к каким ошибкам может привести while при его неправильном использовании и переходе между сценами вообще молчу
Я слышал есть способ с помощью кода переносить изменения с одной сцены на другую покажешь?
Например я сделал интерфейс на 1 уровне, а мне нужен на всех 30 уровнях, мне же придется копировать его и вставлять в каждую сцену и потом ещё ссылки в инспекторе расставлять?
Для этого и нужны префабы) В видео про LOD Group я про них немного рассказал. Ты можешь создать один объект, вносить в него изменения и они применятся на всех сценах сразу
Про них тоже по плану есть ролик. Грамотная работа с префабами - тоже отдельный вид искусства)
Ссылки в инспекторе обычно я прокидываю только в префабах внутри этого самого префаба. Чтобы я его в любой момент закинул на сцену и не нужно было со сцены в него что-то прокинуть через инспектор или наоборот
Привет! Слушай у меня небольшая каша в голове возникла, может расскажешь что да как:
Значит у нас есть несколько видов делегатов Action UnityAction EventHandler
Как я разобрался UnityAction используется когда надо что-то в Unity UI передать.
Но вот чем отличается Action от event EventHandler для меня загадка. И то и то одинаково используется, так в чем разница?
Качество на высоте, дружище! Мб уже писали, но null-coalescing (??=, ??) лучше избегать в unity, особенно новичкам. Загугли, у юньки есть проблемы с ним, вроде как до сих пор не пофиксили.
Спасибо)
Да, трабл в статике я уже с ними нашёл, про что сказал в видео. А так пока всё было окей
@@NightTrainCode, не там дело не в статике на самом деле, а в том, что проверка на null для UnityEngine.Object реализована своя особенная(override Equals()), с обращением к нативной части внутри. Когда мы дестроим UnityEngine.Object, то он уничтожается в нативной части движка, а вот C#-оболочка продолжает существовать и фактически для C# она != null, поэтому весь шарповый сахарок(?./??/etc) видит живую оболочку и говорит "Да не, всё ок, он не нул". Поэтому для юнитёвских объектов всегда надо проверять явно ==/!=/Equals(null). Так же эта особенная проверка теряется, если мы сохраняем ссылку на интерфейс, реализованный в юнити-объекте, тк компилятор больше не знает, что на той стороне у нас UnityEngine.Object и надо использовать особый Equals().
Видео огонь, некоторые моменты значительно упростят кодинг, будет ли видео про addressables?
Ля ты батя!
Люююто недооценен. Очень крутой контент по юнити и шарпу, особенно для тех, кто знания расширяет, подтипа меня. Базу взял у Сакутина, развиваю знания с тобой, спасибо за контент, бро 🔥
На здоровье, спасибо большое)
Доров сахарок, давно тебя не было, у нас тож рост произошёл за это время, больше 1млн установок без вложений в рекламу
Как обычно у тебя хороший контент :)
Надеюсь больше не будешь пропадать :)
Привет, поиск по запросу - мощная вещь, поздравляю)
Спасибо, надеюсь, что минимум по видосику в месяц будет выходить
Про выражения switch хотелось бы по подробнее(для зрителей), штука мощная, но не все её понимают, хотя там 5 минут поиграться и почитать документацию, но у меня коллеги на работе до сих пор не вывозят логику работы такого выражения, особенно когда прямо там объявляешь переменные, так еще и условия проверяешь
По идее то да, с большинством фишечек поиграться по 5 минут и разобраться, что к чему
А про switch можно, конечно, ещё было пару примеров снять с другими типами, но всё равно смысл один и тот же
В курсе уже буду такие моменты тщательно разжевывать)
ждем рецептов шашлыка
оно живое
Bro, в свойствах нет двух аксессоров Эсть get аксессор и set мутатор -)
Справедливо
Привет 13:17 пытаюсь повторить , но ничего не понимаю не работает , повесил наследников на кубы колайдеры есть , на тригерах ис тригер есть , двигаю их и так и сяк , но ответа ноль . Код польностью идентичен . Помогите кто может !
Ты добавил Rigidbody на движущийся объект? Вроде можно isKinematic включить, но лишь бы RB был
Спасибо за видео!..
Интересно, сколько надо наяривать в Unity, чтобы так его понимать и писать норм код?.. Кое-какими фишками из ролика я, конечно, пользовался. Например публичными полями с лямбда, вместо свойств, или запихиванием группы объектов через замочек (не в том же виде, что в видео, но вообще... типа пула объектов)
Но в остальном - куча нового, куча непонятного...
Я тут к дз на курсах наблюдателя к шашкам прикрутить не могу :D чтоб ходы записывать, а потом проигрывать, не то что код вменяемый писать...
Ахахах, спасибо за комментарий, всё с опытом придёт)
когда геткомпонент стал тяжелым методом?)) если объект известен, он чисто по нему проверяет наличие компонента и всё.
вот файндобжект это да, юнити пердак рвёт.
Спасибо за видос✌
Ребят посоветуйте с чего начать в Unity c#
Посоветовал бы один курс на Udemy, так их там сейчас приобрести нельзя в России :/
А свой курс от нуля до джуна буду пилить, но на это нужно время
Пройди какой то хороший курс. Что бы основы все объяснили - и сложилась некая цельная картинка что да как.
@@andrey30966 Вот да. А порекомендовать на данный момент я могу только курсы от Сакутина, за остальные не ручаюсь)
Мужик, в ютубе запрос выдаёт лишь английские варианты. Попробуй сделать видос на эту тему.
Великий суп наварили
Привет, попробовал сделать Instantiate не для GameObject, а для MonoBehavoir, как у тебя показано в первом же примере. Unity 2021.2.16f1, InvalidCastException.
А какой смысл в том, чтобы указывать MonoBehaviour?)
@@NightTrainCode А разве GetComponent работает для еще каких-то типов? Вернее, как он отработает, если не будет явного подключения к GameObject другого типа? MonoBehavior же через инспектор подключаем к GameObject. Логично, что это не просто MonoBehavior, а дочерний класс от него. Мне просто не доводилось видеть ни в каких видео или на форумах, чтобы GetComponent использовали не для получения MonoBehavior скрипта
На 5:35 можно где-то код найти на гитхабе?
Спасибо за видео.
На здоровье)
Да, держи
github.com/MeeXaSiK/MonoCache/blob/main/Code/System/NightSugar.cs
Какие меры можно предпринять, если при переходе из одной сцены в другую, сцена на которую я переходу, затемняется?
У меня такое было, а в билде всё ок. Вроде с обновлением версию юнити ушло
Может быть у тебя в коде в статике проблема, но маловероятно
@@NightTrainCode в билде у меня также затемняется. А старые проекти без проблем открываются с обновлением юнити?
@@lukabrykaylo На работе один проект бывает через две-три версии новые проходит и всё хорошо)
Может свет не запечён или автогенегарция стоит
@@NightTrainCode не помогла новая версия.. а где посмотреть автогенерацию?
@@lukabrykaylo Rendering -> Lighting
Привет, можешь сделать видео, как ты реализовываешь некий проект на Leo ECS? Да, у тебя было видео, но в какие - то моменты ты съедаешь слова, что - то недоговариваешь, что вполне логично, ведь видео на 20 минут. А что если просто сделать полноценную игру используя данный архитектурный паттерн. Уверен, что было бы очень круто и полезно. Заранее спасибо)
Привет. В теории можно, а так, не юзаю ECS и выжимаю максимум из монобехов. Пока что мне это не очень интересно)
2:20 странное, я использовал разве что Instantiate().GetComponent(). (Инстантиэйт возвращает объект, и из него сразу ГетКомпонент.) Но если ГетКомпонент можно сократить, круто. А если всё-таки компонента не окажется?
9:57 А этот ключ event работает на UnityEvent, например?
12:20 так стоп, то есть, можно одновременно делать проверку на is и при прохождении сразу получать переменную нужного типа, не используя дальше в ветке as?
1) Его там не может не оказаться, так как в поле мы указываем нужный тип. То есть в поле Unit я не смогу засунуть рандомный GameObject через инспектор
2) Не использую UnityEvent. Это класс, а не делегат. Его можно сделать с { get; private set; }, а подписываться и отписываться через AddListener и RemoveListener. Ключ event туда не засунешь
3) Чего?)
@@NightTrainCode
1) То есть, мы не можем попытаться присвоить значение этому полю через Instantiate если нужного компонента на создаваемом объекте нет? Или можем, но поле останется как было?
2) А, понятно.
3) Ну,
if(variable is NeededClass) {
var newVariable = variable as NeededClass
}
else
if(variable is AnotherClass) {
...
}
Вот типа такого у меня было, а получается, что присвоение можно делать прямо оператором is.
@@SMT-ks8yp 1) Ну объявляем поле Unit. В него мы никак не перетащим объект без этого класса через инспектор
3) if (variable is AnyClass anyClass)
@@NightTrainCode
1) ой, всё, я напутал, это же мы не ранее объявленной переменной присваиваем, это мы копируем объект с компонентом, на который там ссылка.
Ещё фишек
Чувак если в райдере это всё само делается при форматировании кода
Привет. Ты даешь частные уроки ?
Привет, я всё могу)
Напиши вк (cs_exe) или тг (meexasik)
Скидки в Asset store - круто, но купить в нём ассеты нельзя :с
Да, точно, грустно немного. Рад, что успел купить всё ещё полгода назад для своей игры
А на 12:30 есть код? В гитхабе не нашел
Не-а, пока не выкладывал. Если ты про атрибут "as", то да. Там Modular System, которую я ещё не отполировал для гитхаба, чтобы выложить)
@@NightTrainCode в принципе хотел глянуть на весь namespace Development.Glbal....
@@yummybunny7351 Ой, там у меня миллион скриптов)
Много чего оттуда уже на гитхаб есть. В основном мои системки там и шорт-каты
Там ECS уже не бета и теперь ничего не понятно, я бы посмотрел видосик для чайников
Вообще, фишки топовые, но как я заметил, присутствует кучу лямбда выражений и других способов быстро сократить код. Проблема такого применения в том, что это может быть не читаемо как минимум для новичка и как максимум для хорошего мидла, при условии что этих выражений чрезмерно много и они только путают. Я не говорю что стоит от них отказываться, но и пользоваться ими стоит с умом, чтобы посмотрев на условный код, было сразу понятно что здесь имеется ввиду. За примерами далеко ходить не нужно, стоит попробовать вместо человеческого if else переделать это в лямбду, уже придется остановиться на время чтобы понять что где да как. Так что, по моему скромному, я рекомендую использовать эти выражения только тогда, когда вы сами или ваша команда без проблем сможет понять что вы имели ввиду. Пасыба за видос =)
На здоровье)
Ну, прежде, чем читать код, нужно хорошо знать язык программирования. Ту же аналогию можно и с обычными языками провести
Спасибо за коммент)
приучать к нормальному коду, а то так можно всю жизнь избегать чего-то сложнее 1+1
@@argon9113 Именно
Рощщ
А почему не на анрил. Сейчас все туда переходят
Мда. Продвинутый...