Поддержка изменения размера большого экрана

Переход от телефонов к различным форм-факторам с большими экранами вносит свои коррективы в управление окнами в играх. На GoogleBook , ChromeOS и Google Play Games на ПК ваша игра может работать в оконном режиме поверх основного интерфейса рабочего стола. На новых планшетах и ​​складных устройствах Android под управлением Android 12L (уровень API 32) или выше с шириной экрана > 600dp ваша игра может работать параллельно с другими приложениями в режиме разделенного экрана , изменять размер окон и даже перемещаться между внутренним и внешним дисплеями на складных устройствах, что приводит к изменению конфигурации размера окна и, на некоторых устройствах, его ориентации.

Возможность изменения размера в играх Unity

Базовая конфигурация большого экрана

Укажите, поддерживает ли ваша игра изменение размера экрана:

<android:resizeableActivity="true" or "false" />

Если поддержка изменения размера недоступна, убедитесь, что в манифесте игры явно указаны минимальное и максимальное поддерживаемые соотношения сторон:

<!-- Render full screen between 3:2 and 21:9 aspect ratio -->
<!-- Let the platform letterbox otherwise -->
<activity android:minAspectRatio="1.5">
<activity android:maxAspectRatio="2.33">

Игры Google Play на ПК

В играх Google Play на ПК платформа обеспечивает изменение размера окна с соблюдением заданного соотношения сторон. Размер окна автоматически фиксируется на оптимальных значениях. Необходимо поддерживать соотношение сторон не менее 16:9, если основная ориентация экрана — альбомная, и 9:16, если игра запущена в портретном режиме. Для наилучшего результата рекомендуется явно поддерживать соотношения сторон 21:9, 16:10 и 3:2 для игр в альбомной ориентации. Изменение размера окна здесь не является обязательным, но всё же полезно для совместимости с другими форм-факторами.

Для получения дополнительной информации и рекомендаций см. раздел «Настройка графики для игр Google Play на ПК».

Большие экраны

Чтобы максимально увеличить видимую область для вашей игры в полноэкранном режиме на планшетах с большими экранами, складных устройствах, GoogleBook, ChromeOS и подключенных дисплеях, поддерживайте полноэкранный иммерсивный режим и скрывайте системные панели, устанавливая флаги в decorView , видимости системного интерфейса или через API WindowInsetsCompat . Вам также потребуется корректно обрабатывать события поворота и изменения размера или предотвращать их.

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

Рисунок 1. Диалоговое окно совместимости конфигураций.

На некоторых устройствах при переходе игрока на неподдерживаемую конфигурацию может появиться предложение перезагрузить игру и заново создать окно, чтобы оно наилучшим образом соответствовало новой конфигурации, что нарушает игровой процесс. Протестируйте игру в различных многооконных режимах (размер окна 2/3, 1/2, 1/3) и убедитесь, что никакие элементы игрового процесса или пользовательского интерфейса не обрезаются и не становятся недоступными. Кроме того, проверьте, как ваша игра реагирует на непрерывность отображения на складных устройствах при переходе между внутренним и внешним экранами. Если вы обнаружите проблемы, явно обработайте эти события конфигурации и добавьте расширенную поддержку изменения размера экрана на больших устройствах.

Расширенные возможности изменения размера большого экрана

Рисунок 2. Различные пользовательские интерфейсы на настольном компьютере и в сложенном виде на столе.

Чтобы выйти из режима совместимости и избежать повторного выполнения действий, выполните следующие действия:

  1. Укажите, что размер вашего основного элемента управления можно изменять:

    <android:resizeableActivity="true" />
    
  2. Чтобы получать все события настройки для больших экранов, укажите явную поддержку параметров "orientation", "screenSize", "smallestScreenSize", "screenLayout" и "density" в атрибуте android:configChanges элемента <activity> вашего игрового манифеста.

    <android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard |
                            keyboardHidden | density" />
    
  3. Переопределите onConfigurationChanged() и обработайте событие конфигурации, включая текущую ориентацию, размер окна, ширину и высоту:

    Котлин

    override fun onConfigurationChanged(newConfig: Configuration) {
       super.onConfigurationChanged(newConfig)
       val density: Float = resources.displayMetrics.density
       val newScreenWidthPixels =
    (newConfig.screenWidthDp * density).toInt()
       val newScreenHeightPixels =
    (newConfig.screenHeightDp * density).toInt()
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       val newScreenOrientation: Int = newConfig.orientation
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       val newScreenRotation: Int =
    windowManager.defaultDisplay.rotation
    }

    Java

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
       super.onConfigurationChanged(newConfig);
       float density = getResources().getDisplayMetrics().density;
       int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density);
       int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density);
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       int newScreenOrientation = newConfig.orientation;
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       int newScreenRotation = getWindowManager().getDefaultDisplay()
               .getRotation();
    }

Вы также можете запросить WindowManager информацию о текущем повороте устройства. Используя эти метаданные, проверьте новые размеры окна и отрисуйте его до полного размера окна. Это может не сработать во всех случаях из-за различий в соотношении сторон, поэтому в качестве альтернативы, привяжите пользовательский интерфейс игры к новому размеру окна и добавьте черные полосы по краям для основного игрового контента. Если существуют технические или дизайнерские ограничения, препятствующие любому из этих подходов, выполните собственную внутриигровую обработку черных полос, чтобы сохранить соотношение сторон, и масштабируйте до наилучших возможных размеров, указав resizeableActivity = false и избегая режима конфигурации.

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

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

Многооконный режим

Многооконный режим позволяет нескольким приложениям одновременно использовать один и тот же экран. Многооконный режим не изменяет жизненный цикл активности ; однако состояние возобновления работы приложений в нескольких окнах различается в разных версиях Android (см. раздел «Жизненный цикл активности в многооконном режиме» в разделе «Поддержка многооконного режима »).

Когда игрок переводит приложение или игру в многооконный режим, система уведомляет об изменении конфигурации, как указано в разделе «Расширенные настройки изменения размера для больших экранов» . Изменение конфигурации также происходит, когда игрок изменяет размер игры или возвращает игру в полноэкранный режим.

Нет гарантии, что приложение вернет фокус при переходе в многооконный режим. Поэтому, если вы используете какие-либо события состояния приложения для приостановки игры, не полагайтесь на событие получения фокуса ( onWindowFocusChanged() со значением фокуса true) для возобновления игры. Вместо этого используйте другие обработчики событий или изменения состояния, такие как onConfigurationChanged() или onResume() . Обратите внимание, что вы всегда можете использовать метод isInMultiWindowMode() для определения того, работает ли текущая активность в многооконном режиме.

При использовании оконного режима на Google Books, ChromeOS, а также планшетах и ​​складных устройствах с большими экранами, начальные размеры окна становятся важным фактором. Игра не обязательно должна отображаться в полноэкранном режиме, и в этом случае вам потребуется указать размер окна. Для этого рекомендуется два способа.

Первый вариант работает с использованием определенных атрибутов тега <layout> в вашем Android-манифесте. Атрибуты defaultHeight и defaultWidth управляют начальными размерами. Также обратите внимание на атрибуты minHeight и minWidth , чтобы предотвратить изменение размеров игрового окна игроками до размеров, которые вы не поддерживаете. Наконец, есть атрибут gravity , который определяет, где на экране отображается окно при запуске. Вот пример тега layout с использованием этих атрибутов:

<layout android:defaultHeight="500dp"
        android:defaultWidth="600dp"
        android:gravity="top|end"
        android:minHeight="450dp"
        android:minWidth="300dp" />

Второй способ установки размера окна работает с использованием динамических границ запуска. С помощью функции setLaunchBounds(Rect)⁠⁠ можно определить начальные размеры окна. Если указан пустой прямоугольник, активность запускается в развернутом на весь экран состоянии.

Кроме того, если вы используете игровые движки Unity или Unreal, убедитесь, что вы используете последнюю версию (Unity 2019.4.40 и Unreal 5.3 или новее), которая обеспечивает хорошую поддержку многооконного режима.

Складная опора для осанки

Используйте библиотеку компоновки Jetpack WindowManager для поддержки складывающихся поз, например, в виде стола, чтобы повысить погружение и вовлеченность игрока:

Рисунок 3. Игра в настольном варианте, основной вид на вертикальной части дисплея, элементы управления на горизонтальной части.

Котлин

fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean {
    contract { returns(true) implies (foldFeature != null) }
    return foldFeature?.state == FoldingFeature.State.HALF_OPENED &&
            foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
}

Java

boolean isTableTopPosture(FoldingFeature foldFeature) {
    return (foldFeature != null) &&
           (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) &&
           (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL);
}