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. Судя по полученному ответу, им не удалось воспроизвести проблему. Будем решать этот вопрос дальше — нужно подготовить для ребят другой билд, возможно сделать видео в котором эта ошибка воспроизводится. Это небыстрый процесс, как появятся результаты, я о них напишу.

  • TigraPolosatiy

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

    • Да, новый можно на Unity 4 начинать — есть шанс, что в «четверке» можно будет нормально со шрифтами работать штатными средствами

      • TigraPolosatiy

        ммм. это хорошо.
        Уще один вопрос, не в тему правда, меня интересует Возможно ли использовать рабочее пространство вне поля Terrain? или Unity ограничен только этой площадкой для игрового процесса?
        Хотелось бы сделать масштабный уровень 🙂

        • Я больше по части 2D — использую Unity как кросс-платформенное решение. Но не понимаю, какие есть ограничения в этом вопросе — разве нельзя использовать несколько Terrain? Или подгружать сцены через LoadLevelAdditive?

  • TigraPolosatiy

    Появились 2 проблемы =_=
    Первая связана со скайбоксом: на моих отрендеренных скайбоксах созданных в Terragen почему-то видно швы а на родных — нет. хотя с текстурами все в порядке и они подходят пиксель в пиксель.
    А вторая с тирейном: любые текстуры которые я размещаю на тирейне почему-то размываются. словно их разрешение 5х5 пикселей. Хотя на самом деле они 512р или даже 1024р. Пробовал пересоздавать тирейн — бесполезно.
    Если можно — ответьте в личку через facebook.