Unity 4 — трудности перехода и одна странная ошибка

Недавно мне пришлось совершить перенос одного игрового проекта  c версии «три и пять» на Unity 4. Переход можно назвать «условно неудачным». Неудачным, потому что пришлось делать откат назад к версии 3.5. Условным, потому что проблемы, которые появились в «четверке», каким-то волшебным образом перенеслись и в старую версию.Начну с небольшой проблемы. При переезде сломался код, который импортировал ресурсы и конвертировал их в Unity. Дело в том, что игра основывалась на другой игре, сделанной под Flash. Графика переносилась из Flash путем хитрой маркировки старых ресурсов, утилиты на AIR, которая растеризовывала векторные анимации в текстуру и экспортировала метаданные в виде XML, и Unity-импортера, который при обработке текстуры читал соответствующий XML-файл и создавал необходимые префабы.

Этот код накрылся.

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

Unity 4 принесла новые интересные фичи, например, API для подключаемых шрифтов. Но переходить на нее, когда в проекте уже много кода и с этим кодом предстоит еще дальше работать категорически нельзя. В моем случае проблемы вылезли не сразу после преобразования, а спустя некоторое время, что сделало откат более проблематичным.

Еще одна интересная «магия» обнаружилась в том, как Unity подготавливает код библиотеки LitJSON для iOS. LitJSON — это очень простая библиотека для записи/чтения JSON. Я использовал ее как альтернативу штатному XML, потому что XML не поддерживается в iOS, если включить максимальный iOS Stripping Level. Библиотека стабильно работала на протяжении всей разработки и после перехода на Unity 4, но начала падать случайным образом после того, как в проекте добавилась работа с Game Center.

Падения несли поистине странный характер — все прекрасно работало в редакторе Unity, но начинало выдавать чудеса при работе под iOS. Например, условие:

if (type == JsonType.Long)

при том что переменная type имела значение JsonType.Array (разные значения), выдавало true. Или код:

foreach (object elem in (IList)obj)

вызывал метод ToString() у объекта obj (который возвращал строку, которая реализует IEnumerable<char>, или что-то подобное) — в результате все приложение падало.

Первые мысли — в Unity 4 что-то недотестировали в Mono (они ведут собственную ветку Mono на GitHub), что привело к порче адресации вызовов методов. Очень странно было то, что заменив в коде перечисление JsonType на обычный int первая проблема исчезла, но воявилась вторая. Еще более удивительно было то, что при возврате назад на Unity 3.5.7 эта проблема не исчезла. Т.е. это что-то фундаментальное внутри.

В проекте проблему устранил, переписав код библиотеки LitJSON. Убрал из него абстрактные интерфейсы (я все же думаю, что проблема именно с адресацией вызовов) и неявные преобразования типов — после этого падения приложения на iOS прекратились.

Естественно, я сформировал обращение в тех. поддержку Unity. Судя по полученному ответу, им не удалось воспроизвести проблему. Будем решать этот вопрос дальше — нужно подготовить для ребят другой билд, возможно сделать видео в котором эта ошибка воспроизводится. Это небыстрый процесс, как появятся результаты, я о них напишу.