Как сделать ускорение юнити

Обновлено: 08.07.2024

Приветствую! Когда- то давно я задавался вопросом, как сделать замедление времени в Unity. И казалось-бы первый же запрос в поисковике, выдаст верное решение. Использовать Time.timeScale, но есть одно но. Маленькое такое "но". Если использовать только эту строчку кода, то при замедлении физика начинает вести себя странно, она дергается, хотя FPS не проседает.

Что-же происходит? А происходит вот, что:

Когда вы замедляете время с помощью строчки кода, к примеру,
Time.timeScale = 0.5f. Время замедляется и все, что использует Time.deltaTime тоже замедлиться, логично. Но физика рассчитывается не с помощью update а c помощью FixedUpdate! Соответственно, использует Time.fixedDeltaTime.

Поэтому, когда все замедляется, физика рассчитывается все с той же скоростью, через равные промежутки времени и визуально все дергается.

Что же делать?

Все оказалось банально, как и всегда.

Вместе с Time.timeScale нужно пропорционально менять и Time.fixedDeltaTime. Тогда физика будет рассчитываться правильно в соответствии с замедлением и дерганья не будет. приведу пример.

Обложка: Методы оптимизации при разработке в Unity 3D

Использование Performance Profiler

Первое место, куда нужно смотреть, когда хочется улучшить производительность — это Unity Profiler. Эта функциональность доступна в Unity Pro и позволяет анализировать проблемные места. Профайлер — бесценный инструмент. С его помощью можно определить, где возникают проблемы с частотой кадров. Для его использования запустите игру на мобильном устройстве и профайлер на PC. Когда вы запускаете игру, профайлер начинает загружать данные о производительности.

Чтобы использовать профайлер на мобильных устройствах, сделайте билд в Developer mode. Из документации Unity:

Чтобы иметь возможность подключиться к плееру, плеер должен быть запущен с помощью опции Development Build, которая находится в диалоговом окне Build Settings.

Здесь также можно отметить флажок для автоматического соединения редактора и плеера. Профайлер показывает график использования CPU во время игры. Просто подключите мобильное устройство к машине для разработки и проходите игру. Профайлер покажет все проблемы в режиме реального времени. Он разбивает активности на Rendering, Scripts, Physics, GarbageCollector, VSync и другие. В мобильных играх часто бывают проблемы с рендерингом. Иногда скачки производительности возникают в скриптах при загрузке сцены, но в этом нет ничего необычного. Некоторые скачки связаны с физикой.

Физика и искусственный интеллект

Я опишу несколько основных идей оптимизации кода физики и перейду к графике.

Static batching

Это фича Unity, которая экономит много циклов CPU. Каждый раз, когда объект рендерится, происходит Draw Call — команда для CPU или GPU о том, что объект должен отрендериться. Unity запускает несколько вызовов отрисовки и накладывает их друг на друга, это и формирует сцену. Однако каждый Draw Call требует ресурсов CPU, поэтому мы хотим минимизировать их количество.

Тут и стоит использовать Batching. Он нужен для того, чтобы не делать лишние Draw Calls. Batching бывает двух видов: статический и динамический. Статический дает лучшую производительность, поэтому мы всегда стараемся использовать его.

Чтобы эффективно применять Static Batching, используйте как можно меньше различных материалов. Для этого скомбинируйте все материалы в одну большую текстуру. Последний шаг — добавить Lightmap к сцене. Поскольку мы практически не используем память для текстуры объектов, можно сделать довольно подробную Lightmap, и проблем с памятью не возникнет.

Для использования Static Batching поставьте флажок Static в свойствах объекта. Его можно использовать только для объектов, которые не перемещаются, не вращаются и не масштабируются в сцене.

Dynamic Batching

Для не статических объектов можно использовать Dynamic Batching. Объекты с Dynamic Batching требуют определенные ресурсы на каждую вершину, поэтому он применяется только к мешам, содержащим менее 900 вершин. Наш шейдер использует Vertex Position, UV и Colors. Таким образом, у нас может быть до 300 вершин на объект.

Некоторые полезные советы из руководства Unity:

  • Динамический батчинг связан с дополнительной нагрузкой для каждой вершины, так что он применим только к мешам, в сумме содержащим менее 900 вершин.
  • Если ваш шейдер использует Vertex Position, Normal и единственный UV, то вы можете батчить до 300 вершин; тогда как если шейдер использует Vertex Position, Normal, UV0, UV1 и Tangent, то только 180 вершин.
  • Не масштабируйте. Объекты с масштабом (1,1,1) и (2,2,2) не будут батчиться.
  • Равномерно масштабированные объекты не будут батчиться с неравномерно масштабированными.
  • Использование различных материалов приведет к сбою батчинга.
  • Объекты с Lightmap имеют дополнительный (скрытый) параметр материала: смещение/масштаб в Lightmap, поэтому объекты с Lightmap не будут батчиться.

Заметьте: если у объекта есть анимация, но при этом есть часть, которая никогда не двигается, можно отметить эту часть как статическую, и она не будет мешать анимации.

Я хочу, чтобы мой корабль постепенно набирал скорость, а затем медленно останавливался, как будто не было гравитации, поскольку это будет космическая игра!

Вот мой код для моего космического корабля в настоящее время.

Как это может быть сделано?

2 ответа

Как и в случае с Unity, есть сотни способов сделать это, но я думаю, что использование физики было бы самым простым.

Прямо сейчас вы напрямую управляете преобразованием. Это хорошо, но на самом деле гораздо сложнее, чем просто позволить физике Unitys сделать математику за вас.

Все, что вам нужно сделать, это прикрепить компонент Rigidbody (или Rigidbody2D для 2D-игры) к вашему кораблю.

Затем, добавив силу к Rigidbody, вы получите хорошее постепенное ускорение, а путем настройки линейного и углового сопротивления Rigidbodys в инспекторе вы получите очень плавное и естественное замедление ощущения.

Использование физики - очень интересная и важная часть разработки Unity, поэтому, если вы только начинаете, я настоятельно рекомендую изучать ее сейчас, и это идеальная проблема, которую нужно решить.

Теперь надо на уровень добавить триггер, для перехода на другую карту, Создаем обычный куб, на коллайдере ставим галочку Is Trigger. Сам куб обзываем именем GameFinish. Разместите его там, где должен заканчиваться уровень и настройте размеры. Выключаем Mesh Renderer. На куб вешаем скрипт с таким-же названием:

Не забываем указать имя сцены для загрузки в переменной - level.

Продолжим, создаем новую сцену и сразу сохраняем ее под именем Loading. Добавляем GameObject -> UI -> Image и переименуем в BG, это будет фон, устанавливаем цвет картинки в черный и параметры позиции так, как показана на скриншоте ниже:

Фоновая загрузка сцены / уровня

Добавим еще одно изображение под именем Loading, в качестве источника, возьмем какой-нибудь значок загрузки, например вот такой:


Сделаем анимацию, выделяем картинку и переходим на вкладку Animation, затем, Add Property -> Rect Transform -> Rotation. И делаем ключевые кадры, от 0 до 360 по оси Z:


Выключаем объект, чтобы не мешался и устанавливаем его в правый нижний угол, а также ставим соответствующий пресет якоря:


Добавляем GameObject -> UI -> Text под именем LoadingComplete, этот текст будет появляться после того, когда уровень будет загружен, разместите его там-же, где и значок загрузки.

Создаем пустой объект Ctrl+Shift+N с любым именем, а на него вешаем скрипт GameLoading:

В переменной _keyCode можно выбрать, какую клавишу наживать, по умолчанию это - "Пробел".

loadingInfo - текст перед стартом игры, например; "Нажмите 'пробел', чтобы начать игру."
loadingIcon - иконка загрузки, которая будет показываться пока сцена загружается.

Читайте также: