Quantcast
Channel: Статьи Intel Developer Zone
Viewing all articles
Browse latest Browse all 357

Контроллер от первого лица в Unity* 3D на основе технологии Intel® RealSense™

$
0
0

Download PDF[PDF 1015KB]

Линн Томпсон (Lynn Thompson)

В этой статье я использую алгоритм отслеживания рук в Intel® RealSense™ Software Development Kit (SDK) для управления положением и параметром LookAt (направление взгляда) контроллера от первого (FPC) лица Unity* 3D. Главная камера сцены остается стандартной в сцене с FPC по умолчанию. Затем я добавляю вторую и третью камеры в левой нижней и в правой нижней частях экрана для отображения ресурса Unity 3D, соответствующего движению левой и правой рук пользователя по данным интерпретации камеры Intel RealSense 3D. Эта интерпретация затем связывается с положением по умолчанию и со сценариями LookAt, управляющими расположением и ориентацией FPC.

В этой статье (первой в серии из трех) я начинаю с настройки среды: устанавливаю Unity Pro и Intel RealSense SDK, затем подключаю камеру Intel RealSense 3D к порту USB 3.0 ультрабука Lenovo с процессором Intel® Core™ i5. Чтобы ознакомиться с этой средой разработки, я изучил примеры в составе Intel RealSense SDK, дважды щелкнув значок на рабочем столе Intel RealSense SDK 2014, чтобы открыть Проводник Windows*. Файлы находятся в папке c:\ProgramData\Microsoft\windows\start Menu\Programs\lntel® RealSense™ SDK 2014. В этой папке я щелкнул правой кнопкой мыши пример файла Intel RealSense SDK Browser, выбрал Запуск от имени администратора, чтобы запустить интерфейс демонстрационных приложений Sample Browser.

В левой части окна Sample Browser находится вкладка Unity Toolkit. Этот интерфейс технологии Intel RealSense предоставляет доступ к меню Unity Editor и настройке конфигурации элементов Intel RealSense путем импорта пакета ресурсов Intel RealSense SDK из папки c:\program files\lntel\RSSDK\framework\unity\RSUnityToolkit.unitypackage. В строке меню Unity Editor появится меню RealSense Unity Toolkit. В этой статье я использую интерфейс Unity Toolkit, но в Sample Browser содержатся примеры работы с Intel RealSense SDK с помощью C#, C++, JavaScript* и Unity без интерфейса Toolkit. Сведения об использовании Unity без интерфейса Toolkit см. в сценарии Senselnput в примере CubeSense. Сценарий Senselnput на C# демонстрирует прямой доступ к SDK Intel RealSense.

После того как я перешел на вкладку Unity Toolkit, в правой части окна Sample Browser появилось несколько примеров. Для работы с примером FPC в Intel RealSense SDK для этой статьи я много использовал пример Sample 1: Translation, где применяется жест Grab для инициирования управления над сферой, которая воздействует на другие трехмерные объекты сцены. Изначально меня смутило отсутствие настраиваемых сценариев, связанных с Translating Sphere в сцене, но я обнаружил, что для настройки Translating Sphere используется действие Translate Action, а также поведение Enable и Disable (все это доступно в Unity Editor в меню RealSense Unity Toolkit). Эти компоненты снабжены интуитивно понятными командами меню, предназначенными для настройки действий и поведения жестов.

Настройка трехмерной сцены в Unity*

После начальной настройки и ознакомления с Sample Browser я создал сцену Unity 3D с базовой геометрией и контроллером FPC. В этой сцене я использую клавиатуру для управления положением FPC, мышь — для управления поворотом и направлением взгляда FPC.

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

Затем я добавляю каждой руке поперечную камеру, чтобы отслеживать направление соответствующего вектора. Каждый пустой игровой объект со свечением находится в поле зрения соответствующей поперечной камеры, при этом глубина = 1 (главная камера сцены, если глубина = 0). Пустой игровой объект, содержащий положение левой руки, подсвечивается зеленым, я расположил его в правой нижней части экрана, задав для параметра Viewport Rectсоответствующей камеры значения X = 0, W = 0,25, Y = 0, H = 0,25. Пустой игровой объект, содержащий положение правой руки, подсвечивается красным, я расположил его в правой нижней части экрана, задав для параметра Viewport Rectсоответствующей камеры значения X = 0,75, W = 0,25, Y = 0, H = 0,25.

И наконец, я добавляю еще два пустых игровых объекта для сохранения состояния активности или неактивности каждой руки. Я использую пустые ресурсы в сочетании со сценариями FPC MouseLook и FPSinputcontroller для сброса и отключения отслеживания рук /FPC в нужных случаях, когда руки пользователя оказываются вне поля зрения камеры Intel RealSense 3D. Нужно, чтобы управление положением FPC или параметром LookAt отключалось, когда рука, управляющая этим положением, отсутствует в поле зрения камеры. На рис. 1 показаны ресурсы в Unity Editor.

Рисунок 1. Простая сцена Unity* 3D Editor с контроллером от первого лица с ресурсами для Intel® RealSense™ SDK

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

Настройка жестов Intel® RealSense™ SDK

Для настройки элемента управления отслеживания рук с помощью Intel RealSense SDK я сначала выбираю нужный ресурс. В данном случае это ресурс LeftHandTracking, выделенный зеленым. Я добавляю отслеживание действия из меню RealSense Unity Toolkit (рис. 2). Я использовал параметры по умолчанию, за исключением ограничений Positionи Rotation. Я установил флажок Z-axisдля этих элементов, чтобы пользователь мог перевести положение ресурса на плоскость экрана с координатами X и Y, но не по оси Z. Я также добавил этот элемент отслеживания жестов в ресурс RightHandTracking.

Рисунок 2. Добавление действий Intel® RealSense™ SDK к ресурсу Unity* 3D с помощью меню RealSense Unity Toolkit

Чтобы предоставить пользователю возможность включать и отключать отслеживание рук, я использую меню RealSense Unity Toolkitдля добавления действий Activate и Deactivate ресурсам LeftHandTracking и RightHandTracking. Для действия Activate, где я использую жест Grab, я оставил значения по умолчанию. Для действия Deactivate я сменил жест на FingersSpread (см. рис. 3). Благодаря этим действиям Activate и Deactivate вместе с измененными сценариями FPC пользователь сможет остановить движение, раскрыв пальцы.

Рисунок 3. Изменение жестов, связанных с действиями Intel® RealSense™ SDK

Действия Activate и Deactivate должны быть связаны с соответствующими объектами: LeftHandActive и RightHandActive. Для этого я изменяю размер массива Game Objectsс 0на 1, а затем выбираю нужный элемент сцены (рис. 4).

Рисунок 4. Настройте в Intel® RealSense™ SDK действия Activate и Deactivate для соответствующих ресурсов сцены

На этом этапе я настроил подсвечиваемые ресурсы для отслеживания рук. Я также настроил действия Deactivate и Activate для соответствующих пустых объектов. Теперь эти ресурсы можно связать с положением FPC и сценариями LookAt, чтобы заменить управление контроллером FPC с помощью клавиатуры и мыши.

Контроллер от первого лица и интеграция Intel® RealSense™ SDK Integration

Поскольку ресурсы настроены в Unity Editor, я завершаю работу над примером, привязывая ресурсы HandTracking и HandActive к сценариям FPSlnputcontroller и MouseLook контроллера FPC. Сценарий MouseLook, приведенный во фрагменте кода 1, управляет функциональностью LookAt контроллера от первого лица. Поведение этого сценария по умолчанию: для управления поворотом главной камеры сцены используется движение по горизонтали и по вертикали, а также положение мыши. В результате главная камера сцены «смотрит» на трехмерную точку сцены, соответствующую двухмерным координатам положения мыши по осям X и Y. Этот сценарий настраивает «область нечувствительности», чтобы не управлять функцией LookAt, когда ее значение близко к начальному состоянию в центре поля зрения соответствующей камеры.

Фрагменткода 1. MouseLook.es


using UnityEngine;

using System.Collections;

 

/// MouseLook поворачивает преобразование на основе разницы в координатах указателя мыши.

/// Для ограничения возможного поворота можно использовать минимальное и максимальное значения

 

/// Создание персонажа в стиле шутера от первого лица:

/// - Создаем капсулу.

/// - Добавляем сценарий MouseLook к капсуле.

/// -> Включаем для мыши использование LookX. (Нужно, чтобы персонаж поворачивался, но не наклонялся)

/// - Добавляем сценарий FPSInputController к капсуле. Компоненты CharacterMotor и CharacterController будут добавлены автоматически.

 

/// - Создаем камеру. Делаем эту камеру дочерним объектом капсулы. Сбрасываем ее преобразование.

/// - Добавляем сценарий MouseLook к этой камере.

/// -> Включаем для мыши использование LookY. (Нужно, чтобы камера наклонялась вверх и вниз, как голова). Персонаж уже поворачивается.)

[AddComponentMenu("Camera-Control/Mouse Look")]

public class MouseLook : MonoBehaviour {

 

       public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }

       public RotationAxes axes = RotationAxes.MouseXAndY;

       public float sensitivityX = 15F;

       public float sensitivityY = 15F;

      

       public float minimumX = -360F;

       public float maximumX = 360F;

      

       public float minimumY = -60F;

       public float maximumY = 60F;

      

       //float rotationY = 0.0F;

      

      

       GameObject leftHandTracking;

       GameObject leftHandActive;

      

       //Приведенные ниже значения масштаба по горизонтали и по вертикали

       //соответствуют размерам прямоугольника HandTracking в RealSense

       public float horzLeftScale = 10.Of;

       public float vertLeftScale = 10.Of;

       public Vector3 initLeftPos;

       public Vector3 runningLeftPos = new Vector3(0.Of,0.Of,0.Of);

      

       public float mouseX = O.Of;

       public float mouseY = O.Of;

      

       void Update ()

       {

              //Следующий блок заставляет контроллер FPC обновлять LookAt, только когда

              //отслеживание рук RealSense делает активным ресурс LeftHandActive. Положение

              //подсвеченного ресурса LeftHandTracking сбрасывается на начальное положение,

              //только когда RealSense теряет левую руку. Жест Grab (сжатие кулака) включит

              //ресурс и контроллер, а жест FingersSpread отключит его согласно настройке

              //в Unity Editor.

              if(leftHandActive.activeSelf ){

                     runningLeftPos = leftHandTracking.transform.position;

              }

              else{

                     leftHandTracking.transform.position = initLeftPos;

                     runningLeftPos = initLeftPos;

                     mouseX = 0.Of ;

                     mouseY = 0.Of ;

              }

             

              //Значения -0.25f и +0.25f предназначены для образования области

              //нечувствительности в середине поля RealSense Box, чтобы пользователь мог

              //прекратить поворачивать контроллер от первого лица (изменять LookAt)

             

              if ((runningLeftPos.x - initLeftPos.x) / horzLeftScale > 0.25f &&

	mouseX <= maximumX) {

                     mouseX += 0.5f;

              }

             

              if ((runningLeftPos.x - initLeftPos.x) / horzLeftScale < -0.25f &&

	mouseX >= minimumX) {

                     mouseX -= 0.5f;

              }

             

              if ( (runningLeftPos.y - initLeftPos.y) / vertLeftScale > 0.25f &&

	mouseY <= maximumY) {

                     mouseY += 0.5f;

              }

             

              if ( (runningLeftPos.y - initLeftPos.y) / vertLeftScale < -0.25f &&

	mouseY >= minimumY) {

                     mouseY -= 0.5f;

              }

             

              transform.localEulerAngles = new Vector3 (-mouseY, mouseX, O.Of);

             

       }

       

       void Start ()

       {

              // Делаем тело неподвижным, оно не изменяется при вращении

              if (GetComponent<Rigidbody>())

                     GetComponent<Rigidbody>().freezeRotation = true;

             

              leftHandTracking = GameObject.Find ("LeftHandTracking");

              leftHandActive = GameObject.Find ("LeftHandActive");

              initLeftPos = leftHandTracking.transform.position;

             

       }

}

 

 

Сценарий FPSinputcontroller, показанный во фрагменте кода 2, управляет положением контроллера от первого лица. Этот сценарий также прочитывает и изменяет масштаб соответствующего положения ресурса HandTracking и использует его для управления положением контроллера. Этот сценарий настраивает «область нечувствительности», чтобы не управлять положением контроллера, когда он находится рядом с начальным состоянием в центре поля зрения камеры.

Фрагменткода 2. FPSInputController.js


private var motor : CharacterMotor;

 

var vertical : int;

var horizontal : int;

 

var rightHandTracking : GameObject;

var rightHandActive : GameObject;

var horzRightScale : float;

var vertRightScale : float;

var initRightPos : Vector3;

var runningRightPos : Vector3;

 

// Используем это для инициализации

function Awake () {

       motor = GetComponent(CharacterMotor);

       rightHandTracking = GameObject.Find ("RightHandTracking");

       rightHandActive = GameObject.Find ("RightHandActive");

       rightHandActive.SetActive(true);

      

       vertical = 0;

       horizontal = 0;

      

       //Приведенные ниже значения масштаба по горизонтали и по вертикали соответствуют

       //размерам прямоугольника HandTracking в RealSense

       horzRightScale = 10.Of;

       vertRightScale = 10.Of;

       initRightPos = rightHandTracking.transform.position;

       runningRightPos = rightHandTracking.transform.position;

}

 

// Обновление вызывается один раз за кадр

function Update () {

 

              //Следующий блок заставляет контроллер FPC обновлять положение, только когда

              //отслеживание рук RealSense делает активным ресурс RightHandActive.

              //Положение подсвеченного ресурса RightHandTracking сбрасывается на начальное

              //положение, только когда RealSense теряет правую руку. Жест Grab (сжатие

              //кулака) включит ресурс и контроллер, а жест FingersSpread отключит его

              //согласно настройке в Unity Editor.

              if(rightHandActive.activeSelf ){

                     runningRightPos = rightHandTracking.transform.position;

              }

              else{

                     rightHandTracking.transform.position = initRightPos;

                     runningRightPos = initRightPos;

              }

             

             

              //Значения -0.25f и +0.25f предназначены для образования области

              //нечувствительности в середине поля RealSense Box, чтобы пользователь мог

              //прекратить изменять положение контроллера от первого лица

             

              if ((runningRightPos.x - initRightPos.x) / horzRightScale > 0.25f) {

                     horizontal = 1;

              }

             

              if ((runningRightPos.x - initRightPos.x) / horzRightScale < -0.25f) {

                     horizontal = -1;

              }

             

              if ((runningRightPos.x - initRightPos.x) / horzRightScale > -0.25f && (runningRightPos.x - initRightPos.x) / horzRightScale < 0.25f){

                     horizontal = 0;

              }

             

              if ((runningRightPos.y - initRightPos.y) / vertRightScale > 0.25f) {

                     vertical = 1;

              }

             

              if ((runningRightPos.y - initRightPos.y) / vertRightScale < -0.25f) {

                     vertical = -1;

              }

             

              if ((runningRightPos.y - initRightPos.y) / horzRightScale > -0.25f && (runningRightPos.y - initRightPos.y) / horzRightScale < 0.25f){

                     vertical = 0;

              }

       // Получаем входной вектор с клавиатуры или аналогового джойстика

       //var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

       var directionVector = new Vector3(horizontal, 0, vertical);

      

       if (directionVector != Vector3.zero) {

              // Получаем длину вектора направления и нормализуем его.

              // При делении на длину тратится меньше ресурсов, чем при нормализации,

              //поскольку длина у нас все равно уже есть

              var directionLength = directionVector.magnitude;

              directionVector = directionVector / directionLength;

             

              // Убедитесь, что длина вектора не больше 1

              directionLength = Mathf.Min(1, directionLength);

             

              // Делаем входной вектор более чувствительным по краям и менее чувствительным в середине

              // Это упрощает управление на малой скорости с помощью аналоговых джойстиков

              directionLength = directionLength * directionLength;

             

              // Умножаем направление нормализованного вектора на измененную длину

              directionVector = directionVector * directionLength;

       }

      

       // Применяем направление к CharacterMotor

       motor.inputMoveDirection = transform.rotation * directionVector;

       motor.inputJump = Input.GetButton("Jump");

}

 

// Нужно, чтобы контроллер персонажа был присоединен к этому же игровому объекту

@script ReguireComponent (CharacterMotor)

@script AddComponentMenu ("Character/FPS Input Controller")

Замечания

При приобретении некоторого навыка пользователи могут с помощью рук управлять положением и параметром LookAt контроллера от первого лица Unity. В примере, показанном в этой статье, было нужно, чтобы по жесту FingersSpread отключалась только та рука, которая показала жест FingersSpread. При запуске программы оказалось, что при показе жеста FingersSpread любой рукой отключались обе руки. Кроме того, было нужно, чтобы по жесту FingersSpread Deactivate ресурс HandTracking возвращался в центр поля зрения камеры. Оказалось, что это работает только для левой руки. После некоторых экспериментов выяснилось, что причины таких неполадок связаны с производительностью ультрабука. Описанное выше поведение возникало при запуске сцены на ультрабуке с его максимальным разрешением (3200 x 1800). Все работало должным образом, когда сцена была запущена с разрешением 1024 х 768.

Для настройки полностью функциональной и интересной игры я бы добавил дискретные жесты (большие пальцы вверх, большие пальцы вниз, сведение и пр.), чтобы дополнить элемент управления Translation параметра LookAt и положения FPC. Например, жесты для увеличения скорости изменения LookAt и положения, жесты для стрельбы, включения отображения информации на экране и графического пользовательского интерфейса, регулировки увеличения камеры и выбора цели. С помощью Intel RealSense SDK можно создать графический пользовательский интерфейс для контроллера FPC в Unity, предоставляющего намного более интересные возможности, чем мышь и клавиатура.

Возникли определенные трудности с потерей управления, но они могут быть вызваны тем, что пользователь (то есть я) не держал обе руки в нужном месте в поле зрения камеры. В меню RealSense Unity Toolkit > Add to Scene доступен объект Sense AR. Этот объект можно использовать, чтобы показать изображение, получаемое камерой Intel RealSense 3D. Отображаемая на экране картинка с камеры помогает пользователям правильно расположить свои руки и может устранить проблему потери управления. Я использую объект Sense AR в следующей статье, где приводится пример применения технологии Intel RealSense для реализации последовательностей жестов. Также для решения этой проблемы можно использовать действия поведения Enable и Disable.

Заключение

Меню RealSense Unity Toolkit в Unity Editor — полезный интерфейс технологии Intel RealSense при настройке ресурсов Unity 3D для отслеживания рук. После настройки можно было без труда использовать эти ресурсы для управления положением и параметром LookAt контроллера от первого лица в Unity 3D. В этом простом примере у меня возникли некоторые трудности с управлением, но в пакете есть средства для решения этих проблем. При наличии опыта разработчик Unity 3D может заменить традиционные средства управления контроллером от первого лица на отслеживание рук в Intel RealSense SDK.

Об авторе

Линн Томпсон — специалист в области ИТ, более 20 лет проработавший в области компьютеризации предпринимательской и производственной сферы. Одной из первых его работ стало использование САПР для создания и редактирования чертежей контрольных приборов для энергосистем. Тогда же он получил степень бакалавра электротехники в Университете Небраски (г. Линкольн). В эпоху бума доткомов Линн занимался системным администрированием операционных систем, баз данных и приложений на различных платформах в одном из ИТ-интеграторов. Позже (после «краха доткомов») он участвовал во множестве проектов в роли ИТ-консультанта. Линн работал с компаниями, работающими в сфере легкой промышленности, а также нефтегазовой и оборонной индустрии. Сейчас он вернулся к своей специальности и работает инженером-энергетиком. Линн получил магистерскую степень инженера со специализацией в области управления техническими системами (также в Университете Небраски).


Viewing all articles
Browse latest Browse all 357

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>