Использование стандартного GUI Unity* 3D в сочетании с ресурсами TouchScript

Линн Томпсон

Download PDF

Виджеты стандартного графического пользовательского интерфейса (GUI) Unity* 3D реагируют на касание так же, как на щелчок мыши c включенной функцией Windows* 8 «Перо и сенсорный ввод». В настоящее время для них невозможно настроить поддержку мультисенсорного ввода и жестов. В этой статье рассказывается о том, как TouchScript расширяет возможности стандартных объектов GUI с помощью функции Pan Gesture. Полученные элементы сохраняют внешний вид и функционал обычных виджетов интерфейса Unity 3D, но при этом поддерживают перетаскивание по экрану (функция Pan Gesture). В приведенном примере Unity 3D работает под управлением ОС Windows 8. Эта платформа обладает множеством средств для создания настраиваемых виджетов графического пользовательского интерфейса.

Создание примера

Пример начинается с создания нескольких сфер и кубов в поле обзора основной камеры сцены. Сцена проста и состоит из нескольких трехмерных объектов, которые можно изменять с помощью стандартных виджетов интерфейса Unity 3D. В основном интерфейс состоит из кнопок, горизонтальных ползунков и переключателей. После настройки каждого виджета мы располагаем в том же месте четырехугольник Unity 3D с аналогичными размерами. В настройках этого четырехугольника мы выбираем функцию TouchScript Pan Gesture, которая дает пользователям возможность перемещать данный объект. При перемещении четырехугольника его координаты присваиваются соответствующему виджету интерфейса Unity 3D. В результате мы получаем стандартный виджет интерфейса Unity 3D, который можно перемещать по экрану с помощью жестов TouchScript Pan Gesture. На рис. 1 показан пример такого интерфейса.

Three Unity* 3D standard GUI widgets
Рисунок 1. Три стандартных виджета графического интерфейса Unity* 3D

Добавление стандартного виджета

Для начала добавим три виджета графического интерфейса с помощью функции OnGUI. Первый виджет состоит из панели и нескольких кнопок, изменяющих масштаб примитивов на сцене. На втором виджете располагаются переключатели, которые присваивают геометрическим объектам фиксированные значения масштаба. Горизонтальные ползунки на третьем виджете вращают объекты на сцене по осям X, Y и Z. Расположим эти виджеты в левой, правой и центральной части верхней области экрана (эти объекты будут размещены с учетом разрешения 1024 x 768).

Существует множество справочных материалов, посвященных настройке стандартных элементов графического интерфейса в Unity 3D. Исходный код этих виджетов можно найти в прилагаемом проекте Unity 3D.

Настройка TouchScript

В данном примере четырехугольники Unity 3D добавляются в качестве целей TouchScript, упрощающих сенсорное управление стандартными виджетами графического интерфейса. Эти примитивы добавляются не через редактор Unity 3D, а программно. Ниже приведен код для создания четырехугольника, перемещающего левый виджет с кнопками:

Public Class:
.
.
.
private GameObject buttonQuad;//Создаем ресурс, обрабатывающий жесты
//Объявляем переменные для обработки жестов, с помощью которых будет изменяться
//стандартное положение GUI
private Vector3 buttonQuadStartPosition;
private float buttonQuadDeltaX;
private float buttonQuadDeltaY;
.
.
.
Start Function:
.
.
//Создаем ресурс, обрабатывающий жесты
buttonQuad = GameObject.CreatePrimitive (PrimitiveType.Quad);

//Приводим вектор положения ресурса в соответствие со стандартным расположением GUI
buttonQuad.transform.position = new Vector3(-0.7f,2.25f,-10.0f);

//Добавляем компоненты TouchScript, чтобы ресурс мог реагировать на сенсорные команды 
buttonQuad.AddComponent ("PanGesture");
buttonQuad.AddComponent ("PanScript");

//Задаем начальное положение для ресурса, обрабатывающего сенсорные команды 
buttonQuadStartPosition = buttonQuad.transform.position;
//Инициализируем переменные изменения положения 
buttonQuadDeltaX = 0.0f;
buttonQuadDeltaY = 0.0f;

//Делаем ресурс для обработки сенсорных команд невидимым
MeshRenderer buttonQuadRenderer = (MeshRenderer) buttonQuad.GetComponent ("MeshRenderer");
buttonQuadRenderer.enabled = false;
.
.
.
Update function:
.
.
//Задаем переменные смены положения. Значение 235 — фактор масштабирования 
//для разрешения 1024x768. В полноценном приложении этот фактор будет 
//зависеть от разрешения, установленного программой или пользователем.
buttonQuadDeltaX = -235*(buttonQuadStartPosition.x - 	buttonQuad.transform.localPosition.x);
buttonQuadDeltaY = 235*(buttonQuadStartPosition.y - buttonQuad.transform.localPosition.y);
.
.
OnGUI function:
.
.
////////////////////// Меню с кнопками: начало //////////////////////////////////// 
//Создаем стандартное окно GUI, расположение которого будет зависеть от положения //ресурса, обрабатывающего команды сенсорного управления
		GUI.Box(new Rect(10+buttonQuadDeltaX,10+buttonQuadDeltaY,240,160), "Button Menu");

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

		if(GUI.Button(new Rect(20+buttonQuadDeltaX,40+buttonQuadDeltaY,220,20), "Increase Scale (4x Maximum)"))
		{
			//While increasing the cube scale, limit the cube scaling
			//to be between 0.25 and 4

			if (scale < 4.0)
			{
				scale += 0.1f;
				cube01.transform.localScale += (new Vector3(0.1f,0.1f,0.1f));
				cube02.transform.localScale += (new Vector3(0.1f,0.1f,0.1f));
				sphere01.transform.localScale += (new Vector3(0.1f,0.1f,0.1f));
				sphere02.transform.localScale += (new Vector3(0.1f,0.1f,0.1f));

			}
			if (scale == 4.0f)
			{
				maxscale = true;
				minscale = false;
				defaultscale = false;
			}
			else
			{
				maxscale = false;
			}
			if (scale == 0.25f)
			{
				minscale = true;
				maxscale = false;
				defaultscale = false;
			}
			else
			{
				minscale = false;
			}
			if (scale == 1.0f)
			{
				defaultscale = true;
				maxscale = false;
				minscale = false;
			}
			else
			{
				defaultscale = false;
			}
		}
		
		if(GUI.Button(new Rect(20+buttonQuadDeltaX,80+buttonQuadDeltaY,220,20), "Decrease Scale (0.25x Minimum)"))
		{
			if (scale > 0.25)
			{
			//While decreasing the cube scale, limit the cube scaling
			//to be between 0.25 and 4

				scale -= 0.1f;
				
				cube01.transform.localScale -= (new Vector3(0.1f,0.1f,0.1f));
				cube02.transform.localScale -= (new Vector3(0.1f,0.1f,0.1f));
				sphere01.transform.localScale -= (new Vector3(0.1f,0.1f,0.1f));
				sphere02.transform.localScale -= (new Vector3(0.1f,0.1f,0.1f));
			}
			if (scale == 4.0f)
			{
				maxscale = true;
				minscale = false;
				defaultscale = false;
			}
			else
			{
				maxscale = false;
			}
			if (scale == 0.25f)
			{
				minscale = true;
				maxscale = false;
				defaultscale = false;
			}
			else
			{
				minscale = false;
			}
			if (scale == 1.0f)
			{
				defaultscale = true;
				maxscale = false;
				minscale = false;
			}
			else
			{
				defaultscale = false;
			}
		}

		//Создаем кнопку для выхода из приложения 
		if(GUI.Button(new Rect(20+buttonQuadDeltaX,120+buttonQuadDeltaY,220,20), "Exit Application"))
		{
			Application.Quit();
		}
		
		GUI.Label (new Rect(20,180,220,20),scale.ToString());
		////////////////////// Меню с кнопками: конец////////////////////////////////// 
.
.
.

Сценарий PanScript программно добавляется к четырехугольникам и позволяет сдвигать или перетаскивать их. Работу этих функций можно увидеть в прилагаемом к данной статье примере или в примере под названием Everything, который поставляется вместе с пакетом TouchScript. Прилагаемое видео SGwTS.wmv демонстрирует работу виджетов интерфейса.

Возможности усовершенствования

Самым трудоемким процессом в создании этого примера является размещение четырех-угольника за виджетом GUI. Для этого приходится вручную рассчитывать точные значения x, y, и z и выравнивать положение четырехугольника, совмещая его со стандартным виджетом интерфейса Unity 3D. Кроме того, если пользователь установит разрешение экрана, отличающееся от 1024 x 768, это выравнивание окажется бесполезным. Более совершенным методом будет использование макетов интерфейса и автоматическое размещение четырехугольника с функцией TouchScript Pan Gesture, являющегося целью сенсорной команды.

Ширина четырехугольника в прилагаемом примере совпадает с шириной стандартного виджета графического интерфейса Unity 3D, а высота несколько отличается от него в большую сторону. В результате над виджетом и под ним появляются «поля», с помощью которых пользователь может перемещать виджет по экрану. Передвинув точку сенсорного управления, можно изменить положение четырехугольника относительно стандартного виджета GUI Unity 3D. Например, габариты четырехугольника можно совместить с виджетом внизу и по бокам, тем самым переместив предполагаемую точку управления в верхнюю часть виджета.

В приведенном примере пользователь может перемещать четырехугольник и связанный с ним виджет за любую точку (даже если она находится в габаритах виджета). Чтобы сделать активными только те области, которые выходят за пределы виджета, можно добавить еще один «блокирующий» четырехугольник. Размеры и положение этого четырехугольника должны совпадать с габаритами стандартного виджета графического интерфейса Unity 3D. Размещение блокирующего четырехугольника будет определяться другим четырехугольником, который изменяет положение стандартного виджета. Сама блокировка производится с помощью функции поведения TouchScript Untouchable. Такое поведения можно увидеть в примере Hit. Также это поможет избежать ошибки, при которой ползунок виджета двигется, когда передвигается горизонтальный ползунок.

С помощью сочетания блокирующих и активных четырехугольников можно добиться перемещения настраиваемых виджетов. В совокупности эти два вида четырехугольников позволяют перемещать отдельные компоненты графического интерфейса без изменения позиции самого виджета. Например, пользователь сможет по отдельности независимо перемещать горизонтальные ползунки, находящиеся на одной неподвижной базе. Также с помощью настраива¬емой функции Pan Gesture можно ограничить перемещение компонентов виджета рамками самого элемента интерфейса.

Порядок касания

Напомним, что один из настроенных нами виджетов GUI позволяет масштабировать геометрические примитивы, расположенные на сцене. Левый куб и правую сферу можно свободно перемещать по сцене, так как они были настроены с помощью функции Pan Gesture. В то же время куб и сфера, расположенные в центре сцены, не связаны с TouchScript и не реагируют на сенсорное управление. Из-за этого масштабируемые примитивы могут закрыть собой четырехугольники, предназначенные для перемещения виджетов интер¬фейса. Если пользователь увеличит размер примитива, а затем перетащит на него виджет, следующая сенсорная команда в этой области экрана затронет не виджет, а примитив. Разумеется, можно использовать ту же команду-жест, чтобы вывести примитив из области виджета и снова сделать этот элемент интерфейса доступным для сенсорного управления.

Тем не менее, если пользователь перетащит виджет на один из центральных примитивов, которые не поддерживают сенсорное управление, этот виджет будет заблокирован. Эту проблему можно решить, назначив через TouchScript примитиву поведение Untouchable с помощью кнопки Add Component («Добавить компонент») (см. рис. 2). Такая конфигурация позволит виджетам GUI, настроенным с помощью функции Pan Gesture, считывать сенсорные команды даже через геометрические примитивы. Эту схему можно наблюдать в прилагаемом видео: при перемещении виджета интерфейса на левый куб или правую сферу следующий жест передвигает соответствующий примитив. В то же время после переноса виджета на среднюю сферу (которой назначено поведение Untouchable) следующая команда перемещает сам виджет. Если из-за фактора масштабирования средний куб закроет собой не прошедшие рендеринг четырехугольники, перенесенный на этот куб виджет окажется заблокированным.

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

Configuring a Unity* 3D scene asset to allow touch gestures
Рисунок 2. Настройка сенсорного управления для объектов, находящихся за ресурсом Unity* 3D

Последовательность рендеринга

Видимые компоненты виджетов GUI, упоминающихся в этой статье, созданы с помощью встроенной функции Unity 3D OnGUI. Они будут отображаться всегда, и настраивать отдельную камеру для рендеринга отдельного слоя виджетов не требуется.

Заключение

Функции пакета TouchScript хорошо подходят для совместной работы со стандартными интерфейсными виджетами Unity 3D. Сочетание этих функций позволяет создавать традиционные элементы интерфейса, которые можно перемещать по экрану с помощью стандартного управления. При этом нет необходимости разрабатывать виджеты с нуля и создавать геометрические объекты для работы с жестами TouchScript. Полученный в результате код отличается стабильностью работы на платформе Unity 3D для Windows 8. Описанный метод идеально подходит для быстрой разработки стандартных виджетов графического интерфейса с поддержкой перетаскивания.

Другие материалы по этой теме:

Об авторе

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

Intel, эмблема Intel и Xeon являются товарными знаками корпорации Intel в США и в других странах.
*Прочие наименования и товарные знаки могут быть собственностью третьих лиц.
© Корпорация Intel, 2013. Все права защищены.

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