- PVSM.RU - https://www.pvsm.ru -

Как адаптировать игру на Unity под iPhone X к апрелю

Как адаптировать игру на Unity под iPhone X к апрелю - 1

Месяц назад Apple предупредила [1] всех разработчиков, что с апреля все приложения, которые заливаются в App Store, должны быть собраны с использованием последнего iOS 11 SDK. О том, как правильно позиционировать контент, используя новый API, уже давно можно почитать в официальной документации [2] и Human Interface Guidelines [3]. А хорошими и подробными статьями об адаптации игр на Unity ни на русском, ни на английском языке нас не радуют. А так как в War Robots поддержка нового UI появилась с февральским релизом версии 3.6.0, я решил написать собственный гайд со скриптами и скриншотами.

Теория

Начнем с того, что любая игра на Unity собирается под iOS сначала системой сборки самого движка. На выходе вы получаете обычный Xcode-проект. Допустим, сейчас сентябрь 2017, вы привычно работаете в Xcode 8.3 и успешно отправляете релизы вашей игры в App Store. Что же будет, если в этот момент в продажу поступит устройство с экраном, которого до этого не существовало? Все банально просто: проект, собранный в Xcode старых версий, а именно ниже версии 9.0, получит большие черные полосы сверху и снизу. А в landscape-ориентации в качестве бонуса к двум полосам по бокам достанется еще и такой же черный отступ снизу, чтобы обеспечить достаточно свободного места для нового элемента интерфейса iOS, эксклюзивного для iPhone X — контрастной горизонтальной полосы, заменяющей кнопку Home.

Таким образом Apple заботливо уберегла пользователей от немыслимого числа приложений, которыми нельзя пользоваться из-за кнопок, отрисованных в углах или под козырьком. Но выглядит это совсем не секси, совсем не Human Interface Guidelines.

Тут же в голову приходит соблазнительная идея: установить Xcode 9 и собрать свой проект уже с его помощью. Казалось бы, это и есть та самая серебряная пуля, но увы, во многих случаях результат может оказаться еще хуже.

Как адаптировать игру на Unity под iPhone X к апрелю - 2

Дело в том, что в этом случае вы уже сами берете на себя ответственность, а Apple не мешает вам сделать неюзабельное приложение. Важные элементы интерфейса, которые раньше уютно располагались по углам и вдоль различных сторон экрана, теперь оказались обрезаны и закрыты Face ID или кнопкой Home. Само собой, никакой магии не произошло, экран iPhone по-прежнему прямоугольный, а видеокарте нет никакого дела до этих дизайнерских нововведений.

Практика

Но решение есть. В iOS 11 компания Apple представила новое property UIView, которое позволяет получить UIEdgeInsets. Он будет содержать в себе значения безопасных отступов от каждой из сторон экрана:

@property(nonatomic, readonly) UIEdgeInsets safeAreaInsets;

Весь кайф в том, что для всех устройств, кроме iPhone X, будут возвращаться нулевые отступы, а значит вам не придется огораживать код условиями для каких-то конкретных случаев, все будет работать одинаково хорошо на всем парке девайсов. Зная об этом, вам остается получить искомые значения в проекте Unity.

Во-первых, Apple рекомендует адаптировать игры таким образом, чтобы информационный контент занимал все доступное пространство, а смещались только интерактивные элементы управления. Скорее всего, у вас они уже находятся в отдельном Canvas и их имеет смысл выделить в RectTransform, отдельный от декоративных и требующих всей плоскости экрана элементов. Оставшиеся изменения не представляют большой сложности. В реализации этого поможет workaround решение от Unity из их репозитория на BitBucket [4].

Как адаптировать игру на Unity под iPhone X к апрелю - 3

Мы немного доработали скрипт SetCanvasBounds, заменив вызов метода Update() вызовом Awake(), поскольку значения отступов не меняются, а элементы UI в нашей игре всегда находятся на одних и тех же местах. Достаточно только один раз установить нужные отступы компоненту RectTransform и все будет выглядеть правильно в любой ситуации.

private void Awake()
{
	var safeArea = GetSafeArea();

	if (safeArea != _lastSafeArea)
	{
		ApplySafeArea(safeArea);
	}
}

В этом скрипте в методе GetSafeArea() вызывается нативный C-метод

void GetSafeAreaImpl(float* x, float* y, float* w, float* h) { ... }

объявленный в файле SafeAreaImpl.mm. Именно здесь, в соседнем методе, вы можете найти тот самый API, о котором было упомянуто выше.

UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0);
if ([view respondsToSelector: @selector(safeAreaInsets)]) {
    insets = [view safeAreaInsets];
}

Используйте API Screen.safeArea вместо вызова нативного метода, если ваша версия Unity его поддерживает. В скрипте SetCanvasBounds заботливо оставлен соответствующий комментарий.

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

private void ApplySafeArea(Rect area)
{
	var anchorMin = area.position;
	var anchorMax = area.position + area.size;
	anchorMin.x /= Screen.width;
	anchorMin.y /= Screen.height;
	anchorMax.x /= Screen.width;
	anchorMax.y /= Screen.height;
	_panel.anchorMin = anchorMin;
	_panel.anchorMax = anchorMax;

	_lastSafeArea = area;
}

Как адаптировать игру на Unity под iPhone X к апрелю - 4

Как это выглядит у нас

Чтобы продемонстрировать результат на примере реального проекта, мы сделали скриншоты трех различных сборок нашей игры: Xcode 8, Xcode 9 без поддержки iPhone X и Xcode 9 с поддержкой iPhone X.

Как адаптировать игру на Unity под iPhone X к апрелю - 5
Как адаптировать игру на Unity под iPhone X к апрелю - 6
Xcode 8

Как адаптировать игру на Unity под iPhone X к апрелю - 7
Как адаптировать игру на Unity под iPhone X к апрелю - 8
Xcode 9 без поддержки iPhone X

Как адаптировать игру на Unity под iPhone X к апрелю - 9
Как адаптировать игру на Unity под iPhone X к апрелю - 10
Xcode 9 с поддержкой iPhone X

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

Потом, когда мы просто собрали игру в Xcode 9, полосы исчезли как страшный сон. Но теперь станет заметно, что часть наших кнопок утонула под козырьком нового iPhone. Другие же пали жертвами углов. Надо было спасать UI от причудливых форм флагмана Apple.

Мы использовали описанные в этой статье приемы и собрали игру в третий раз. Снова в Xcode 9. Вот этот результат полностью удовлетворил наши ожидания. Кнопки в ангаре находятся на своих местах и не прячутся за углами, а интерфейс боя стал удобнее, не потеряв своей привлекательности. На этом варианте мы и остановились, так как он полностью соответствует требованиям Human Interface Guidelines, после чего отправили очередной релиз в App Store, чего желаю и вам, если вы еще не успели этого сделать.

Автор: Дмитрий Старокожев

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/ios/275244

Ссылки в тексте:

[1] предупредила: https://developer.apple.com/ios/submit/

[2] официальной документации: https://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area?language=objc

[3] Human Interface Guidelines: https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/

[4] репозитория на BitBucket: https://bitbucket.org/p12tic/iossafeareasplugin/src

[5] Источник: https://habrahabr.ru/post/351184/?utm_source=habrahabr&utm_medium=rss&utm_campaign=351184