Unity3d. Уроки от Unity 3D Student (B25-B28)
Всем привет. Это заключительная серия базовых уроков по Unity 3D от сайта Unity3DStudent. Далее будут еще два урока среднего уровня.Ссылки на предыдущие уроки:
Базовый урок 25 — Объект GUI Texture и события мыши В уроке рассказывается о создании простой кнопки, с использованием GUI Texture и событий мыши.Если вы хотите создать простой пользовательский интерфейс, то можно использовать объект GUI Texture. Рассмотрим этот объект на примере создания кнопки. В первую очередь нам понадобятся две текстуры: для кнопки в обычном состоянии и для кнопки в состоянии, когда на нее наведен курсор мыши. Подготовим соответствующие файлы и добавим их в проект.
Теперь кликнем по файлу button_normal, а затем создадим GUI Texture из меню GameObject — Create Other — GUI Texture. На сцене появиться новый объект, на который будет сразу же наложена соответствующая текстура нормального состояния кнопки.
Созданный объект состоит из двух компонентов: Transform и GUITexture. Обратите внимание, что изменение параметров компонента Transform работает несколько иначе по сравнению с другими объектами сцены. В параметрах Position и Scale обрабатываются только изменения по осям X и Y, изменения по оси Z игнорируются. Изменения параметра Rotation игнорируется полностью. Кроме того, в параметре Position значения указываются не в мировых, а в экранных координатах, где 0,0 — левый нижний угол экрана, а 1,1 — правый верхний угол экрана. По-умолчанию выставляются значения 0.5,0.5, т.е. центр экрана. В компоненте GUITexture можно задать текстуру, цвет, дополнительное смещение от краев экрана и границу. Поскольку мы выбрали конкретную текстуру перед созданием объекта, Unity сама задала эти значения. При желании, их можно изменить.
Итак, у нас есть кнопка в центре экрана, которая пока ничего не делает. Давайте оживим ее при помощи следующего скрипта: Код на JavaScript:
var normalTex: Texture2D; var hoverTex: Texture2D; function OnMouseEnter () { guiTexture.texture = hoverTex; } function OnMouseExit (){ guiTexture.texture = normalTex; } function OnMouseDown (){ Debug.Log («clicked»); } Код на C#: public Texture2D normalTex; public Texture2D hoverTex; private void OnMouseEnter () { guiTexture.texture = hoverTex; }
private void OnMouseExit () { guiTexture.texture = normalTex; }
private void OnMouseDown () { Debug.Log («clicked»); } Мы завели переменные normalTex и hoverTex для хранения, соответственно, текстуры нормального состояния кнопки и текстуры кнопки под курсором мыши. Затем обрабатываем три метода: OnMouseEnter (наведение курсора мышки на объект), OnMouseExit (выход курсора мышки из объекта) и OnMouseDown (клик мышкой по объекту). Эти методы вызываются после соответствующих событий мышки, если объект, к которому присоединен скрипт, унаследован от класса GUIElement или Collider. В методах вхождения/выхода курсора мышки мы устанавливаем объекту соответствующую текстуру, в методе клика просто пишем сообщение в консоль.Присоединяем скрипт к нашей кнопке, заносим файлы текстур в соответствующие поля:
Запускаем сцену и тестируем кнопку. Кнопка меняет текстуру при наведении курсора мышки, при клике выводит сообщение «clicked» в консоль и меняет текстуру обратно при выводе курсора.
Ссылка на оригинальный урок
Дополнительные материалы: Ссылка на документацию компонента GUI TextureСсылка на документацию метода OnMouseEnterСсылка на документацию метода OnMouseExitСсылка на документацию метода OnMouseDownБазовый урок 26 — Использование метода Mathf.Clamp для ограничения значений В уроке показано, как ограничить значения в определенном диапазоне с помощью метода Mathf.Clamp.При разработке игровой механики иногда нужно ограничить некое значение в пределах заданного интервала значений. Например, вы пишете какую-нибудь простую космическую стрелялку и хотите, чтобы управляемый игроком корабль не вылетал за пределы границ экрана. В этом нам поможет метод Clamp класса Mathf.
Рассмотрим использование этого метода на сцене, где у нас есть камера, источник света и простой кубик Cube.
Реализуем возможность перемещения кубика по оси X, причем перемещаться можно будет только в пределах от Х = -10 до Х = 10. Для этого напишем следующий скрипт и добавим его к кубику: Код на JavaScript:
function Update () { var xMove: float = Input.GetAxis («Horizontal») * Time.deltaTime * 20; transform.Translate (Vector3(xMove,0,0)); transform.position.x = Mathf.Clamp (transform.position.x, -10, 10); } Код на C#: void Update () { float xMove = Input.GetAxis («Horizontal») * Time.deltaTime * 20; transform.Translate (new Vector3(xMove,0,0)); transform.position = new Vector3(Mathf.Clamp (transform.position.x, -10, 10), transform.position.y, transform.position.z); } Мы перемещаем кубик с использованием значения виртуальной оси Х и метода Transform.Translate, а затем ограничиваем позицию кубика по оси Х, вызывая метод Mathf.Clamp. Метод принимает три параметра: ограничиваемое значение, минимальную границу диапазона и максимальную границу диапазона.Запускаем сцену, нажимаем на клавиатуре A/D или стрелки влево-вправо. Кубик перемещается, причем переместиться за границы диапазона Х = -10…10 он не может (чтобы в этом убедиться, можно добавить в конец метода Update вывод в консоль значения позиции по оси Х — Debug.Log (transform.position.x); — прим. переводчика).
Ссылка на оригинальный урок
Дополнительные материалы: Ссылка на документацию метода Mathf.ClampБазовый урок 27 — Реализация приостановки (паузы) в игре при помощи Time.timeScale В уроке рассматривается использование свойства Time.timeScale для приостановки/возобновления игры.Разрабатывая игру, вы наверняка захотите дать игрокам возможность поставить ее на паузу, а потом возобновить. Для этого нужно всего лишь немного поработать со статическим свойством timeScale класса Time.
Для примера, у нас есть сцена, где по полу скачет небольшой шарик, и мы хотим приостанавливать/возобновлять его движение. Сперва нам нужен объект, на который мы «повесим» скрипт реализации паузы. Для этого можно создать пустой игровой объект (меню GameObject — Create Empty), разместить в любом удобном месте и назвать его, например, Manager.
Теперь создадим новый скрипт и напишем в нем следующее: Код на JavaScript:
var paused: boolean = false; function Update () { if (Input.GetButtonUp («Jump»)){ if (! paused){ Time.timeScale = 0; paused=true; }else{ Time.timeScale = 1; paused=false; } } } Код на C#: bool paused = false; private void Update () { if (Input.GetButtonUp («Jump»)) { if (! paused) { Time.timeScale = 0; paused=true; } else { Time.timeScale = 1; paused=false; } } } В скрипте мы завели переменную paused для контроля, включена пауза или нет. Включение/выключение паузы мы делаем в методе Update по нажатию кнопки «Jump» — при стандартных настройках ввода это клавиша пробела. Далее мы проверяем, выключена ли пауза? Если это так — присваиваем свойству Time.timeScale значение 0, что остановит течение времени в игре; и обозначаем, что пауза включена — paused=true. В противном случае — присваиваем Time.timeScale значение 1 и выключаем паузу. Свойству Time.timeScale также можно устанавливать значения между 0 и 1 и больше 1, что будет, соответственно, замедлять и ускорять течение времени, если вам это нужно.Добавляем скрипт к объекту Manager, запускаем сцену. В любой момент нажимаем на пробел — шарик останавливается. Повторное нажатие возвращает приостановленное движение шарика.
Ссылка на оригинальный урок
Дополнительные материалы: Ссылка на документацию свойства Time.timeScaleБазовый урок 28 — Использование метода SendMessage для вызова внешних методов В уроке рассказывается, как использовать метод SendMessage класса GameObject для вызова метода скрипта другого игрового объекта.Существуют разные способы связаться из скрипта одного игрового объекта со скриптом другого игрового объекта. Ранее мы рассматривали метод GetComponent, с помощью которого можно получить компоненты объекта, в том числе и его скрипты. Альтернативой этому может быть использование метода SendMessage.
Рассмотрим сцену, на которой есть голубой шар Ball, падающий на красный ящик Switch. Рядом с ними висит в воздухе черный блок Block. Давайте сделаем так, чтобы при падании шара на ящик блок менял текстуру и тоже падал вниз.
Сначала нам надо написать скрипт для блока. Создадим новый скрипт, назовем его Reactor и напишем следующее: Код на JavaScript:
var downTexture: Texture2D; function React () { renderer.material.mainTexture = downTexture; yield WaitForSeconds (1); gameObject.AddComponent (Rigidbody); } Код на C#: public Texture2D downTexture; private IEnumerator React () { renderer.material.mainTexture = downTexture; yield return new WaitForSeconds (1); gameObject.AddComponent (typeof (Rigidbody)); } Мы объявили переменную downTexture для хранения текстуры и реализовали метод React, в котором меняем текстуру объекта, делаем небольшую задержку в 1 секунду и добавляем компонент твердого тела Rigidbody, чтобы на объект стала действовать гравитация. Добавим сразу этот скрипт к объекту Block и перетянем в поле скрипта Down Texture любую подходящую картинку. В уроке это изображение направленной вниз желтой стрелки на черном фоне.
Не торопитесь пока запускать сцену, на ней пока что ничего не изменится. Далее нам нужно сделать скрипт для шара Ball. Назовем его Switcher и напишем внутри: Код на JavaScript:
function OnCollisionEnter (col: Collision) { if (col.gameObject.name == «Switch»){ gameObject.Find («Block»).SendMessage («React»); } } Код на C#: private void OnCollisionEnter (Collision col) { if (col.gameObject.name == «Switch») GameObject.Find («Block»).SendMessage («React»); } Мы реализовали метод OnCollisionEnter, который будет вызван при столкновении коллайдера шара с коллайдером другого объекта. Нас интересует столкновение с ящиком Switch, поэму мы сперва делаем соответствующую проверку. Если это так, мы ищем объект блока Block при помощи метода GameObject.Find, указав имя блока. Для найденного объекта вызывается метод SendMessage, в который передается имя метода, который мы хотим вызвать (React), после чего, соответственно, происходит выполнение этого метода.
Добавляем скрипт к шару, запускаем сцену. Теперь при падении шара на ящик блок меняет текстуру и спустя секунду тоже падает вниз.
Примечание от переводчика: одним из минусов использования SendMessage является возможное ухудшение производительности по сравнению с вызовом методов напрямую. Вот на этой странице, посвященной вопросам производительности, говорится о разнице в 100 раз в пользу прямого вызова. Поэтому применять этот метод следует с осторожностью (как и методы GetComponent, Find и т.п.), и если его использование действительно становится виновником падения производительности — использовать более быстрые решения.
Ссылка на оригинальный урок
Дополнительные материалы: Ссылка на документацию метода GameObject.SendMessage