Советы по оптимизации Unity

Unity — игровой движок, популярный не только среди инди-разработчиков, но и среди крупных компаний.

Он имеет удобный интерфейс, мощный конвейер рендеринга, простую в использовании систему компонентов и, наконец, поддерживает широкий спектр платформ.

Но с простым в использовании интерфейсом усложнить игру еще проще (например, размещая множество ненужных объектов и т. д.), поэтому важно иметь оптимизацию иметь в виду на протяжении всего процесса разработки.

Вот важные советы для трех основных категорий (Рендеринг, Сценарии, и Аудио), которые помогут вам улучшить производительность вашей игры:

Рендеринг

Совет 1. Сохраняйте объекты с компонентом Renderer немасштабированными

Немасштабированные объекты — это объекты, имеющие масштаб (1, 1, 1). В этом случае Unity не нужно выполнять дополнительные вычисления для изменения масштаба объекта в каждом кадре.

Пример: Допустим, у вас есть модель дома, которая слишком велика или слишком мала для вашего уровня. Естественно, что нужно масштабировать его следующим образом:

Изменение размера здания

В большинстве случаев можно масштабировать объект в представлении «Сцена», но если вы планируете иметь много дублированных экземпляров этого объекта, предпочтительнее изменить масштаб в настройках импорта.

Первое, что вам нужно сделать, это масштабировать модель до тех пор, пока она не будет соответствовать вашим потребностям (например, здание выше было масштабировано с (1, 1, 1) до (0,49482, 0,49482, 0,49482)), затем выберите модель в проекте. Просмотрите и в настройках импорта отметьте масштабный коэффициент (обычно это 1 или 0,1).

Установите новое значение, которое должно равняться масштабному коэффициенту по умолчанию, умноженному на новый масштаб (в моем случае это 1 x 0,49482 = 0,49482), затем нажмите «Применить». Теперь вернитесь к модели в виде сцены и установите масштаб обратно на (1, 1, 1).

Настройки масштабного коэффициента Unity 3D

Объект теперь масштабируется так, как вам нужно, сохраняя масштаб по умолчанию (1, 1, 1).

Этот совет особенно важен для анимированных объектов, использующих SkinnedMeshRenderer, поскольку рендеринг этого компонента требует больше затрат, а наличие масштаба (1, 1, 1) упрощает процесс рендеринга.

Совет 2. Используйте как можно меньше источников света.

В Unity есть 3 типа источников света (направленный свет, точечный свет и прожектор). С точки зрения производительности, направленный свет является самым дешевым для рендеринга, затем точечный и, наконец, прожектор.

Как правило, вам не нужно иметь более одного направленного источника света на сцену, а для точечного и точечного освещения старайтесь использовать как можно меньше (или вообще не использовать его).

Что касается теней в реальном времени, хотя они и улучшают визуальный аспект игры, они требуют высоких затрат производительности, поэтому, как правило, лучше отключить их или запечь в lightmaps и light. зонды.

Совет 3: используйте прозрачные шейдеры с осторожностью

Используйте прозрачные шейдеры или шейдеры частиц только на поверхностях, которые должны быть прозрачными (например, заборы, частицы дыма и т. д.).

Объекты с прозрачностью требуют дополнительного прохода рендеринга, что может снизить производительность, особенно на платформах с ограниченными ресурсами, таких как мобильные устройства или Интернет.

Сценарии

Совет 1. Всегда кэшируйте ссылки на компоненты.

Вам всегда следует кэшировать ссылки на компоненты, если вы планируете получать к ним доступ при каждом обновлении.

Например, проверьте скрипт ниже:

Плохой

using UnityEngine;

public class Script1 : MonoBehaviour
{
    float someValue = 0;

    // Update is called once per frame
    void Update()
    {
        someValue = GetComponent<Script2>().someValue2;
    }
}

Здесь у нас есть Script1, который получает переменную "someValue2" из Script2 и присваивает ее локальной переменной.

Теперь вызов только одного GetComponent в каждом кадре не окажет никакого влияния на производительность, однако вам следует взять за правило кэшировать компоненты, которые будут часто использоваться.

Существует два способа кэширования компонента в скрипте: либо создать общедоступную переменную и назначить ее в представлении инспектора, либо создать частную переменную и назначить ее из меню «Пуск» или «Пробуждение». Проверьте пример ниже:

Хороший

using UnityEngine;

public class Script1 : MonoBehaviour
{

    float someValue = 0;

    Script2 script2Cached;

    // Use this for initialization
    void Start()
    {
        script2Cached = GetComponent<Script2>();
    }

    // Update is called once per frame
    void Update()
    {
        someValue = script2Cached.someValue2;
    }
}

Гораздо лучше то, что теперь к Script2 можно получить доступ при каждом обновлении без снижения производительности.

Сделайте то же самое для встроенных компонентов, таких как BoxCollider, Rigidbody и т. д. (кроме Transform и GameObject, они по умолчанию уже кэшированы, поэтому вы можете сразу получить к ним доступ).

Совет 2. Используйте SendMessage с осторожностью.

SendMessage позволяет вызывать определенную функцию (если она существует) для каждого MonoBehaviour, присоединенного к игровому объекту.

Например, когда вы стреляете из оружия в игре, вы можете быстро нанести урон при попадании пули во врага, без необходимости использования GetComponent и других дополнительных вещей.

Однако этот метод не следует вызывать слишком часто, поскольку он требует больших вычислительных ресурсов.

Совет 3. Используйте GameObject.Find и GameObject.FindWithTag с осторожностью.

GameObject.Find, GameObject.FindWithTag и GameObject.FindGameObjectsWithTag позволяют быстро искать объекты на сцене. Эти методы намного медленнее, чем GetComponent, и их следует использовать только во время инициализации.

Совет 4. Избегайте использования OnGUI

Исторически OnGUI был единственным способом сделать меню в Unity. Но с тех пор была добавлена ​​альтернатива под названием UI Canvas, которая намного лучше с точки зрения производительности и предлагает гораздо больше функций.

Тем не менее, OnGUI по-прежнему остается жизнеспособным способом создания пользовательского интерфейса в Unity, и если вам абсолютно необходимо его использовать, имейте в виду, что OnGUI вызывается как минимум дважды за кадр (в два раза чаще, чем Update и LateUpdate), поэтому не используйте его для любых вычислений, кроме пользовательского интерфейса.

Единственное, что вы можете сделать, — это создать отдельный скрипт, в котором есть только OnGUI, и включать/отключать его при необходимости.

Например:

UIScript.cs

using UnityEngine;

public class UIScript : MonoBehaviour {

    void OnGUI()
    {
        if(GUI.Button(new Rect(5, 5, 125, 25), "Button 1"))
        {
            //Button 1 was pressed, Do Something
        }
        if (GUI.Button(new Rect(140, 5, 125, 25), "Button 2"))
        {
            //Button 2 was pressed, Do Something
        }
    }
}

Script1.cs

using UnityEngine;

public class Script1 : MonoBehaviour
{

    UIScript uiScript;

    // Use this for initialization
    void Start()
    {
        uiScript = GetComponent<UIScript>();
        uiScript.enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            //toggle UIScript when Tab is pressed
            uiScript.enabled = !uiScript.enabled;
        }
    }
}

И UIScript, и Script1 прикреплены к одному и тому же GameObject. Script1 контролирует, когда показывать меню.

Когда игрок нажимает Tab, включается UIScript и отображаются кнопки. Повторное нажатие Tab деактивирует его, скрывая кнопки.

Пока UIScript деактивирован, метод OnGUI не вызывается, что, в свою очередь, повышает производительность.

Совет 5: Используйте профилировщик

Profiler — один из наиболее важных инструментов для выявления узких мест и падений частоты кадров, который упрощает поиск точной причины низкой производительности.

Аудио

Аудиоклипы можно оптимизировать, убедившись, что их настройки импорта верны.

Оптимальные Настройки импорта аудио будут зависеть от длины звука, частоты воспроизведения и целевой платформы.

Рекомендуемые статьи
Как использовать обновление в Unity
Генератор рекламных щитов для Unity
Unity оптимизирует вашу игру с помощью профайлера
Улучшение производительности мобильной игры в Unity
Настройки импорта аудиоклипов Unity для лучшей производительности
Советы по Twitter для Unity
Как стать лучшим программистом в Unity