Unity3d. Уроки от Unity 3D Student (B17-B20)

  • Tutorial
Всем привет. DisaDisa начал хорошее дело по переводу уроков по Unity 3D от сайта www.unity3dstudent.com. Я решил продолжить начатое, чтобы уж на хабре был законченный курс.

Ссылки на предыдущие уроки:



Базовый урок 17 — Работа с компонентами игровых объектов в скриптах




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

Итак, на нашей сцене есть следующие объекты: плоскость Floor [1], падающий на нее красный кубик redbox [2] и точечный источник света Light [3]. При этом, источник света изначально отключен (снят флаг соответствующего компонента), т.е. он не освещает сцену. Мы хотим, чтобы источник света включился тогда, когда красный кубик упадет на плоскость.



Создадим новый скрипт и реализуем в нем метод OnCollisionEnter. Напоминаю, что этот метод вызывается при столкновении коллайдера игрового объекта с коллайдером другого игрового объекта. В нашей сцене коллайдеры есть и у плоскости Floor и у кубика redbox, поэтому метод вызван будет.
Код на JavaScript:
function OnCollisionEnter (myCollision : Collision) {
 if(myCollision.gameObject.name == "Floor"){
   var myLight : Light = gameObject.Find("Light").GetComponent(Light);
   myLight.enabled = true;
   myLight.intensity = 5;
 }
}

Код на C#:
void OnCollisionEnter(Collision myCollision) 
{
    if(myCollision.gameObject.name == "Floor")
    {
        var myLight = (Light)GameObject.Find("Light").GetComponent(typeof(Light));
        myLight.enabled = true;
        myLight.intensity = 5;
    }
}

В скрипте мы сначала проверяем, столкнулся ли кубик с плоскостью. Если да — ищем игровой объект с именем Light при помощи метода GameObject.Find, а потом у найденного объекта получаем компонент освещения Light, используя метод GetComponent. Затем включаем компонент установкой флага enabled и задаем интенсивность излучения intensity равное 5.

Добавляем скрипт к redbox, запускаем сцену. Кубик падает вниз, и при соприкосновении его с плоскостью включается свет.



Примечание от переводчика: в целях улучшения производительности необходимо следить за грамотным вызовом метода GetComponent. В нашем примере он вызывается один раз при обнаружении коллизии, и никаких проблем от этого не возникает. Однако, если вам необходимо многократно использовать полученный при помощи метода компонент, и вы поместите вызов GetComponent, например, в код метода Update, который вызывается в каждом кадре игры — возникнут дополнительные накладные расходы на поиск компонента. Их можно избежать, вызвав метод GetComponent в коде метода Start (который вызывается один раз для игрового объекта), сохранить полученный компонент в переменную и работать дальше с этой переменной, а не вызывать повторно GetComponent.

Ссылка на оригинальный урок

Дополнительные материалы:

Ссылка на документацию метода GetComponent

Базовый урок 18 — Разница между локальными и мировыми направлениями




В уроке показываются особенности при перемещении игрового объекта в локальной и мировой системах координат.

При перемещении игровых объектов может возникнуть недопонимание отличия локальной системы координат объекта от мировой системы координат. Направление мировых координат всегда остается неизменным, в то время как направление локальных координат может меняться и, как следствие, отличаться от мировых. Рассмотрим сцену на картинке ниже. У нас есть игровой объект Pengium. Он расположен так, что направление его локальных координат отличается от направления мировых координат.



Давайте создадим и добавим к нашему объекту простой скрипт:
Код на JavaScript:
function Update () {
 transform.Translate(Vector3(0,0,1) * Time.deltaTime);
}

Код на C#:
void Update() 
{
    transform.Translate(new Vector3(0, 0, 1) * Time.deltaTime);
}

В скрипте мы перемещаем наш объект по оси Z, т.е. вперед. Но вдоль какой оси будет происходить перемещение — мировой или локальной? Запустим сцену и увидим, что объект движется вдоль своей локальной оси Z.



Теперь немного изменим скрипт. Закомментируем первую строчку и добавим вторую:
Код на JavaScript:
function Update () {
 //transform.Translate(Vector3(0,0,1) * Time.deltaTime);
 rigidbody.AddForce(Vector3(0,0,100));
}

Код на C#:
void Update() 
{
    //transform.Translate(new Vector3(0, 0, 1) * Time.deltaTime);
    rigidbody.AddForce(new Vector3(0, 0, 100));
}

Теперь мы осуществляем перемещение объекта путем прикладывания силы. Напоминаю, что для этого у игрового объекта должен быть компонент Rigidbody, иначе будет выдана ошибка. Запустим сцену — объект улетел так же по оси Z, но теперь перемещение произошло в направлении мировых координат.



Как же нам приложить силу так, чтобы объект двигался вперед в локальных координатах? Для этого добавим в скрипт строку перед вызовом метода AddForce, которая сохранит локальное направление объекта, и используем это направление для прикладывания силы:
Код на JavaScript:
function Update () {
 //transform.Translate(Vector3(0,0,1) * Time.deltaTime);
 var fwd = transform.forward * 100;
 rigidbody.AddForce(fwd);
}

Код на C#:
void Update() 
{
    //transform.Translate(new Vector3(0, 0, 1) * Time.deltaTime);
    Vector3 fwd = transform.forward * 100;
    rigidbody.AddForce(fwd);
}

Теперь объект переместится вдоль своей локальной оси Z.

Дополнительные материалы:

Ссылка на документацию класса Transform

Базовый урок 19 — Слежение за объектами с помощью LookAt




В уроке показано применение метода LookAt для слежения за игровым объектом

Представим, что нам необходимо реализовать слежение камеры за движущимся игровым объектом. Такое поведение можно легко сделать при помощи метода LookAt класса Transform.

На нашей сцене есть плоскость, на которую падает красный кубик redbox, отскакивает от поверхности и вылетает за пределы поля зрения камеры Main Camera.



Чтобы камера следила за кубиком, достаточно добавить к ней следующий скрипт:
Код на JavaScript:
var myTransform : Transform;
 
function Update () { 
 transform.LookAt(myTransform); 
}

Код на C#:
public Transform myTransform;

void Update() 
{ 
    transform.LookAt(myTransform); 
}

В скрипте мы объявили переменную myTransform для хранения ссылки на компонент Transform объекта, за которым мы следим. В методе Update для компонента камеры Transform вызывается метод LookAt с передачей в качестве аргумента myTransform. Добавляем скрипт к камере Main Camera, перетаскиваем объект redbox из иерархии сцены в поле My Transform, запускаем сцену.



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

Дополнительные материалы:

Ссылка на документацию метода Transform.LookAt

Базовый урок 20 — Подробное объяснение оператора проверки условия if и булевых переменных




В уроке объясняется работа оператора условия if/[else] и его связь с булевыми выражениями и булевыми переменными.

В программировании большое значение имеет оператор if. Он позволяет проверить некое условие и, в зависимости от того, выполняется ли оно или нет, произвести те или иные действия. Иными словами, при помощи этого оператора ход программы(игры) можно разделить на несколько возможных вариантов, в зависимости от заданных условий.
Посмотрим на следующую простую сцену: камера Main Camera и текст GUI Text.



Напишем следующий скрипт и добавим его к текстуGUI Text:
Код на JavaScript:
var myCheck : boolean = true;
 
function Update () { 
 if(myCheck){
  guiText.text = "Its on!";
 }else{
  guiText.text = "Its Off!";
 }
 
 if(Input.GetButtonUp("Jump") && myCheck){
  myCheck = false;
 }else if(Input.GetButtonUp("Jump") && myCheck == false){
  myCheck = true;
 }
}

Код на C#:
bool myCheck = true;
 
void Update()
{
    if(myCheck)
    {
        guiText.text = "Its on!";
    }
    else
    {
        guiText.text = "Its Off!";
    }

    if(Input.GetButtonUp("Jump") && myCheck)
    {
        myCheck = false;
    }
    else if(Input.GetButtonUp("Jump") && !myCheck)
    {
        myCheck = true;
    }
}

В скрипте мы сперва заводим булеву переменную myCheck. Булевы переменные способны принимать только два значения true или false («истина» или «ложь»). Изначально мы задали значение переменной равное true. Затем, в методе Update при помощи оператора if проверяется значение этой переменной. Такая запись — if(myCheck) — означает проверку значения переменной на предмет равенства значению true. То есть, если значение переменной истинно, программа перейдет в блок кода сразу за оператором if, где мы присваиваем тексту значение «Its on!».
Если бы проверка на true не удалась, программа бы выполнила код после оператора else. Это не обязательный оператор, его можно опустить, если в случае неудачи проверки ничего делать не нужно. Мы же в этом случае устанавливаем значение тексту «Its Off!».

Далее идет еще одна связка операторов if/else. Теперь в нем проверяется не просто переменная, а целое булево выражение. Мы проверяем, была ли нажата клавиша прыжка (по-умолчанию это клавиша пробела) и является ли наша переменная истинной. Если это так, мы меняем значение переменной myCheck с true на false. В операторе else у нас почти что обратная ситуация: мы также проверяем нажатие клавиши прыжка, но теперь значение переменной myCheck проверяется на ложь. Если все так — меняем значение переменной на true. При этом мы используем не просто оператор else, но и еще один оператор if. Кроме того, условия проверки объединяются при помощи оператора && — логическое «И», то есть наши условия должны выполниться оба. Если бы нам было достаточно выполнение любого из условий — необходимо было бы воспользоваться оператором || — логическое «ИЛИ».

Запустим сцену. На экране отобразиться «Its on!», так как переменная myCheck равна true. Нажмем на пробел — текст поменяется на «Its Off!». Еще раз пробел — снова «Its on!».



Примечание от переводчика: в версии скрипта для C# для проверки переменной на ложь я использовал такую запись: !myCheck, то есть просто добавил перед переменной символ восклицательного знака. Это сокращенный способ проверки на ложь, эквивалентный более длинному myCheck == false.

Дополнительные материалы:

Ссылка на MSDN об операторе if/else
  • +27
  • 82,7k
  • 2
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 2
    0
    Спасибо хороший перевод, будет чем заняться в свободное от работы время.
      +1
      К уроку 18 плохой пример, надо использовать физику в FixedUpdate(), вместо Update().
      Кроме того, чтобы двигаться в глобальных координатах можно сделать так:
      void Update () {
      	Vector3 worldDirection = new Vector3(0, 0, 1);
      	transform.position += worldDirection * Time.deltaTime;
      }
      

      Для приложения силы в локальных координатах используют AddRelativeForce():
      void FixedUpdate () {
      	Vector3 localDirection = Vector3.forward * 10; // = new Vector3(0, 0, 10) 
      	rigidbody.AddRelativeForce(localDirection);
      }
      


      В уроке 20 просто неудачный пример, обычно вместо этого:
      if(Input.GetButtonUp("Jump") && myCheck)
      {
          myCheck = false;
      }
      else if(Input.GetButtonUp("Jump") && !myCheck)
      {
          myCheck = true;
      }
      

      пишут так:
      if(Input.GetButtonUp("Jump"))
      {
          myCheck = !myCheck;
      }
      

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

      Самое читаемое