This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Прежде чем приступать к оптимизации игры с целью достичь стабильной высокой частоты кадров, нужно понять, где находятся узкие места. Что именно занимает наибольшее время в кадре вашей игры? Рендеринг? Логика игры? Сценовый граф? Чтобы это выяснить, рекомендуется использовать встроенные инструменты профилирования. Используйте экранный или веб-профайлер, чтобы проанализировать производительность игры и затем принять решение, что и стоит оптимизировать. После этого можно переходить к устранению проблем.
Снижение времени выполнения скриптов требуется, если профайлер показывает высокие значения в области Script
. В общем случае следует стараться выполнять как можно меньше кода в каждом кадре. Выполнение большого объёма кода в update()
и on_input()
в каждом кадре может сильно повлиять на производительность, особенно на слабых устройствах. Вот некоторые рекомендации:
Не опрашивайте состояние, если можно получить обратный вызов (callback). Не анимируйте вручную то, что можно поручить движку (например, используйте go.animate()
вместо ручной анимации).
Если вы создаёте много короткоживущих объектов (например, таблиц Lua) каждый кадр, это приведёт к частому срабатыванию сборщика мусора. Это может проявляться как небольшие задержки/скачки времени кадра. По возможности переиспользуйте таблицы и избегайте создания таблиц внутри циклов.
Если у вас много сообщений или событий ввода, рекомендуется заранее хешировать строки. Пример:
function on_message(self, message_id, message, sender)
if message_id == hash("message1") then
msg.post(sender, hash("message3"))
elseif message_id == hash("message2") then
msg.post(sender, hash("message4"))
end
end
В этом случае строка будет хешироваться каждый раз при получении сообщения. Лучше сделать так:
local MESSAGE1 = hash("message1")
local MESSAGE2 = hash("message2")
local MESSAGE3 = hash("message3")
local MESSAGE4 = hash("message4")
function on_message(self, message_id, message, sender)
if message_id == MESSAGE1 then
msg.post(sender, MESSAGE3)
elseif message_id == MESSAGE2 then
msg.post(sender, MESSAGE4)
end
end
Передача сообщений или обращение к игровым объектам/компонентам может выполняться через строку, хеш или URL. Строки и хеши будут преобразованы во внутренний URL. Поэтому лучше заранее кэшировать часто используемые URL. Пример:
local pos = go.get_position("enemy")
local pos = go.get_position(hash("enemy"))
local pos = go.get_position(msg.url("enemy"))
-- do something with pos
Во всех трёх случаях будет получена позиция игрового объекта с id enemy
. Однако в первом и втором случае строка или хеш будут сначала преобразованы во внутренний URL. Это означает, что для достижения наилучшей производительности лучше заранее кэшировать URL и использовать его повторно:
function init(self)
self.enemy_url = msg.url("enemy")
end
function update(self, dt)
local pos = go.get_position(self.enemy_url)
-- do something with pos
end
Снижение времени, необходимого для рендеринга кадра, требуется, если профайлер показывает высокие значения в областях Render
и Render Script
. Ниже приведены несколько аспектов, которые следует учесть при попытке ускорить рендеринг:
builtins/materials
), и снизить точность с highp
до, например, mediump
, что в некоторых случаях может немного повысить производительность на слабых устройствах.Это необходимо, если профайлер показывает высокие значения в области GameObject
, особенно в UpdateTransform
. Рекомендации:
disable
или enable
каждому объекту.Сценарий рендеринга может автоматически игнорировать объекты вне фрустума. Подробнее — в руководстве по Render Pipeline.
Android Dynamic Performance Framework — это набор API, позволяющих играм взаимодействовать с системами питания и температуры устройств Android. Это помогает отслеживать поведение системы и настраивать производительность игры на устойчивом уровне без перегрева устройства. Используйте расширение ADPF, чтобы отслеживать и оптимизировать производительность на Android.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB