Unity настройка камеры под андроид

Камера

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

Свойства

Свойство: Функция:
Clear Flags Определяет, какие части экрана будут очищены. Это удобно при использовании нескольких камер для отрисовки разных элементов игры.
Background Цвет, применяемый для фона после отрисовки всех элементов, в случае отсутствия скайбокса.
###Маска отрезания Включение или исключение слоёв объектов на рендер этой камерой. Назначение слоёв объектам производится через Inspector.
Projection Переключает способность камеры симулировать перспективу.
X Камера будет рисовать объекты в перспективе.
X Camera will render objects uniformly, with no sense of perspective. NOTE: Deferred rendering is not supported in Orthographic mode. Forward rendering is always used.
Size (когда выбран ортографический режим) Размер зоны видимости камеры для ортографического режима.
Field of view (когда выбран режим перспективы) Ширина угла обзора камеры, измеряется в градусах по локальной оси Y.
###Clip Planes (Плоскости отреза) Дистанция, на которой камера начинает и заканчивает рендеринг.
X Ближайшая точка относительно камеры, которая будет рисоваться.
X Дальняя точка относительно камеры, которая будет рисоваться.
Normalized View Port Rect Четыре значения, отражающие то, в какой области экрана будет выведено изображение с камеры, в экранных координатах (от 0 до 1).
X Начальная позиция области по горизонтали вида камеры, который будет рисоваться.
Y Начальная позиция области по вертикали, где вид камеры будет рисоваться.
W (Ширина) Ширина вида камеры на экране.
H (Высота) Высота вида камеры на экране.
Depth Позиция камеры в очереди отрисовки. Камеры с большим значением будут нарисованы поверх камер с меньшим значением.
###Способ рендера Опции для определения методов рендеринга для камеры.
X Камера использует метод рендеринга, установленный в Player Settings.
Вершинное освещение Все объекты рисующиеся этой камерой будут рендериться как Vertex-Lit-объекты.
X Все объекты будут рендериться с одним проходом на материал.
Deferred Lighting (только в Unity Pro) Все объекты будут рендериться сначала без освещения, а затем будет произведён рендер освещения для всех объектов разом, в конце очереди рендеринга.
Target Texture Ссылка на Render Texture, которая будет содержать результат рендеринга камеры. Назначение этой ссылки отключает способность камеры рендерить на экран.
HDR Включение технологии High Dynamic Range.
Target Display Defines which external device to render to. Between 1 and 8.

Детали

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

Вы можете создать несколько камер и назначить каждой свою глубину(Depth). Камеры будут отрисовываться от низшей глубины до высшей глубины. Другими словами, камера с Depth 2 будет отрисована поверх камеры с Depth 1. Вы можете настроить значение свойства Normalized View Port Rectangle для изменения позиции и размера изображения с камеры на экране, например для создания нескольких экранов в одном, или для создания зеркала заднего вида.

Способ рендера

Unity поддерживает различные способы рендеринга. Вы должны выбрать один из них, в зависимости от содержимого вашей игры и целевой платформы / аппаратного обеспечения. Различные методы рендеринга поддерживают различные возможности и дают различную производительность, особенно в аспекте применения теней и источников света. Метод рендеринга, используемый в вашем проекте, выбирается в Player Settings. Дополнительно свой метод рендеринга может быть выбран для каждой камеры.

См. способы рендеринга для получения всех подробностей.

Clear Flags

Каждая камера хранит информацию о цвете и глубине, когда рендерит свой вид. По умолчанию, незаполненные части экрана, будут показаны в виде скайбокса. При использовании нескольких камер, каждая камера будет иметь свои буферы цвета и глубины, заполняемые при каждом рендеринге. Каждая камера будет рендерить то, что видно с её ракурса, а путем изменения настройки Clear Flags можно выбрать набор буферов, которые будут обновлены (очищены), во время рендеринга. Это осуществляется, выбором одного из четырёх вариантов:

Skybox

Это настройка по умолчанию. Пустые участки экрана будут отображать скайбокс текущей камеры. Если текущая камера не имеет скайбокса, то скайбокс будет использован стандартный скайбокс из меню Render Settings ( Edit->Render Settings ). Если и там не будет указан скайбокс, то будет использован цвет Background Color . Также к камере может быть добавлен компонент Skybox. Если вы хотите создать новый скайбокс, см. это руководство.

Solid color

Любые пустые части экрана будут отображать текущий фоновый цвет ( Background Color ) камеры.

Только глубина

Если вы хотите рисовать оружие игрока не подвергая его обрезке объектами окружения, внутри которых оно находится, установите одну камеру, рисующей окружение, с Depth 0, и ещё одну камеру, рисующую оружие — Depth 1. Для камеры оружия выберите Clear Flags depth only . Это позволит отобразить окружение на экране, но проигнорировать всю информацию о взаимном положении предметов в пространстве. Когда оружие будет отрисовано, непрозрачные части будут полностью отрисованы на экране поверх ранее находившегося там изображения, независимо от того, насколько близко оружие находится к стене.

Оружие отрисовано последним после очистки буфера глубины предшествовавшей камеры.

Не очищать

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

Clip Planes (Плоскости отреза)

Near и Far Clip Plane — свойства, определяющие, где начинается и заканчивается область отрисовки камеры. Эта область ограничивается плоскостями, перпендикулярными направлению камеры, и находившимися в этих позициях относительно неё. Near Plane — это ближайшая позиция, а Far Plane — дальняя позиция.

Плоскости также определяют точность буфера глубины. Для обеспечения наивысшей точности вам следует отодвинуть Near Plane так далеко, насколько возможно.

Обратите внимание, что эти плоскости вместе определяют поле зрения камеры, которое известно как фрустум. Unity гарантирует, что объекты, полностью находящиеся за пределами фрустума, не будут отображаться. Это называется Frustum Culling и это срабатывает независимо от Occlusion Culling.

Из соображений производительности вы можете прекращать отрисовку мелких объектов раньше, чем отрисовку прочих. Для этого поместите их в separate layer и настройте дистанцию обрезки для этого слоя, используя функцию Camera.layerCullDistances.

Маска отрезания

Culling Mask используется для выборочного рендеринга групп объектов посредством использования слоёв. Больше информации об использовании слоёв можно найти здесь.

Normalized Viewport Rectangles

Normalized Viewport Rectangles предназначено для определения части экрана, на которой будет отрисовано изображение с камеры. Вы можете, к примеру, вставить изображение карты в нижний правый угол экрана, а вид с камеры на выпущенной ракете — в верхний левый угол. Немного поработав над дизайном, используя Viewport Rectangle , вы сможете создать кое-какие уникальные системы.

Очень просто создать раздельный экран для двух игроков, используя Normalized Viewport Rectangle . После создания двух камер, установите обеим камерам свойство H в значение 0.5 и для одной из них свойство Y в значение 0.5, а для другой — в значение 0. В результате, первая камера будет рисовать изображение в верхней половине экрана, а вторая камера — в нижней половине экрана.

Создание экрана для двух игроков с помощью Normalized ViewportRectangle

Orthographic

Переключив камеру в ортографичесий ( Orthographic ) режим, вы устраните всю перспективу из отрисовываемого ей изображения. Это полезно для создания двумерных и изометрических игр.

Заметьте, что туман отрисовывается при этом равномерно, так что может выглядеть не так, как вы ожидали. Прочтите справко по компоненту Render Settings для получения подробностей.

Перспективная камера. Ортографическая камера. Изображение объектов не уменьшается при увеличении дистанции.

Текстура рендера

Эта возможность доступна лишь в расширенных лицензиях Unity. Она позволяет отрисовывать изображенеи с камеры в текстуру (Texture), которая может быть применена к другому игровому объекту. Это делает простым создание спортивной арены с видеомониторами, камеры наблюдения, отражений и т.д.

Использование рендертекстуры для создания монитора

Target display

A camera has up to 8 target display settings. The camera can be controlled to render to one of up to 8 monitors. This is supported only on PC, Mac and Linux. In Game View the chosen display in the Camera Inspector will be shown.

Источник

Разработка Unity плагинов для iOS и Android

Есть куча ситуаций когда одной Unity недостаточно и нужно использовать возможности платформы. Банально, но до сих пор, в Unity нет работы с галерей и камерой из коробки. Понятно, что Unity не ограничивается мобильными платформами, но 60-70% всех мобильных игр, как бы говорят:

Если говорить о самой Unity, то особых подвижек в этом направлении у них нет. Они заняты более важными вещами… В менеджере пакетов есть какой-то куцый пакет для уведомлений, да и всё вроде. Это если говорить про мобайл. Недавно они зарелизили пакет для локализации (уже что-то!). Всё остальное делают сторонние разработчики и выкладывают либо на Github или продают в Asset Store. В принципе, в сторе можно найти и купить (или скачать) практически любой плагин для любой платформы. Но часто бывает, что требуется лишь одна-две функции, а приходится тянуть весь пакет. А сколько всего можно использовать:

  • геолокация
  • ин-апп оценки и покупки
  • уведомления
  • авторизация
  • синхронизация данных
  • работа с безопасным хранилищем
  • карты

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

За несколько лет, я сделал большое количество различных плагинов для iOS и Android (iCloud, Google Sign-in, Sign-in with Apple, Firebase Push Service, In-app purchases, Browser, Sharing, Mail, Images, Review, NativeInput, . ), почти все они давно в продакшне и отлично работают. Система отлажена, обновляется и функционирует 🙂 Да, она не идеальна, но зато проста в создании и использовании.

В блоге я уже давно пишу короткие посты про плагины:

Они немного устарели конечно, но основа осталась примерно такая же: есть общий интерфейс приема/передачи сообщений на стороне Unity и есть такая же система на стороне платформы. Эта статья – апдейт и рефакторинг накопившихся знаний.

Важное отличие моего подхода к созданию и использованию плагинов для Unity: модульность. Собственно, оно так и должно быть. Т. е. каждый плагин автономен и не зависит от других (почти), нет необходимости тянуть скопом всё что есть, ради одной функции тост-сообщений :).

Unity часть (контроллер и плагин)

У Unity в документации есть немного про создание плагинов, если совсем только начали, то стоит ознакомиться. А так на Хабре (и на Медиуме) были уже годные статьи на эту тему, можно поискать, почитать, сравнить, выбрать для себя лучшее решение.

И так, делаем ещё одну свою систему плагинов.

Первое что понадобится: объект на сцене который будет принимать команды от плагинов. Но не просто объект, у него должно быть определенное имя, потому что любой плагин при передаче данных в Unity будет искать на сцене именно его. В общем-то таких объектов может быть много, например, для каждого плагина свой. Но это только усложнит архитектуру. Поэтому, делаем одну точку входа и далее контролируем все получаемые данные оттуда.

Кроме того, этот объект скорее всего должен быть неразрушаемым, мало ли какие плагины, на каких сценах и при каких условиях будем использовать. Теперь осталось повесить на этот объект скрипт и можно принимать сообщения от плагинов. Полдела сделано (нет). Ещё нужно определиться с именем метода который будет обрабатывать поступающие сообщения. Их тоже может быть несколько, как и объектов, но я делаю все плагины унифицированными и поэтому использую один объект, один метод и определенный протокол. Быстрее показать сразу код и объяснить.

Вот как выглядит примерный контроллер плагинов:

Все данные между Unity и плагинами передаются в JSON формате. Это удобно, это понятно, это легко реализовать. Можно использовать и свой какой-нибудь формат/протокол.

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

Также, есть один метод для приема всех сообщений от всех плагинов. Там как видно, парсится JSON и в нужный плагин передаются данные. Всё просто.

Для работы с JSON я давно использую NiceJson, меня он полностью устраивает, хотя есть и куча других сериализаторов, в том числе и встроенный Unity. Так что тут тоже, свобода выбора.

Теперь, что касается самого скрипта плагина.

Все плагины живут на объекте с контроллером и каждый должен реализовать интерфейс IPlugin. Он был описан в контроллере выше. Всё что нужно, это уметь принимать данные, принимать сообщения об ошибках и отдавать своё имя. Этого пока хватало для всего. Ниже, пример плагина для отправки писем:

Это самый простой плагин. Тут вроде ничего сверхъестественного: один метод вызова нативных функций и обработчики данных и ошибок, для данного плагина больше ничего и не требуется. Так как из плагина никаких данных не приходит (кроме возможных ошибок), то метод OnData пустой.

Интересней плагин работы с галереей и камерой. Тут есть коллбек в котором уже возвращается адрес с картинкой и угол поворота. Ну и дополнительное взаимодействие с правами доступа и оповещением, если файл картинки долго скачивается из Google Photo, например.

Тут в методах Pick и Capture передаётся Action который выполнится после выбора изображения. В нём вернётся путь до картинки на устройстве и угол её поворота из Exif данных. В общем-то, это необязательно и «выравнивать» её можно на стороне плагина, но я делаю так и всю обработку оставляю на стороне Unity: поворот, кадрирование, масштабирование и т.д.

Вот так примерно выглядит работа с плагином:

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

Прежде чем перейдем к нативной части, напомню, что все плагины хранятся в папке Plugins/iOS или Plugins/Android, если мы рассматриваем эти платформы, в любой глубине по иерархии проекта. Но следует учесть что кастомный файл AndroidManifest.xml, должен быть в самом верху: Assets/Plugins/Android.

Android плагины

Для создания плагинов под Android, я использую Android Studio, пишу на Java. Почему не Kotlin? Потому что пока нет времени выучить его. Но в планах, всё же переписать плагины на Kotlin и на Swift под iOS. Опять же, я не Android или iOS разработчик, поэтому не претендую на академическую правильность написания на Java или Obj-C 🙂

Все плагины – это набор Android Library (AAR) внутри пустого проекта.

Входная точка для работы плагина – класс Plugin. В нем будут хранится все основные методы и к нему будет обращаться скрипт Unity. Если плагин простой и состоит из 1-3 методов, то одного этого класса может быть достаточно. Если требуется какая-то более сложная реализация, то есть варианты.

  1. Отдельный класс
  2. Фрагмент
  3. Сервис

Вообще, внутри плагина можно делать всё что душе угодно, как будто вы пишите нативное приложение, но с некоторыми условиями. Можно даже делать свои активити и вызывать из Unity.

Первые версии плагинов были сделаны во фрагментах. Это было удобно, внутри можно было обрабатывать onActivityResult, что решало много вопросов. Но сейчас старые фрагменты устарели, на смену пришли фрагменты из AndroidX Fragment library. Сейчас можно вообще делать вот такую вещь:

В этой статье подробно описано, как использовать новые API. Но к сожалению, это не получится сделать у нас, потому что чтобы запустить метод registerForActivityResult нужно юнитевский активити кастануть в AppCompatActivity, а у меня это никак не получилось 🙁 Если знаете как – поделитесь, буду очень благодарен.

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

Чтобы что-то отправить в Unity, нужно вызвать специальный метод у UnityPlayer:

object – имя объекта на сцене Unity
receiver – метод который обработает данные
data – строка с данными

У каждого плагина можно писать в собственный AndroidManifest.xml, все манифесты потом мерджатся при билде. Также у каждого плагина могут быть свои ресурсы, картинки и всё остальное. Папку Plugins/Android/res в Unity проекте уже мало кто использует.

В Gradle файл добавляете все необходимые зависимости которые будете использовать в плагине, например, Firebase или ещё что-то. Также потребуется ссылка на библиотеку с классами Unity. Эта библиотека понадобится, если вы захотите обратиться и использовать UnityPlayer.currentActivity, например, ну и собственно чтобы отправлять данные обратно в Unity.

Файл можно скопировать из папки Unity если у вас MacOS. Для Windows путь будет не особо отличаться.

Этот файл копируем в папку libs своего плагина и в Gradle добавляем:

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

У Gradle много настроек и тонкостей, это тема отдельной статьи. Добавлю лишь, как я копирую все скомпилированные плагины в одну папку:

После запуска таска Assemble для всего проекта со всеми плагинами, они компилируются, переименовываются и копируются в одну папку.

Вот пример плагина галереи и камеры, точнее, только точка входа, вся магия в файле MediaService.java (изучить исходник можно на Github)

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

Чтобы сервис работал, нужно прописать его в манифесте:

Ещё есть отдельный плагин-хелпер с помощью которого можно легко отправлять данные в Unity, чтобы каждый раз не хардкодить названия объектов и методов, всё это захардкодено там 🙂 В хелпере есть несколько методов которые собирают JSON с нужными ключами и отправляют в Unity.

Хотя, при желании можно сделать специальный метод инициализации, где при старте приложения будут передаваться название объекта и метод куда отсылать данные, для всех плагинов.

Ну и чтобы завершить тему Android плагинов, расскажу как обрабатывается onActivityResult и разрешение прав.

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

Плагин наследуется от UnityPlayerActivity и переопределяется в манифесте:

Таким способом можно отлавливать и другие события Activity, как например изменение ориентации устройства.

iOS плагины

Начнём с того, что iOS плагины разрабатывать легче! Тут тоже есть свои заморочки, но в целом – легче. Я пишу на Objective-C, да это олдскулл, но на чём знаю, на том и пишу.

Обычно плагин наследуется от NSObject или UIViewController, если требуется какое-то более сложное взаимодействие. Вот пример плагина нативного шаринга текста:

В начале тоже подключается хелпер (тут не используется, просто по привычке подключаю везде сразу) для отправки данных в Unity, потом идёт сам плагин с одним методом и в конце блок на С, который вызывается из Unity.

Из интересного тут UnityGetGLViewController() – это метод который возвращает текущий контроллер который рендерит Unity приложение. Как UnityPlayer.currentActivity в Android плагинах. Собственно с этим контроллером и работаем обычно. В скомпилированном Xcode проекте можно открыть папку Classes и поизучать внутренности 🙂 Например, файлы UnityAppController.mm или UnityInterface.h.

Лучше рассмотрим тот же плагин с камерой и галереей.

Тут плагин наследуется от UIViewController и указываются делегаты для ImagePicker’а и навигатора. Метод didFinishPickingMediaWithInfo возвращает все нужные нам данные. Там мы определяем, что если изображение с камеры, то необходимо получить его угол поворота, если из галереи то по-умолчанию нормализуем ориентацию. И отправляем в Unity путь до картинки и угол.

Там где вызывается камера сначала проверяются права доступа и если они есть, то всё норм, если нет – то ответ (NO_PERMISSION) придёт в Unity, который предложит открыть настройки приложения.

Выше я рассказывал про класс UnityAppController.mm, в нём описаны все методы из нативного AppDelegate: didFinishLaunchingWithOptions, didReceiveRemoteNotification, openURL и т.д. Так вот чтобы сделать свой плагин и переопределить эти методы, нужно наследоваться от него и в конце добавить такую конструкцию:

Все плагины имеют расширение *.mm или отдельно, заголовки и реализация: *.h и *.m. Кроме того, вам ничего не мешает сделать свою скомпилированную библиотеку-плагин. В Xcode при создании проекта выбираете Static Library, пишите плагин и делаете билд. Как и все iOS плагины, надо будет закинуть в папку Plugins/iOS.

Как-то так. Это наверно самое основное, что необходимо знать чтобы сделать плагин под iOS. Т.е. алгоритм примерно такой: хотите сделать определение геолокации -> читаете мануал, как это сделать на Obj-c или Swift -> создаёте шаблон плагина и заголовки -> добавляете внутрянку, запросы на доступ и коллбеки -> профит.

Чуть не забыл упомянуть про External Dependency Manager for Unity. Этот пакет автоматически загрузит все необходимые зависимые библиотеки для Android и подсы (cocoapod) для iOS. Для этого в папке Editor нужно создать XML файл и указать используемые библиотеки. Пример есть на Github или репозитории проекта.

На Github я обновил репозиторий с исходниками всей этой системы, тремя плагинами и примером.

Ну и не забываем, отключать сервисы когда они уже не нужны и очищать все созданные контроллеры и объекты в плагинах 🙂

Источник

Читайте также:  Android usb modem mac os big sur
Оцените статью