2. О чём речь?
1. Почему Unity3D?
2. Влияние движка на пайплайн разработки.
3. Неожиданные технические проблемы и их решения.
4. Удобство Unity3D для подобных проектов.
3. О чём речь?
1. Почему Unity3D?
2. Влияние движка на пайплайн разработки.
3. Неожиданные технические проблемы и их решения.
4. Удобство Unity3D для подобных проектов.
Brace yourselves
Technical mumbo-jumbo is coming
18. Портирование с С++
• Семантика сохраняется, меняются только элементы синтаксиса.
• Кодовая база C++ не пропадает даром.
19. Расширяемость и препроцессинг
• Утилита командной строки обрабатывает ассеты перед сборкой.
• В редакторе обработка запускается из кастомного пункта меню.
20. Расширяемость и всё остальное
Расширения редактора могут быть
любой сложности и назначения.
У нас используются для:
● препроцессинга ассетов
● пакетной обработки графики
● отладки геймплея
● самых разных читов
● упрощения редактирования
● сборки DLC
● ...
23. Плагины и Asset Store
• Проверенные решения многих задач.
• Недорого/бесплатно.
• Легко интегрировать.
• О чём ещё мечтать?
24. Плагины и Asset Store: функциональность
Возможности
кроссплатформенног
о плагина
Требуемый функционал
Часть нужного
функционала недоступна
25. Плагины и Asset Store: настройка
Плагинам иногда требуется внести
изменения в конфигурацию приложения.
Они могут делать это автоматически и
удалять другие важные изменения.
Следите за ними и отдавайте
предпочтение ручной настройке.
1.
2.
3.
26. Плагины и Asset Store: настройка
Изменения в конфигурацию приложения
могут вноситься и на этапе сборки.
Редактор поочерёдно запускает все скрипты
Editor/PostProcessBuildPlayer*.
Затем вызывает все методы с атрибутом
PostProcessBuild (PostProcessBuildAttribute) в
порядке, указанном в скобках.
Изучите эти скрипты и методы, если
конфигурация внезапно поломалась.
27. Плагины и Asset Store: настройка
Чтобы результат выполнения
скрипта никто не попортил,
запускайте его последним
Ваш скрипт
Запредельный
порядок выполнения
28. Плагины и Asset Store: настройка
Некоторые плагины имеют
взаимоисключающие требования.
Решение - препроцессинг
конфигурационных файлов при
сборке под конкретную платформу.
29. Плагины и Asset Store: ограничения Android
UserProfile.java
MainActivity.java
economics.jar
.class
.class
classes.dex classes.dex
Game.apk
N
methods
M
methods
K
methods
S = N + M + K + ...
● S < 63000: OK.
● S > 65536: Ошибка сборки APK в Unity.
● 63000 < S <= 65536: FFFFUUUUU~!!
30. Плагины и Asset Store: ограничения Android
Выпилить лишние SDK:
+ Максимально просто
- Эффективно “до следующего раза”
- Лишние? Мне всё нужно!
Выпиливать SDK в зависимости от
платформы:
• Относительно просто
• Относительно эффективно
- Легко облажаться
Multidex:
+ Решит проблему, сохранив SDK
- Экспорт проекта Android Studio
- Лишнее остаётся в APK
ProGuard:
+ Максимально эффективно
- Экспорт проекта Android Studio
- Требует настройки
31. Плагины и Asset Store: поддержка
В плагинах нередки баги.
Поддержка и фиксы остаются на
совести автора плагина.
Фиксить баги самому мешает
закрытый исходный код.
Сообщество пользователей, как
правило, невелико.
32. Редактор: стабильность и производительность
Редактор иногда падает. В новых
версиях реже.
Иморт/экспорт ассетов в один поток -
долго. Облегчат жизнь:
• SSD
• Ramdisk
• Десятки тысяч долларов на
крутую билд-машину
33. Редактор: MonoDevelop
• Долго перезагружает проект после внешних изменений.
• Иногда портит отступы в коде.
• Дебаггер не всегда подключается.
• Отладочная информация не всегда релевантна.
Не повод отказываться от любимого текстового редактора,
но может быть полезна для отладки в ряде случаев.
34. Редактор: threading
• Симуляция игры происходит в UI thread редактора.
• Ошибка в скрипте может “повесить” Unity.
• Запуск на устройстве даст больше информации о причине зависания.
• Panic Button plugin прервёт любой скрипт в редакторе.
35. Редактор: конфликты версий
Если работать над проектом в
разных версиях Unity, некоторые
файлы спонтанно меняются.
Это ведёт к конфликтам при
слиянии.
Держите всех на одной версии
редактора.
39. Компилятор и runtime: Garbage collection
• Сборка мусора работает плохо.
• Производительность игры со временем снижается.
• “Ручного управления” освобождением памяти нет.
40. Компилятор и runtime: Garbage collection
ReferenceType
class Entry {
uint id;
long phone;
string name;
}
Thread stack
var e1 = new Entry();
var e2 = e1;
Managed heap
ref1
Entry
id: 1337
phone: 88005553535
name: ref2
String
value: “Ayy Lmao”
ref3
42. Компилятор и runtime: Garbage collection
Нужно снижать число аллокаций:
• меньше временных объектов, аллоцируй
однажды и переиспользуй;
• ValueType вместо ReferenceType, где уместно;
• гибридные контейнеры. refactor
43. Компилятор и runtime: Garbage collection
struct HList<T> : IList<T>
гибридный контейнер
T val0;
T val1;
T val2;
T val3;
List<T> fallback; T TT ...
myHList.Add(newVal);
Count >
Capacity?
True,
alloc fallback
once
False,
no allocs
44. Компилятор и runtime: Garbage collection
Встроенные возможности языка много
аллоцируют. Зона риска:
• foreach;
• using;
• Array.IndexOf и т.п.;
• “Excessive” + “ strings “ + “concat”;
• …
• твоя киска
Можно придумать неаллоцирующие замены.
45. Компилятор и runtime: Garbage collection
Boxing
здорового человека
Boxing C#-программиста
struct Entry : IPrintable
Thread stack
var e1 = new Entry();
Entry
Managed heap
void MyCustomPrint(IPrintable p)
Object (boxed Entry)
IPrintable toPrint = e1;
MyCustomPrint(toPrint); IPrintable ref1
Неявная аллокация
46. Компилятор и runtime: повреждение стека
При передаче крупных структур по
значению возможно повреждение
стека.
Закономерность не установлена.
Решение - передавать их по
ссылке.
Unity call stack be like:
i == 2 i == 2 i == 2 i == -97
47. Компилятор и runtime: креши UnityPlayer
WindZone + UnloadUnusedAssets() =
падение самого UnityPlayer на iOS.
Соотнести причину со следствием
было очень сложно.
Пришлось отказаться от WindZone.
UnityPlayer? More like UnityPrayer!
50. Компилятор и runtime: жизнь без JIT на iOS
Весь код должен быть виден и понятен среде выполнения при запуске:
• Generics + Reflection = butthurt;
• Generics + Native code = butthurt;
• Delegates + Native code = butthurt;
...
Страница “Troubleshooting on iOS devices” - ваш друг и помощник.
51. Компилятор и runtime: жизнь без JIT на iOS
C#
JS
US
CIL
CIL
CIL
Sources Script compiler Mono runtime
JIT
AOT
dlldll
C++ Native binary
scripting backend: Mono
scripting backend: IL2CPP
Попытка использовать
JIT ведёт к
ExecutionEngineException
При попытке
использовать JIT не
происходит НИЧЕГО
DLL, собранные другим
компилятором, не знают,
что JIT недоступен
52. Компилятор и runtime: жизнь без JIT на iOS
• “Chat ConnectAsync…” выводится
• “Chat Connecting…” - нет.
Диагностика:
• Переключить Scripting backend на Mono
и словить ExecutionEngineException.
Решения:
• Использовать исходники вместо DLL.
• Собрать DLL компилятором Unity.
53. Компилятор и runtime: жизнь без JIT на iOS
Workaround для проблемы с DLL:
• объявлять операции
add/remove у event явно.
+ Все компиляторы будут
генерить одинаковый байткод.
- Код становится менее
компактным.
- Про это каждый раз надо
помнить.
60. Зона видимых объектов
Оптимизация графики: depth buffer
Far Clip Plane
Near Clip Plane
Здесь ничего
не рендерится
Здесь ничего
не рендерится
61. Оптимизация графики: depth buffer
Слишком широкий диапазон,
низкая точность.
Разрядность буфера зависит
от GPU, на ряде устройств
появляется Z-fighting.
OK!
Слишком узкий
диапазон, отсекается
больше, чем нужно
63. Сообщество: Unity Answers
• Огромная численность.
• Преобладание начинающих
разработчиков.
• Много странных вопросов.
• Много ответов на простые
вопросы.
• Мало ответов на сложные
вопросы.
2006: 2016:
The impact of Unity Answers
64. Сообщество: участие Unity Technologies
• Движок активно поддерживается.
• Сообщество активно обсуждает релизы и использует issue tracker.
• Представители Unity Technologies принимают участие в обсуждениях.
• Графон всё лучше.
• Развиваются веб-сервисы для Pro-пользователей (аналитика, crash
reporting).
65. TL;DR: Unity норм
• Unity - это внушительный набор средств для разработки.
• Бинарные ассеты - отстой, храните больше в текстовом виде.
• Скриптуемость и расширяемость редактора - это очень круто.
• There’s a [bad] plugin for that.
• Отлаживать код не всегда удобно, используйте логи.
• Аллокации - зло.
• Желательно понимать, что там под капотом.
• Учитывайте специфику мобильных устройств при оптимизации.
• На сообщество надейся, а сам не плошай.
Несмотря на подводные камни, достоинства перевешивают недостатки.