Как стать автором
Обновить

Как я адаптировал игру к экранам мобильных устройств

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров2.7K

Коротко расскажу историю процесса 

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

В процессе я получше познакомился с UI и как адаптировать его под различные размеры экранов, а так же немного погрузился в постобработку. Что, кстати, само по себе не решает проблем возникающих на некоторых экранах, если UI должен отображаться поверх объекта на сцене. Кнопочки и надписи то растянуть по размеру экрана и сохранить их местонахождение относительно всего экрана — не сложно. А вот чтобы при этом кнопка осталась поверх нужного объекта и все было хорошо, это надо попотеть. По крайней мере, если не делал ничего похожего и в целом опыта в разработке немного.

Я очень долго пробовал, пытался, искал. Мое виденье того, как должна выглядеть сцена постоянно менялось. Это сбивает с толку, потому что спустя несколько изменений сцены я перестал понимать как я хочу видеть все это, как будет красиво, а как нет. Уже просто что‑то делал, что‑то пробовал, пытался хоть как‑то привести все в порядок. Можно сказать на автомате. И в итоге то ли понял, то ли осознал, то ли окончательно решил что и как именно мне надо сделать. Я начал завершающую фазу адаптации, от финиша меня отделало примерно 5 часов работы. Думать больше не надо, осталось только сделать. Я сделал и улыбнулся, в тот момент я саркастически радовался, потому что осознал, что в какой‑то момент свернул с правильной дорожки и мне надо все пе‑ре‑де‑лАть.

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

Ознакомлю с трудностями

Что ломается:

  1. Сбивается отображение кнопок, которые должны быть поверх куба.

  2. На экранах с челкой используется виньетка, чтобы закрыть слишком большое свободное пространство. А на экране без челки она все портит. Половина сцены становится слишком темной. На устройствах с более широким форматом экрана этого пространства нет. Теперь, кстати, виньетка носит не только декоративно‑ретушный характер, но и стилистический — еще одно хорошее открытие, сделанное благодаря этой преграде.

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

  3. Расположение слайдера относительно куба, который описывает за что слайдер отвечает (Sound, Sensetive. Кнопка Reset Levels относительно соответствующего куба.

Все это съезжает из-за того что меняется высота камеры. UI-то растягивается по размеру экрана, но вот только размер и положение объектов уже не соответствуют элементам интерфейса:

Опишу текущее решение

В итоге я сделал несколько массивов, в которых я храню:

  1. Модели устройств для которых нужны специфические настройки.

  2. Элементы UI, расположение которых нужно изменить для этих моделей.

  3. Координаты для каждого элемента UI, и для каждой модели они свои.

  4. Интенсивность виньетки для каждой модели.

  5. Размер камеры для каждой модели (камера в режиме ортографии разумеется).

Логика обработки массивов:

  1. В методе Awake, перебираю все модели из массива и сравниваю с моделью текущего устройства.

  2. При совпадении, смещаю позицию UI элементов на соответствующие этой модели и этим элементами координаты.

  3. Изменяю значения интенсивности виньетки и размера камеры на соответствующие опознанному устройству.

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

    public string DeviceModel { get; private set; }
    public int IndexDeviceCheck;
    public string DeviceName { get; private set; }

    public string[] Model;

    public RectTransform[] UIElemet; //позиция кнопок для переноса
    public Vector3[] Coordinates;//новая позиция для кнопок

    public Camera MainCamera;
    public float[] SizeCamera; //размеры камер

    public PostProcessVolume _postProcessVolume;
    private Vignette _vignette; //переменная в которую записывается ссылка для обращения к виньетке в PostProcessVolume
    public float[] intensivityVignette;

    void Awake()
    {
        DeviceModel = SystemInfo.deviceModel;
        DeviceName = SystemInfo.deviceName;

        _postProcessVolume.profile.TryGetSettings(out _vignette); //запись ссылки для обращения к виньетки

        CanvasAdaptation();
    }

    public void CanvasAdaptation()
    {
        for (int i = 0; i < Model.Length; i++)
        {
            List<Vector3> Offsetpos = new List<Vector3>(UIElemet.Length); //координаты для перемещения конкретных  UI элементов

            if (DeviceModel == Model[i])
            {
                int LenghtUIarray = UIElemet.Length;
                int end = (i + 1) * LenghtUIarray - 1;
                int start = end - (LenghtUIarray - 1);

                for (int b = start; b <= end; b++)
                {
                    Offsetpos.Add(Coordinates[b]);
                }

                for (int e = 0; e < UIElemet.Length; e++)
                {                   
                    UIElemet[e].position += Offsetpos[e]; //перемещаем UI на координаты присвенные модели устройства
                }

                MainCamera.orthographicSize += SizeCamera[i];
                _vignette.intensity.value += intensivityVignette[i]; //усиление виньетки для экранов с челкой
            }
        }
    }
Как это выглядит в инспекторе
Как это выглядит в инспекторе

А основные настройки, сделаны под устройства с чуть более широкими экранами. В общем они чуть более квадратные. И таких устройств гораздо больше. Поэтому имеет смысл сделать настройки под них, а адоптироваться под более высокие экраны. Ну и разумеется под сумасшедшие форматы, где устройство — это книжка.

Хочу обратить внимание, что объекты, на которых висит аниматор, не меняют свое местонахождение в запущенной игре. То есть они останутся на том же месте где и были, игнорируя логику в скрипте. Мое решение — добавить эти объекты в пустые объекты и аниматор повесить на пустышки. Эти объекты можно будет двигать в рамках пустышки. В моем случае, второй заяц такого решения — это сокращение количества анимаций. Потому как для меня это была сцена меню с разными разделами и вместо кучи анимаций с несколькими UI объектами для каждого раздела, у меня стало три пустышки с шестью анимациями, которые подтягивают и возвращают все кнопочки, слайдеры, тексты для всего раздела целиком.

Подведу итоги

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

Но в итоге я придумал вариант и для тех, и для этих и пока что мне нравится результат. Хотя, я не знаю наверняка правильный он или нет, но какого‑то гайда под мою ситуацию я не нашел, а сам пришел только к такому варианту. Возможно я еще переделаю эту систему. Например, я прописывал значения массивов в инспекторе. Возможно стоит это делать приватно в коде, возможно для хранения этих данных можно использовать какое‑то более правильное или оптимальное решение, например реляционную базу данных. Еще к примеру было бы круто иметь возможность отредактировать эти настройки не выпуская новой версии игры. Поэтому, возможно, в будущем я сделаю так, чтобы конфигурации хранились удаленно и я мог менять их мгновенно для всех игроков, как только это понадобится. Это кстати учебный проект, так что спрячьте свои помидоры, я учусь. Следовательно, хоть игра и примитивная, реализовать такой функционал можно. А потом все же не воспользоваться им, потому что игра слишком простая для такого.

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

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Где вы пишите игры?
7.14% Инди студия1
50% Сам7
7.14% По найму1
0% Не студия, но у нас тусовка и мы работаем над общими проектами0
21.43% Не пишу игры, но хочу3
28.57% Просто интересуюсь4
Проголосовали 14 пользователей. Воздержались 3 пользователя.
Теги:
Хабы:
Всего голосов 1: ↑1 и ↓0+1
Комментарии9

Публикации

Истории

Работа

Ближайшие события

2 – 18 декабря
Yandex DataLens Festival 2024
МоскваОнлайн
11 – 13 декабря
Международная конференция по AI/ML «AI Journey»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань