Unity фоновый режим android

Как получить сообщение, когда приложение находится в фоновом режиме? (Android, Unity, GCM)

У меня большой опыт работы с Unity и iOS, и я могу развернуть свое приложение Unity на Android. Но я ничего не знаю о нативном Android.

Моя проблема заключается в получении сообщения GCM и отображении уведомления, когда приложение Android находится в фоновом режиме. Я реализовал его, и он отлично работает, когда приложение находится на переднем плане, но мой прослушиватель сообщений GCM не запускается, когда приложение находится в фоновом режиме, и я не могу показать уведомление.

Я пытался связаться с авторами этих плагинов, но они долго не отвечали .

2 ответа

Я решил свою проблему, используя плагин «Android Native» от StansAssets в магазине ресурсов. С его реализацией устройство Android показывает уведомление, когда приходит облачное сообщение, даже если приложение находится в фоновом режиме. При нажатии на уведомление открывается приложение.

Возможно, вам будет интересна концепция автобуса для мероприятий. Я постараюсь показать вам пример, хотя раньше я никогда не использовал его с уведомлениями. Я буду использовать сообщения Toast в качестве замены, так как это то, что мне удобно.

Идея довольно проста в том, что любой объект ( activity ) может «ездить на автобусе»:

Вам нужны методы подписчика для запуска, когда шина «пищит» (издает событие):

То, когда объекту необходимо высадить автобус:

Кроме того, чтобы автобус действительно «пищал»:

Это вызывает вызов метода onEvent(NotificationEvent event) в каждом объекте, который находится на шине. Вы можете добавить различные методы подписчика (например, onEvent(LocationEvent event) ), и этот метод будет запускаться только при генерировании события одного и того же типа bus.post(new LocationEvent()) Нет ограничений на количество объектов, которые могут быть зарегистрированы на шине.

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

Источник

Руководство по фоновой работе в Android. Часть 1

О фоновой работе приложений в Android есть много статей, но мне не удалось найти подробного руководства по реализации работы в фоне – думаю, из-за того, что появляется все больше новых инструментов для такой работы. Поэтому я решил написать серию статей о принципах, инструментах и методах асинхронной работы в приложениях под Android.

Будет несколько частей:

  1. Основной поток, осуществление фоновой работы с помощью AsyncTask, публикация результатов в основном потоке.
  2. Затруднения при использовании AsyncTask. Loaders как один из способов их избежать.
  3. Работа в фоне с помощью ThreadPools и EventBus.
  4. RxJava 2 как метод асинхронной работы.
  5. Корутины в Kotlin как метод асинхронной работы.

Начнем с первой части.

Основы UI

Первое, что следует понять, – почему мы вообще беспокоимся о работе в фоне в мобильных приложениях.

Во всех приложениях для Android есть хотя бы один поток, на котором происходит прорисовка UI и обработка пользовательского ввода. Поэтому он и называется потоком UI или главным потоком.

Каждый метод жизненного цикла каждого компонента вашего приложения, включая Activity, Service и BroadcastReceiver, исполняется на UI-потоке.

Человеческий глаз преобразовывает сменяющиеся изображения в плавное видео, если частота смены достигает 60 кадров в секунду (да, это магическое число берется отсюда), давая основному потоку только 16 мc для прорисовки всего экрана.

Продолжительность сетевого вызова может быть в тысячи раз больше.

Когда мы хотим загрузить что-либо из Интернета (прогноз погоды, пробки, сколько стоит ваша часть биткоина в данный момент), мы не должны делать это из главного потока. Более того, Android не позволит нам, выбросив NetworkOnMainThreadException.

Семь лет назад, когда я разрабатывал свои первые приложения на Android, подход от Google был ограничен использованием AsyncTasks. Давайте посмотрим, как мы писали код для общения с сервером (псевдокод преимущественно):

Метод doInBackground() гарантированно будет вызван не на основном потоке. Но на каком? Зависит от реализации. Вот как Android выбирает поток (это часть исходного кода класса AsyncTask):

Здесь можно увидеть, что выполнение зависит от параметра Executor. Посмотрим, откуда он берется:

Как здесь указано, по умолчанию executor ссылается на пул потоков размера 1. Это означает, что все AsyncTasks в вашем приложении запускаются последовательно. Это не всегда было верно, так как для версий ОС от DONUT до HONEYCOMB использовался пул размером от 2 до 4(в зависимости от количества ядер процессора). После HONEYCOMB AsyncTasks снова выполняются последовательно по умолчанию.

Итак, работа выполнена, байты закончили свое длинное путешествие с другого полушария. Нужно превратить их во что-то понятное и разместить на экране. К счастью, наша Activity тут как тут. Давайте поместим результат в одно из наших View.

О, черт! Опять исключение!

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Но мы не делали никаких сетевых обращений на основном потоке! Правильно, но мы попытались нарушить другой закон UI. Пользовательский интерфейс можно менять только из UI-потока. Это верно не только для Android, но и практически для любой системы, с которой вы столкнетесь. Причину этого хорошо объяснили в Java Concurrency In Practice. Вкратце – архитекторы хотели избежать сложной блокировки при изменениях из нескольких источников (пользовательский ввод, биндинг и другие изменения). Использование единственного потока решает эту проблему.

Да, но UI все равно нужно обновлять. У AsyncTask есть еще метод onPostExecute, который вызывается на UI-потоке:

Как эта магия работает? Посмотрим в исходном коде AsyncTask:

AsyncTask использует Handler для вызова onPostExecute в UI, ровно как и метод postOnUiThread в компонентах Android.

Handler прячет всю внутреннюю кухню. Какую именно? Идея состоит в том, чтобы иметь бесконечный цикл проверки сообщений, приходящих на UI-поток, и обрабатывать их соответствующе. Велосипедов тут никто не изобретает, хотя без кручения педалей не обошлось.

Для Android это реализовано классом Looper, который передается в InternalHandler в приведенном выше коде. Суть класса Looper находится в методе loop:

Он просто опрашивает очередь входящих сообщений в бесконечном цикле и обрабатывает эти сообщения. Это означает, что на UI-потоке должен быть инициализированный экземпляр Looper. Можно получить доступ к нему с помощью статического метода:

Читайте также:  Восстановить данные ватсап с андроида как

Кстати, вы только что узнали, как проверить, вызывается ли ваш код в UI-потоке:

Если вы попытаетесь создать экземпляр Handler в методе doInBackground, то получите другое исключение. Оно сообщит о необходимости наличия Looper для потока. Теперь вы знаете, что это значит.

Надо заметить, что AsyncTask может быть создан только в UI-потоке по указанным выше причинам.
Вы можете подумать, что AsyncTask – это удобный способ выполнения фоновой работы, так как он скрывает сложность и требует немного усилий при использовании, но есть несколько проблем, которые приходится решать по пути:

  • Каждый раз нужно писать достаточно много кода для решения относительно простой задачи
  • AsyncTasks ничего не знают о жизненном цикле. При неправильном обращении лучшее, что вы получите — утечка памяти, в худшем – сбой
  • AsyncTask не поддерживает сохранение состояния прогресса и повторное использование результатов загрузки.

В следующей части я подробно разберу эти проблемы и покажу, как Loaders могут помочь их решить.

Источник

Практическое руководство по оптимизации для мобильных

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

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

Мобильные устройства не созданы одинаковыми

Информация здесь предполагает аппаратное обеспечение на уровне чипсета Apple A4, который используется в оригинальных iPad, iPhone 3GS и третьем поколении iPod Touch. Из Android предполагается устройство подобное Nexus One, или большинства устройств, работающих на Android 2.3 Gingerbread. В основном, эти устройства были выпущены в начале 2010 года. Эти устройства старее, медленнее современных, но так как они составляют большую часть рынка, их также следует поддерживать.

Есть очень быстрые и очень медленные телефоны. Вычислительные мощности мобильных устройств растут с потрясающей скоростью. Для нового поколения мобильной GPU, быть в 5 раз быстрее своего предшественника — обычное дело. Скорость мобильных устройств уже сравнима со скоростью ПК.

Для обзора технических характеристик мобильных устройств от Apple, см. Hardware.

Если вы хотите разрабатывать под мобильные устройсва, которые станут известными в будущем, или эксклюзивные high end устройства прямо сейчас, вы можете это сделать. См. Мобильные устройства будущего.

Очень низкая производительность (например, iPhone 3G или первое и второе поколение iPod touches) требует особого внимания к оптимизации. В противном случае могут возникнуть проблемы когда покупатели, не обновившие устройства, будут покупать ваши приложения. Если же вы делаете бесплатное приложение, можно не беспокоится о поддержке старых устройств.

Оптимизацию не следует считать последней стадией разработки проекта

Британский ученый Майкл А. Джексон часто цитируется своими Правилами оптимизации программ:

_Первое правило оптимизации программы: не делаете ее. Второе правило оптимизации программы (только для экспертов!): не делайте ее пока что.

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

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

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

Оптимизация: Не только для программистов

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

  • На художника ложится большая ответственность. Если дизайн игры предполагает атмосферность и освещение, их можно нарисовать в текстурах вместо запекания.
  • Каждый раз, когда что-либо может быть запечено, художники могут готовить контент для выпекания, вместо рендеринга в реальном времени. Это позволяет им игнорировать технические ограничения и работать свободно.

Планируйте игру так, чтобы во время исполнения она работала “плавно”.

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

Профилируйте на ранней стадии и почаще

Профилирование важно, потому что оно поможет выяснить, какие оптимизации действительно приведут к большому приросту производительности, а какие являются пустой тратой вашего времени. Благодаря тому, что рендеринг обрабатывается на отдельном чипе (GPU), отрисовка одного кадра занимает в два раза меньше времени (только GPU, а не CPU + GPU). Это означает, что если CPU замедляет работу, оптимизация ваших шейдеров вообще не повысит частоту кадров, и если GPU замедляет работу, не помогут оптимизация физики и скриптов.

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

Внутренний Профайлер

Профайлер в Unity в основном используется при ориентации на iOS и Android. См. Руководство по профайлеру для основных инструкций по его использованию.

Внутренний Профайлер

Внутренний профайлер выкидывает текст каждые 30 кадров. Это поможет вам выяснить, какие аспекты вашей игры замедляют ее, будь то физика, скрипты, визуализация, но без множества деталей (например, только название скрипта или визуализации).

См. Встроенный Профайлер для подробной информации о том, как это работает и включается.

Источник

Оптимизация 2d-приложений для мобильных устройств в Unity3d

Возможно все!

Начну с того, что каждый раз, когда я приступаю к оптимизации, я поначалу не верю, что можно что-то еще оптимизировать, особенно если проект уже прошел несколько циклов оптимизации до этого. Но просмотр официальной документации Unity, тем на форумах, статей в Интернете наводит меня на мысль о новых возможных улучшениях. Таким образом я веду специальный список, в котором записаны основные идеи по тому, что можно оптимизировать в проекте на Unity, постоянно обновляю его и первым делом обращаюсь к нему, когда речь заходит об оптимизации. Этими идеями я хочу с Вами поделиться. Надеюсь, статья поможет Вам сделать Ваш проект намного более шустрым.
Сразу обозначу, что разработка велась на Unity 3.5.6, целевая платформа — устройства Apple от iPhone 3GS и новее.

Читайте также:  Farengeight android 4 pda

Базовые правила

Для начала приведу несколько правил, которыми я пользуюсь при разработке и оптимизации.
1. Не оптимизируйте заранее.
Это золотое правило должно быть знакомо всем, кто когда-либо занимался оптимизацией. Вспомним правило 80/20: 80% пользы получается от 20% работы.

Цифры довольно условны, но я имел ввиду вот что: наиболее вероятно, что большая часть оптимизаций, которые Вы собираетесь сделать на начальном этапе проекта, скорее всего вообще никак не повлияет на конечный проект в целом.

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

  • Допустим, есть код, или конструкция, которую вы уже сейчас знаете, как написать лучше, с меньшей затратой по памяти/процессора и тд. Вы об этом знаете по своему опыту, потому что не раз оптимизировали компоненты подобного рода, и знаете, что это приводит к увеличению производительности. Так почему бы уже сейчас не написать ее правильно? Обычно такие вещи складываются в свод правил типа «как правильно писать код, и как писать не надо», и грамотный программист постоянно им пользуется во избежание ошибок в будущем. Нечто подобное имеет место для художников, дизайнеров и тд.
  • Если есть действие, которое будет повторяться много раз, и с самого начала можно его оптимизировать, почему бы это не сделать сразу. Дальше все будет идти автоматом, и не нужно будет исправлять одну и ту же вещь несколько раз. Сюда относятся, например, вспомогательные скрипты, помогающие дизайнерам ускорить однообразную работу с группой объектов.

2. Найдите то, что нужно оптимизировать.
Несколько лет назад я имел такую ситуацию: проходишься по коду, сценам и тд и оптимизируешь все, что только можно, а потом смотришь на производительность — это ошибка начинающего оптимизатора.
Для начала нужно найти то, что тормозит систему, на чем бывают скачки производительности. В этом очень сильно помогает профайлер. Конечно, он довольно условен и сам немного нагружает систему, но польза от него неоспорима! В Unity Pro есть встроенный пройфалер, довольно удобный. Но если у Вас обычный Unity, можно использовать профайлер xCode, или любой другой подходящий. Профайлер помогает находить наиболее нагружающий код, показывает используемую память, насколько звуки грузят систему, кол-во DrawCall на конечном устройстве и тд. Таким образом, прежде чем оптимизировать, прогоните приложение через профайлер. Думаю, Вы много чего нового узнаете о своем проекте)

Что мне помогло решить проблему с производительностью?

Еще до прогона через профайлер было очевидно, что слабое место — в кол-ве Draw Calls. В среднем сцена выдавала порядка 70 DrawCalls, что для устройств уровня iPad1 и ниже является фатальным. Нормально для них — 30-40 Draw Calls. Посмотреть кол-во Draw Calls можно прямо в редакторе в окне Game->Stats:.

Кол-во Draw Calls, показываемых в редакторе, совпадает с таковым на конечных устройствах. Профайлер это подтвердил. Вообще, очень полезно смотреть эту статистику, и не только программистам, но и дизайнерам, для нахождения «тугих» мест в игре.
В наших сценах плохо работало группирование нескольких Draw Calls для одного и того же материала в один Draw Call. Это называется Dynamic Batching. Я начал рыть на тему «как понизить кол-во Draw Calls и улучшить их группирование». Ниже перечислены основные правила, придерживаясь которых, можно получить приемлемое количество Draw Calls. Вот те, которые мне очень сильно помогли:

1. Использовать атласы для комбинирования нескольких текстур в одну большую.
На самом деле важнее даже, чтобы спрайты/модели использовали не то что бы одну общую текстуру, а скорее один общий материал. Именно в кол-ве различных материалов измеряется кол-во Draw Calls (в идеальном случае). Поэтому у нас в проекте используемые изображения всегда объединены в атласы, разбитые на категории: объекты, используемые на всех сценах, объекты GUI, задний фон и тд. Вот пример такого атласа:

Такое разбиение так же будет полезно в будущем для применения к текстурам различных настроек. Но об этом позже.

2. Не стоит изменять Transform->Scale.
Объекты с измененным Scale попадают в отдельную категорию, увеличивающую кол-во Draw Calls. Я заметил это, когда еще раз проходился по документу Draw Call Batching. Вот что значит перечитывать;) Пройдясь по сцене, я обнаружил огромное количество таких объектов:

  • Оказалось, что дизайнеры уже давно увеличили некоторые часто используемые объекты в 1.2 раза через Scale прямо в прифабе объекта. В итоге, мы пришли к решению увеличить их размер прямо в текстуре. Это к тому же соблюдало условие пиксель-в-пиксель, что очень важно для 2d-игры.
  • Были объекты, которые имели одно и то же изображение, но разный Scale. Для таких объектов был написан специальный скрипт, который переводил нужный Scale с Transform прямо на меш, используемый для спрайта, т.е. менял размер меша и оставлял Scale = (1, 1, 1).
  • Также Scale часто использовался у нас для отражения объекта, например, Scale.x = -1 отражает объект слева направо. Все такие скейлы были заменены на соответствующие им повороты.
  • Еще у некоторых объектов Scale был изменен в анимации, пару раз неоправданно. Не забывайте проверять анимации, часто изменения в них — неявные, и могут быть обнаружены только после запуска.

В результате устранения практически всех изменений Scale удалось снизить кол-во Draw Call практически вдвое! Правда, эти улучшения заняли у нас порядочное время, поэтому стоит помнить о Scale уже на начальном этапе дизайна уровней. И теперь в Памятке дизайнерам у нас жирным шрифтом красным цветом написано: Старайтесь избегать изменения Scale.

Еще несколько подсказок (взятых в том числе из документа Unity), как сократить количество Draw Calls:

  • Статические объекты могут быть помечены как Static. Тогда будет использоваться Static Batching (только в Pro-версии), который тоже поможет сократить кол-во Draw Calls.
  • Старайтесь использовать объекты с одним и тем же материалом на одном и том же расстоянии от камеры. Пример: у нас различия по расстоянию в 10 юнитов уже давали 1-2 дополнительных Draw Call. При этом какая-то особая закономерность выявлена не была, но я подозреваю, что есть связь между размерами камеры, размерами объектов, их расстоянием до камеры и количеством Draw Calls. Экспериментируйте!
  • Старайтесь, чтобы объекты с разными материалами не перекрывали друг друга. Это тоже увеличивает кол-во Draw Call, особенно для полупрозрачных объектов.
  • Многопроходные (multi-pass) шейдеры увеличивают количество Draw Call. У нас таких не было, но полезно будет учесть это в будущем.
  • Каждая система частиц дает 1 Draw Call. (Имеется ввиду старая система частиц Unity 3.5.6, используемая нами по сей день. Как обстоят дела в Unity 4, я не знаю). Поэтому если на экране одновременно N систем частиц — это автоматически как минимум N Draw Calls. Обычно, одного и того же эффекта можно достигнуть разными способами, в том числе меньшим числом как систем частиц, так и частиц в системе. Часто видел, как начинающие дизайнеры эффектов используют огромное кол-во частиц (и огромный размер самих частиц), чтобы создать вау-эффект. При этом они не думают о производительности (особенно учитывая, что все это делается в редакторе на PC) и обычно достаточно меньшего количества частиц, чтобы достичь того же эффекта.
Читайте также:  Как сменить пароль точки доступа андроид

Скачки производительности

Второй фактор, влияющий на производительность — так называемые скачки производительности. Порою в игре были «зависания» на 0,5-1 секунду, что конечно же было неприемлемо и напрямую влияло на геймплей. Причем такое наблюдалось даже на самых последних устройствах.
И в этом случае помог профайлер! Вот список правил для уменьшения скачков производительности:

1. Старайтесь не использовать Instantiate(), особенно для сложных объектов.
Скачки производительности приходились в основном на вызовы Instantiate(), которые создавали новые объекты из прифабов, или клонировали существующие. Причем некоторые объекты были очень громоздкими, что и повлияло на время их создания. Вместо этого пришлось переписать систему так, чтобы объекты использовались заново. Т.е. состояние объекта после окончания использования (или перед использованием) приводилось к начальному. Это также помогло сократить объем используемой памяти (так как на новые объекты больше не нужно было новой памяти) и количество вызовов Destroy().

2. Минимизируйте количество вызовов Destroy().
Destroy (особенно для больших объектов) почти всегда приводит к манипуляциям с памятью. А это обычно плачевно сказывается на производительности. Это правило напрямую связано с правилом выше, ибо вызовы Instantiate()/Destroy() обычно связаны. Таким образом, использование объектов заново лишило необходимости уничтожать их.

3. Минимизируйте вызовы gameObject.SetActiveRecursively().
Для сложных объектов вызов может быть очень долгим, потому что он предполагает не просто активацию объектов и их компонентов, но в некоторых случаях и загрузку необходимых ресурсов.

4. Минимизируйте вызовы Object.Find().
Думаю, не стоит объяснять, что время этой операции зависит от кол-ва объектов на сцене. Сюда же относятся функции типа GetComponent().

5. Минимизируйте вызовы Resources.UnloadUnusedAssets() и GC.Collect().
Unity иногда сама прибегает к ним, если недостаточно памяти для загрузки нового ресурса или пришел запрос от ОС освободить неиспользуемую память. Таким образом, первые 2 правила автоматически сокращают кол-во таких вызовов. Лучшее место для вызова Resources.UnloadUnusedAssets вручную — перед загрузкой сцены или непосредственно сразу после ее запуска. Это также поможет освободить дополнительную память для сцены, что иногда бывает критично. Соответствующий скачок производительности можно скрыть, например, экраном загрузки;)

Использование правил выше привело к устранению скачков производительности и намного более плавным геймплею и картинке.

Другие оптимизации

Далее привожу другие правила, которые могут помочь Вам. Большинством из них я сам пользовался на предыдущих этапах оптимизации.

Скрипты
  • Не используйте GetComponent<>() в Update, FixedUpdate и других подобных функциях. Вместо этого лучше кэшировать компонент в Awake() или Start(). Если объектов, использующих скрипт, очень много, такое кэширование может значительно сократить время работы скрипта.
  • Кэшируйте встроенные компоненты типа transform, renderer и тд. Особенно если они используются в функциях типа Update(). Ибо каждый такой вызов делается через GetComponent(). См. правило выше. Это можно сделать, например, так:
  • Используйте Vector2(3,4).sqrMagnitude вместо magnitude.
  • Используйте Color32 и Mesh.colors32 вместо Color и Mesh.colors при доступе к цветам меша.
  • Можно использовать OnBecameVisible/OnBecameInvisible для скриптов, которые могут быть отключены, когда камера больше не видит объект.
  • Используйте встроенные массивы. Имеются ввиду массивы типа T[]. Они намного быстрее всех остальных коллекций.
  • Отключите логи при работе приложения на устройстве. Обычно печать лога требует доступа к файловой системе, а если логов много, это может привести к печальным последствиям для производительности.
  • Отключите исключения. Как следствие — старайтесь не использовать их в коде. Отключение исключений поможет сохранить до 30% производительности. Но не забывайте, что если ошибка произойдет, и она не сможет быть обработана исключением — это падение приложения на устройстве. Поэтому приходится выбирать — либо хорошее тестирование и прирост производительности, либо надежность, но производительность чуть хуже. В случае, когда производительность удовлетворяет, преимущество лучше отдать второму варианту.

Физика
Анимации
Система частиц
Другое

Уменьшение размера приложения

Для чего это может понадобиться? Раньше это делалось потому, что приложения размером Archives даже появилась специальная кнопочка Estimate Size:

Все необходимое по уменьшению размера билда описано в документах Unity:

  • Player Size Optimization
  • Reducing File Size

Я же опишу здесь то, что использовал сам. Начнем с того, что влияет на производительность:

1. Используйте правильный формат текстуры.
Это также позволит уменьшить объем используемой текстурной памяти, а соответственно и повысить производительность. Иногда достаточно использовать формат текстуры 16 bits, особенно если вся графика нарисована всего в нескольких цветах. Сравните:

Для монотонных текстур можно использовать только ее серую и альфа-компоненту и лепить из них готовый объект, используя специально написанный для этого шейдер и умножение на цвет:

Для задников и нечетких объектов можно использовать компрессию. Сейчас PVRTC-компрессия на iOS довольно продвинутая. Стоит помнить, что чем больше текстура — тем лучше ее качество после компрессии. На маленьких текстурах использование компрессии может быть неприемлемым.
Чтобы это все имело смысл, нужно разделять объекты на группы типа «задний фон», GUI, игровые объекты, о чем я уже писал. Тогда на каждый тип можно завести свой атлас и использовать различные настройки формата текстуры.

2. Используйте правильный формат звуков.
Раньше я не задумывался об этом. Использование компрессии на звуках позволило мне не только сократить размер приложения, но и объем используемой им памяти. Сам я пользуюсь следующими правилами:

    Используйте Audio Format = Native для очень коротких и маленьких по размеру звуков (

Источник

Оцените статью