Оптимізація продуктивності в unity3d

Оптимізація продуктивності в unity3d

Загалом нижче будуть перераховані основні прийоми оптимізації ігор в Unity.

Кілька порад щодо зниження Draw Calls (Draw Calls - кількість звернень CPU до GPU)

Правильне використання музики в грі:

1. Використовувати невеликі розміри террейн

150x150
2. Pixel Error - виставити з 0 до максимального значення (хоч це і зрадить стрибають вершини при наближенні камери, зате в рази збільшить продуктивність)
3. Відключати прапорець Draw
4. Не використовувати отрисовку трави в інструментах Terrain`a - в рази зменшує продуктивність

1. Всі розрахунки проводити виключно в Update. У FixedUpdate можна робити невеликі перевірки, специфічні для фізики, але краще взагалі уникати використання FixedUpdate. Чому? Update викликається FPS-рівну кількість разів і збільшення навантаження просто буде просаджувати швидкість рендеринга ривками. Це не страшно, тому що всі апдейти повинні вестися з урахуванням Time.deltaTime. FixedUpdate виконується рівну кількість разів в секунду і движок чекає завершення виконання. В результаті гру буде візуально смикати при нерівномірному обчислювальної навантаженні в FixedUpdate.
2. Не використовувати new (типу new Vectro3 (x, y, z), new Rect ()) в циклах і часто викликаються місцях
3. CompareTag більш ніж удвічі швидше прямої перевірки тега по імені.
4. (thisTransform.position - target.position) .sqrMagnitude швидше Vector3.Distance
5. Робіть якомога менше викликів thisTransform.forward або position, краще ці значення один раз отримати в Update, і використовувати у всьому скрипті. Це стосується будь-яких готових властивостей MonoBehaviour, включаючи сам transform. Відчуття, що вони завжди виходять вибором зі списку компонентів, без кешування - його потрібно робити руками. Все вектора в глобальному просторі (forward, right, up і т.п.) завжди переобчислюють при кожному зверненні до них по ієрархії GameObject - треба прочитати один раз і використовувати в поточному коді.
6. Для включення скрипта на об'єкті при можливості використовувати не GetComponent (.) .enabled із заздалегідь відключеним скриптом, а AddComponent (.)
при заздалегідь не повішеним скрипті на об'єкті

7. Використання статичних змінних

Розглянемо кілька прикладів:

В даному варіанті foo буде динамічно визначено, таким чином виклик функції DoSomething триває довше ніж потрібно, тому що тип foo невідомий, і спочатку потрібно з'ясувати, чи підтримує foo функцію DoSomething, і якщо підтримує те викликати її.

Тут foo у нас має певний тип. Продуктивність в даному випадку буде набагато краще.

8. Використовуйте #pragma strict

Звичайно, зараз проблема полягає в тому, що ви зазвичай не помічаєте використання динамічної верстки. #pragma strict зможе вам допомогти. Просто додайте в початок коду #pragma strict і Unity відключить динамічну верстку в даному скрипті, змушуючи вас використовувати статичну. Там де тип буде невідомий, Unity повідомить нам про помилки компіляції. В цьому випадку foo видаватиме помилку на етапі компіляції:

9. кешування пошук компонентів

Ще однією оптимізацією є кешування компонентів. На жаль, ця оптимізація вимагає невеликих зусиль кодинга і не завжди варто цього. Але якщо ваш скрипт дійсно часто використовується і вам не зайвим було б підвищення продуктивності, то це буде дійсно непогана оптимізація.

Всякий раз коли ви отримуєте доступ до компоненту через GetComponent або засобом доступу змінної, Unity повинен знайти потрібний компонент з ігрового об'єкта. Час на пошук можна легко скоротити якщо використовувати кешування посилання на компонент в приватній (private) змінної.

Просто перетворіть цей код:

Останній варіант буде працювати набагато швидше, так як Unity не потрібно шукати компонент Transform в ігровому об'єкті кожен кадр.
Теж саме стосується для скриптових компонентів, де ви використовуєте GetComponent замість transform або інших змін властивостей.

10. Використовуйте вбудовані масиви

Вбудовані масиви мають дуже високу швидкість роботи, намагайтеся використовувати їх коли це можливо. Хоч ArrayList або класи масивів набагато простіше використовувати, так як в них легше виробляти додавання елементів, швидкість роботи у них нижче. Вбудовані масиви мають фіксований розмір, але в більшості випадків розмір відомий нам з самого початку, і ми можемо в будь-який момент заповнити його. Одним з найважливіших достоїнств вбудованих масивів є те, що вони безпосередньо включають типи даних struct в один сильно упакований буфер, без будь-якої додаткової інформації про тип або накладних витрат. Таким чином, здійснювати інтеракції на кеші дуже легко, так як в ньому все вирівняно.

11. Не робіть виклик функції, якщо без цього можна обійтися

Найпростіший і кращий спосіб оптимізації - це здійснювати якомога менше зайвої роботи. Наприклад, коли ворог далеко від нас, найкращим буде зробити так, щоб він «заснув». Тобто не здійснював ніяких дій поки гравець не підійде ближче. Ось повільний варіант реалізації цього випадку:

Це не найбільш вдала ідея, так як Unity повинен викликати update функцію постійно, а значить ми виконуємо зайву роботу кожен кадр. Найкращим рішенням в даному випадку буде відключення програми ворога, поки гравець не підійде ближче. Існує 3 способи реалізації цієї ідеї:

1) Використовувати OnBecameVisible і OnBecameInvisible. Ці виклики закладені в системі промальовування. Як тільки якась камера бачить об'єкт, викликається OnBecameVisible, коли жодна камера не бачить його, робиться виклик OnBecameInvisible. У деяких випадках це виправдано, але іноді це проблематично для AI, так як вороги стають неактивними, коли ви відхиляєте від них камеру.

2) Використовуйте тригери. Простий кулястий тригер області може творити чудеса. При виході з обраної нами області впливу ми отримуємо виклики OnTriggerEnter / Exit.

3) Використовуйте Coroutines. Головним недоліком Update є те, що він виконується кожний кадр. Цілком можливим була б перевірка відстані до гравця кожні 5 секунд. Це б непогано підвищило продуктивність.

Не застосовувати препарат об'єкти з Rigidbody?) Може бути, Ви хотіли сказати "Намагайтеся не використовувати об'єкти з Rigidbody не в режимі isKinematic"? Тому що не використовувати Rigidbody взагалі не можна, якщо у тебе на об'єктах колайдери і вони (об'єкти) рухаються. Нестатичних коллайдер МОЖНА рухати без Rigidbody. Інакше ви якраз ту саму горезвісну продуктивність вб'єте геть.
Наприклад, в тому ж 2dToolkit Rigidbody є практично на кожному елементі інтерфейсу. Але, звичайно ж, на кожному з них виставлено прапор isKinematic. Продуктивність практично не змінює, зате все віджети можна безболісно рухати по екрану.
Звідси висновок: не бійтеся використовувати Rigidbody для нестатичних об'єктів з колайдера, тільки без фізики (ставте isKinematic).

І взагалі, якщо вже говорити про продуктивність в скриптах, то про JS треба забути. Використовуйте C # - тут набагато більший простір для оптимізації, та й розробнику дабтся більш потужні механізми ООП (якщо він, звичайно, вміє їх використовувати).

Останнє з форуму

Appfoxapp → Потрібно Unity розробник на віддалену роботу
Потрібно Unity розробник на віддалену роботу, в графіку 5-2 з 10.00 до 19.00 п.

proxyan → Сервіс PROXYAN.net - купити надійні серверні проксі, швидкі HTTP / SOCKS
Акція! Активуй при оплаті промокод 6DCEBF5601DF48B7 і отримай знижку 5%. Акція дійства.

dimaCyberpunk → Гра в розробці: Chronicles of cyberpunk
Технічна частина розробки закінчена, гру можна пройти від початку до кінця. Залишилось тільки.

ZARR → мотивовані установки андроїд додатків
Сервіс для розробників андроїд додатків, пропонує найдешевші мотивовані установки.

KregHEK → Silone - online PvP TBS (в розробці - версія dev10, озвучка, багаторівневі перкі)
Реліз dev9 (Побудова)! - Введено ударна бойова група і резерв. - Додано новий клас -.

kysovue → Комплексний прогін сайтів ru і en
Акція! Всім привіт, з 12.10.17 по 15.10.17 знижка -30% на будь-який пакет, прошу відразу.

Наші друзі