Оптимизация игры на Unity, часть 3 - Код. Profiler
HTML-код
- Опубликовано: 28 сен 2024
- Привет! В этот раз будем оптимизировать программный код, разберёмся со встроенной в Unity утилитой Profiler, которая позволяет тестировать производительность и оптимизацию игры, и рассмотрим частые ошибки в коде, которых стоит избегать, чтобы в игре был высокий и стабильный показатель FPS.
Поддержать канал на русскоязычном Boosty: boosty.to/insa...
Или на Patreon: / insaneone
Discord-сервер канала: / discord
Группа VK: insaneo...
У меня на канале регулярно выходят новые видео с уроками по Unity и разработке игр, а так же другими интересными темами, связанными с геймдевом. Подписывайся!
Не забывай оставлять комментарий, если у тебя появились вопросы или предложения по видео :)
#Unity #ОптимизацияUnity #РазработкаИгр
Это уже третье видео по оптимизации игры на моём канале. :)
Пишите в комментариях, о чём ещё вы бы хотели услышать в следующих видео!
Го туторы по шейдерам. :D
Если их ещё нет...пока не знаю.
Или туториалы о том как добиться максимально красивой графики...
Спасибо, вот это прям очень полезная штука. Сколько туториалов смотрел, никто про неё не говорил
Только подписался и тут же новое видео) Лайк авансом!
Интересно было бы посмотреть видео о том какие хитрости и приемы используют разработчики для оптимизации игры. Например лифты в играх которые часто служат тем, чтобы незаметно подгрузить другую часть уровня.
Как только компания юньки выпустила технологи диагностики проекта - все сразу начали беспокоится о оптимизации. А раньше, экземпляры объектов в update создавали. Не кто не жаловался.
Это та информация, которую сложно найти в рунете, спасибо огромное!
Качество видео супер)) Продолжай в том же духе!
Спасибо за контент!!
Хорошо объяснил + с примерами☝
Очень полезная инфа, спасибо! лаконично, без растягивания времени, круто)
Очень классный контент!
Спасибо! Отличные советы
Эх, немного другого от этого видео ожидал. Про работу с профайлером почти ничего в ролике не было, скорее набор советов для новичков. Что тоже неплохо, но про другое
спасибо за видео
Да вообще лучше всегда вместо функций поиска объектов, вроде Find или FindChild использовать ссылки на объекты, которые созданы в начале игры. Да, это немного увеличит требуемое место в памяти, но лишь немного, ведь это просто ссылки, а не полноценные копии объектов.
Расскажи больше пожалуйста о Post эффектов
Спасибо за качественный контент! Много чего узнал с видео.💥 Давай когда наберёшь 1000 подписчиков стрим замутишь??
Вполне может быть. А на какую тему интересуют стримы вообще?)
@@insaneone-7220 На тему разработки игр😁
Спасибо за видео. Может стоить параллельно начать плейлист про структурирование и правильные приоритеты на юнити? Если тебе не будет сложно. Голос и подача отменная
Спасибо за фидбек) А что именно понимается под структурированием и приоритетами? Улучшение качества кода или что-то другое имеется в виду?
@@insaneone-7220 Скорее всего, он имел в виду архитектуру кода и использование паттернов. К примеру zenject или как он там щас называется)
Имхо. За свои пару лет работы в юньке, не раз пытался пристроить популярные подходы из мира вебки и как-то не сложилось, пришел к тому, что стандартная компонентная система и так хороша, если уметь ей пользоваться. Когда будет не лень, посмотрю что там в ECS интересного)
@@slava7522 да в целом моё мнение примерно такое же. Когда-то давно умный человек мне сказал "Юнити построена на компонентах. Зачем ты пытаешься выдумать что-то другое?", тогда эта простая вещь почему-то стала для меня озарением, и очень сильно упростила мою жизнь как разработчика)
@@insaneone-7220 Я имел ввиду как правильно начинать писать, начиная с архитектуры. На какие вещи точно нельзя забивать, какие есть примеры реализаций элементов или структур и твои мысли по этому поводу. Это так-то сложная тема, просто как вариант
@@ghoulwill4399 Понял. Подумаю, как про это можно было бы рассказать, спасибо за разъяснение)
Спасибо, крутой урок, жаль что вы канал забросили
Пожалуйста, сними видео про лечение вылетов с помощью UnityCrashHendler
Я понимаю, что видео уже 2 года, но что лучше использовать: GetComponent или назначать через [serialize field]?
Нет особой разницы, если GetComponent при инициализации. SerializeField позволяет вручную назначать из редактора, что удобно - не требует изменений кода и перекомпиляции.
Я искал золото, а нашел алмаз
огонь
Человек рассказывает про кэширование 6 минут, даже не объясняя в чём проблема его отсутствия
Если кто-то наткнулся на этот коммент и не понимает, что и как оптимизировать, вот краткое объяснение
Оперативной памяти, которая хранит переменные, очень и очень много, почти никогда не возникают проблемы с её нехваткой
А вот профессор или видеокарту можно нагрузить любой простейший вещью, банальным if в коде
И чем меньше будут задаваться эти 2 вещи, тем лучше дела будут с оптимизацией
На примере FindObjectOfType, если на сцене сотня объектов, метод каждый из них проверит, и проверит каждый компонент на объекте. Чтобы понять, как это влияет на процессор, попробуйте вручную такое сделать, перебирая каждый и поймёте, в чём дело
Кэширование решает эту проблему так: ты выделяешь немного памяти, которой очень много, делаешь эту работу один раз, и запоминает результат
Благодаря этому не приходится глобальную работу делать несколько раз
Есть вариант менее удобный но он ещё лучше: на сцене заранее выделить необходимый объект, если это возможно, и запихать вручную ссылку на него туда, куда это нужно
Всё это либо полностью избавит процессор от лишней работы, либо сократит её а разы, из-за чего всё будет происходить быстрее
Таким же образом можно избавиться от кучи if или циклов, которые сильно нагрузят процессор. If можно заменить на case который работает для множества вариантов сразу в случае выбора по условию, и работает в разы быстрее if
Циклы не стоит делать вложенные, так как из-за особенностей их работы они будут значительно медленнее работать таким образом, и разделив 3 вложенных цикла на 3 отдельных будет значительный прирост
Или делать какую-то работу не каждый кадр, а например 50 раз в секунду, раз в секунду или ещё реже через какой-то короутин, это может уменьшить нагрузку на процессор
И с видеокартой всё точно так же, однако в случае юнити эта проблема не такая большая
По моим словам должно быть понятно: оптимизация заключается в том, чтобы заставить комп делать как можно меньше, и это всё
То есть, чтобы оптимизировать проект, надо не просто исправить пару критических моментов, но ещё и понять, в чём проблема, чтобы проектировать приложение от этого, иначе оно никогда не начнёт работать
Иначе уберёте ваши GetComponent из Update, а фпс повысится с 10 до 30, но проблему это особо не решит
у меня нету UsableItem - это изза нэймспэйса оптимизэйшенпт3???
UsableItem я добавил сам в этом проекте, он не присутствует в Unity. Ну и да, неймспейсы нужно подключать через using NamespaceName;, если ты их используешь например как в видео)
@@insaneone-7220 , а что внутри этой области имен ?
@@ZmastaZz только то, что я показывал в этом уроке) Это скорее для себя: я когда записываю видео, всё делаю в одном проекте Unity. Чтобы не было конфликтов, каждый урок имеет свой namespace.
А в какой проге пишешь код?
Rider
спасибо
@@insaneone-7220 от JetBrains?
@@АнтоновЗахар-с9д да
Чел, ты... Видео конечно классное. Но первую половину видео ты просто рассказываешь что надо использовать не метод старт, а метод апдейт...
Ого, классный лайоут, украл
С точки зрения геймдизайна разовый вызов Raycast бесполезен, так как в играх сейчас всегда вешают какой-то "маяк" для игрока. Например картинка действия или кнопка для действия. В таком случае разовый Raycast это бесполезных 5 строчек, так как в Update всегда будет Raycast для "маяка". Костыли в виде "сделаем таймер" или "пусть проверяет раз в 0.5 секунд" всегда ломаются. По этому в данном случае никак не оптимизировать.
Ооо да, я где-то у истоков будущего крутого канала.
Очень нравиться, что видео почти без воды, все только по делу. Так и видео еще хорошо отредактировано, нет ни одного вздоха на вдох и выдох, и выглядит как ускореное в 1.25 раз. Без сарказма, очень хорошо что сжато и по делу, так еще и коментарии, что там не с воздуха 100 взято, а вполне реальная ситуация.
Отличные видео по оптимизации. Отдельная благодарность за живые примеры производительности, так как выглядит гораздо нагляднее.
Спасибо за крутой и уникальный контент!
Корутины - это добро! Согласен. Постоянно их использую. Одну раз в секунду, вторую раз в 10 секунд. В одной помещены более важные действия, во второй менее важные.
когда у тебя 30фпс - это норма, херово когда у тебя сейчас 60фпс, а через мгновение уже 10, а потом снова 60, а потом снова 10. Фризы и статоры это боль
Тема с кэшированием данных достойна отдельного видео) Статическое кэширование, атрибуты, кэширование в свойства и т.д.
На сколько помню, в Юньке используется свой оператор сравнения для компонентов, при этом двигло обращается в нативный код и этот момент тоже можно оптимизировать приведением к object
Согласен, очень много любопытных моментов в C# и отдельно в Unity, но на глубоких этапах там уже идёт битва на байты и наносекунды в общих случаях, я многими из этих вещей даже сам почти не пользуюсь, т.к. релизнутая игра лучше идеально оптимизированной. :D Но всё же наверное было бы полезно это рассмотреть, спасибо за идею)
Кэширование - наше всё! :)
Хотелось бы увидеть туториал про то,как время идёт,когда приложение выключено и чтобы выращивать можно было что-то,пока приложение выключено у пользователя.
В принципе это было у другого хорошего автора - Emerald Powder. Надо собирать авторов которые шарят в кучу ) А то остальные сделают говнокода на полэкрана чтобы тупо двигать перса на клавишах и радуются ) А тут тебе и кеширование и оптимизация. Аж глаза радуются)
Да, сам про Emerland Powder хотел написать, у него вроде не так давно на эту тему видео было) Но всё равно за идею спасибо, можно будет как-то эту тему развить я думаю
Всё ясно. Осталось придумать как исправить мой код... (тут не ясно)
А автор канала не хочет попробовать rust оптимизировать?)
А что делать если скачет Editor loop?
Он влияет на производительность только в редакторе Unity. Чем тяжелее код основного проекта, тем больше требует Editor Loop, а так же все скрипты редактора, плагины и т. д. - сокращать их количество или оптимизировать код.
Прям радуешь)
Еще пушка бьющая всех врагов в радиусе можно вызывать поиск врагов после ее перезарядки и тогда стрелять, а если нет доступных врагов, тогда каждые пол секунды.
Да, вполне хороший вариант)
хорошее видео
Спасибо Большое!
У меня появился вопрос, а как в апдейте разово закешировать что-то? Сделать булеву переменную(кэширован), и проверку (если кэширован = ложь - вызвать функцию кэширования), или как?
В Update вероятно не должно быть ситуаций с необходимостью кеширования, лучше делать это при инициализации (например, в Start). Но да, в апдейте можно сделать флаг для проверки, или же проверять существование самого объекта в переменной, в которую он будет кеширован (через проверку на null).
@@insaneone-7220 спасибо большое за ответ!) просто Вы упомянули о случаях, когда объект создаётся после начала, и её кэшировании в апдейт, вот мне и стало интересно, а как это сделать, вдруг что)
блин, итс вэри юсфул=) подписка, лайкос
а, и колокол
Жду 4 часть !!!!!
Еще можно не пинать постоянно new WaitForSeconds(1f) в корутине, а просто обойтись конструкцией
var endTime = time.Time + 1f;
while (endTime > 0)
yield return null;
А вместо перезапуска корутины, если потребуется, воспользовться goto.
если еще будут видосики про оптимизацию архитектуры для последующих обновлений игрульки, добавления нового функционала и модулей, чтобы все нафиг не порушилось, то зэ бэст =)
Как, чтобы не рейкастить каждый кадр, сделать, чтобы на экране выводилась надпись, что я могу сделать с объектом, если я на него только навёлся? Рейкастить каждый кадр, но только по максимально ужатому слою? А в таком случае оно будет реагировать через стены? Это фиксится добавлением слоя стен в рассчёт? (Такое большое количество вопросов только потому, что хочу разобраться)
Также. Будет ли приемлимым решение в "Ультра слабом режиме" делать рейкасты "по времени", а не по кадрам. Думаю, сделать в FPS игре подобный "режим"
Можно сделать рейкаст с задержкой, например 4 раза в секунду, но надписи тогда будут обновляться с небольшой задержкой (не более 250 мс при проверке 4 раза в секунду). Или более простой вариант - делать рейкаст каждый кадр, но использовать его вообще для любых расчётов, завязанных на этом луче. Это не просадит производительность слишком радикально. В видео я об этом говорю принимая во внимание, что в проекте может быть и 10 рейкастов запросто, конечно оставлять их все в Update нецелесообразно. А если он будет всего один, например, то это обычно не страшно. Если же идёт борьба за каждый кадр FPS, то стоит попробовать первый вариант)