30 апреля 2012 в 01:25

Unity3d. Уроки от Unity 3D Student (B04-B08)

Добрый день.

Предыдущие уроки вы можете найти в соответствующем топике.

Теперь в каждом посте в скобках (в конце) будут указываться номера уроков. Буква в начале номера обозначает раздел (B-Beginner, I — Intermediate).

PS: Если вы не проходили предыдущие уроки, очень рекомендую их пройти, т.к. последующие изредка на них ссылаются.




Базовый Урок 04 — Уничтожение объектов




В уроке рассказывается как удалять объекты со сцены, использую команду Destroy (уничтожить).

Создайте пустую сцену и добавьте в нее сферу (GameObject->Create Other->Sphere) и куб (GameObject->Create Other->Cube). Куб назовем “Box”. Расположите объекты как показано на рисунке ниже.
B0400

Добавьте C#-Скрипт (Project View->Create->C# Script) и назовите его Destroyer. Как уже говорилось, при создании C#-скрипта Unity создает некий каркас, состоящий из подключенных библиотек и основного класса (используемого скриптом) с методами Start() и Update(). В Базовом Уроке 02 (основы ввода) использовался метод Update(), который вызывается каждый кадр. В данном случае мы воспользуемся методом Start(), который выполняется сразу после загрузки сцены. Добавим в тело метода Start() функцию Destroy() и передадим в нее gameObject, указав таким образом, что скрипт должен уничтожить объект, компонентом которого он является:

// метод Start() выполняется единожды, сразу после окончания загрузки сцены
Start() {
  // уничтожить объект к которому прикреплен данный скрипт
  Destroy(gameObject);
}


Добавим скрипт к сфере. Сделать это можно несколькими путями. Перетащив скрипт из Project View на сферу в Scene View.
B0401

Или на имя объекта в Hierarchy.
B0402

Так же можно выбрать сферу и добавить скрипт через меню компонентов (Component->Scripts->Destroyer) или просто перетащив скрипт в Inspector View выбранного объекта.
B0404

Снова выберите сферу и убедитесь, что среди компонентов присутствует ваш скрипт.
B0403

Нажмите на Play и вы увидите, что сразу после загрузки сцены сфера исчезает.
B0404_1

Давайте теперь попробуем уничтожить другой объект. Для этого нам понадобится статический метод Find класса GameObject. Заменим код в методе Start() следующим:
// ищем объект с именем Box и если таковой есть – уничтожаем его
Destroy(GameObject.Find(“Box”));


Примечание от автора перевода: Обратите внимание, что во втором случае мы передаем значение, вызывая статическую функцию, поэтому пишем имя класса (GameObject — с большой буквы), в то время как в первом мы передаем объект этого класса (gameObject — с маленькой буквы). В противном случае компилятор выдаст ошибку:

error CS0176: Static member `UnityEngine.GameObject.Find(string)' cannot be accessed with an instance reference, qualify it with a type name instead

что переводится как:
“статический член UnityEngine.GameObject.Find(string) не может быть доступен по ссылки экземпляра (класса), вместо этого определите (вызовите) его с именем типа.”

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

Что делать, если нам требуется уничтожить объект не сразу, а спустя какое-то время? Это можно сделать передав значение во 2ой параметр функции Destroy:

// Теперь уничтожаем Box спустя 3и секудны после загрузки сцены
Destroy(GameObject.Find(“Box”),  3);


Нажмите Play и убедитесь, что куб изчезает через 3и секунды после того, как сцена целиком загрузится.

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

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

Справка по функции Destroy() из официального справочника о скриптах Unity3d



Базовый Урок 05 — Реализация создание объектов




В уроке рассказывается как создавать объекты в сцене в реальном времени (runtime), используя префабы и команду Instantiate (инстанциирование)

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

Загрузите сцену из Базового урока 03 (Префабы) или создайте такую же новую. В нашей сцене присутствует префаб BouncyBox.
B0500

Нажмите Play и убедитесь, что куб по-прежнему падает и отталкивается от поверхностей.
Теперь удалите со сцены экземпляр BouncyBox.
B0501

После этого добавьте пустой объект (напоминаю, GameObject->Create Empty или Ctrl + Shift + N в Windows, Cmd + Shift + N в MacOS). Расположите его примерно в том месте, где раньше был экземпляр BouncyBox.
B0502_1

Создадим C#-Скрипт и назовем его Creater. Начнем редактирование скрипта. Заведем открытую (public) переменную типа GameObject и назовем ее thePrefab. Модификатор public требуется указывать, если, например, вы хотите передавать значение переменной через Inspector View. После чего в теле функции Start() создадим еще один GameObject (с именем instance) и проинициализируем его значением с помощью статической функции Instantiate().


public GameObject thePrefab; 
  
void Start () {
  GameObject instance = new GameObject();
  instance = Instantiate(thePrefab, 
                         transform.position, 
                         transform.rotation) as GameObject; 
}


Рассмотрим метод Instantiate() подробнее.

Instantiate(GameObject original, Vector3 position, Quaternion rotation)

Метод клонирует объект original с заданными вектором положения (position) и кватернионом поворота (rotation).
Тип Vector3 является обычным 3х компонентым вектором (аналогично вектору из R3).
Тип Quaternionкватернион, задающий поворот объекта.

Добавьте скрипт к пустому объекту (c именем GameObject).Напоминаю, поскольку thePrefab объявлен с модификатором public, вы можете задавать его начальное значение прямо в Inspector View (у соответствующего компонента, то есть в нашем случае это Creator у GameObject'а). Перетащите наш префаб в место указания значения (или выберете его из списка, кликнув на кружок справа).
B0503

Нажмем Play и увидим, что на сцене появился наш прыгающий кубик.
B0504

Но наш кубик прыгает просто вверх и вниз, потому что не имеет начального угла поворота. Выберите GameObject и поверните его под небольшим углом.

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

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

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

Описание функции instantiate() из официального справочника о скриптах Unity3d

Описание класса Transform из официального справочника о скриптах Unity3d



Базовый Урок 06 — Простой таймер




В данном уроке рассказывается как в Unit при помощи скриптов
создавать простой таймер, используя Time.deltaTime и переменную типа float.


Воспользуемся сценой из предыдущего урока (с пустым игровым объектом,
генерирующим экземпляры префаба, т.е. BouncyBox).
B0600

Создадим С#-скрипт и назовем его Timer. Добавим переменную myTimer, и напишем следующий код.


public float myTimer = 5.0f;

void Update() {
  //Time.delaTime - время (сек), которое требовалось для отрисовки   последнего кадра (read only)
  myTimer -= Time.deltaTime;  
  if (myTimer <= 0.0f) {
    Debug.Log("GAME OVER");
  }
}


Сохраняем скрипт и переключаемся назад в Unity. Добавим скрипт к объекту GameObject.
B0601

Напомню, т.к. myTimer объявлена открытой (public), то в Inspector View вы можете менять ее начальное значение.

Жмем Play. Как только значение myTimer упадет до нуля, в статус баре вы увидите строку GAME OVER. Значение переменной myTimer будет продолжать опускаться (это можно увидеть в Inspector View).
B0602

Для того, чтобы переменная myTimer не опускалась ниже нуля, добавим еще одно ветвление в функцию Update(), в итоге мы получаем следующий код:

void Update () {
  if(myTimer > 0){
    myTimer -= Time.deltaTime;
  }else if(myTimer <= 0){
    Debug.Log("GAME OVER");
  }
}


Нажмем Play и проследим за поведением переменной myTimer. Когда ее значение будет достаточно близким к нулю, то оно перестанет изменяться.
B0603

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

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

Информация о Time.deltaTime из официального руководства о скриптах Unity3d



Базовый Урок 07 — Основы движения




В уроке рассказывается, как двигать объекты c помощью функции transform.Translate.

Создадим сцену с кубом, камерой и источником света.
B0700

Создадим новый C#-скрипт и назовем его Move.
Поскольку движение должно быть непрерывно во времени, то основной код будет располагаться в методе Update(). Вызовем функцию Translate, объекта transform и передадим ей в качестве параметра Vector3(0, 0, 1). Получим следующий код:


void Update () {
  transform.Translate(new Vector3(0.0f, 0.0f, 1.0f)); // задаем движение объекту вдоль оси Oz
}


Разберемся подробнее в коде. Тут transform — это объект класса Transform, привязанный к нашему объекту. Метод Translate() двигает объект вдоль вектора на расстояние равное его длине (параллельный перенос).

Сохраним наш скрипт и добавим его к нашему кубу. Нажмите Play и увидите как куб стремительно улетает вдоль оси Oz.

B0701

Давайте уменьшим скорость движения, например, умножив наш вектор на Time.deltaTime, то есть:


transform.Translate(new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime);


Нажмите Play и убедитесь, что куб начинает двигаться заметно медленнее.

Можно сделать наш скрипт более удобным в использовании, если скорость задать не фиксированным вектором, а через переменную. Заведем public переменную типа float и назовем ее speed. С помощью этой переменной можно будет задавать начальную скорость через Inspector View (по умолчанию она будет равна 5.0f):


public float speed = 5.0f;
void Update () {
  transform.Translate(new Vector3(0.0f, 0.0f, speed) * Time.deltaTime);
}


Сохраним скрипт и убедимся, что в Inspector View у компонента Move появилась переменная Speed.
B0702

Посмотрите, как будет меняться скорость движения нашего объекта в соответствии с заданным начальным значением этой переменной. Например, при Speed = 3 скорость объекта не очень быстрая, но и не медленная.

Примечение: Для выражения Vector3(0.0f, 0.0f, 1.0f) существует короткая (но видимо чуть более медленная, если не прав, прошу поправить) запись Vector3.forward.

Кусок кода из обертки:

public static Vector3 forward
  {
    get
    {
      return new Vector3(0.0f, 0.0f, 1.0f);
    }
  }


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

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


Информация о методе transform.Translate из официального справочника о скриптах Unity3d

Информация Time.deltaTime из официального справочника о скриптах Unity3d



Базовый Урок 08 — Основы движения с помощью силы.




В уроке рассказывается как c помощью приложения силы двигать физическое тело (Rigidbody).

Если у вас на сцене есть объект с компонентом Rigidbody, то нужно задавать ему движение с помощью приложения силы (передав таким образом все расчеты движения физическому движку игры). В противном случае вы можете начать конфликтовать с физикой объекта. Мы по-прежнему используем сцену из Базового урока 03.

B0800

Создадим C#-скрипт и назовем его Force. В методе Start() вызовем метод AddForce() компонента rigidbody (cвязанного с нашим объектом) и передадим ему вектор приложенной силы Vector3(0.0f, 0.0f, power). В классе заведем переменную типа float с именем power и значением, по умолчанию равным 500.0f:


public float power = 500.0f;
void Start () {
  rigidbody.AddForce(new Vector3(0.0f, 0.0f, power));
}


Сохраним скрипт и добавим его к нашему объекту (или префабу). Теперь, если нажать Play, вы увидите как куб падает не вниз а под углом, из-за воздействия силы приложенной вдоль оси Oz.
B0801

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

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


Информация о классе Rigidbody из официального справочника по скриптам Unity3d

Информация о методе AddForce из официального справочника по скриптам Unity3d

PS: Всем хороших и плодотворных выходных
Денис Исламов @DisaDisa
карма
45,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (19)

  • +1
    Спасибо, довольно детальные, и интересные уроки, как раз то что нужно для быстрого старта. В переводе читать их несколько приятнее :)
  • 0
    А какие отличия Unity3d от blender?
    • +5
      Примерно такие же, как и у фотошопа от офиса.
      Продукты решают разные задачи.
    • 0
      Это гейм движек. А то визуализатор.
  • 0
    Я движком в блендере не пользовался, поэтому от себя ничего уверенного сказать не могу. Но, на форуме Юньки этот вопрос как-то уже поднимался
  • 0
    кр-сть — с. тал.
  • 0
    Да и не понятно, то ли урок по Unity, то ли по C#.
    • 0
      Я же писал, в предыдущем топике: «Данная статья представляет из себя первый набор базовых (из раздела Beginner) уроков. Уроки в основном нацелены на изучения скриптинга и использования компонентов.»

      И где, кроме моего примечания, тут изучения C#? Изучение библиотек Unity имеет косвенное отношение к изучению шарпа.
  • 0
    Как скоро будет продолжение? Судя по времени между публикациями — где-то через месяц?
    • 0
      Извиняюсь за перерывы — работа и учеба :/ Самому хотелось бы сделать в течении ближайших 2х недель, пока буду в командировке.
  • 0
    Реквестирую туториал, объясняющий как сделать исполняемый файл с моей игрой и дать поиграть другу.
    • 0
      Нажать File->Build, выбрать операционку.
  • 0
    Урок 05 — создаётся паразитный объект по координатам 0 0 0, его можно увидеть в списке.

    Лучше сделать так:

    void Start () { GameObject instance = Instantiate(thePrefab, transform.position, transform.rotation) as GameObject; }
    • 0
      В ближайшее время поправлю.
      • 0
        Да перенесите же вы изображения статей на habrastorage.org. Уже половина не отображается!
  • 0
    C учетом того, что Unity выдает предупреждение об отсутствии использования переменной instance.
    Assets/Creater.cs(10,23): warning CS0219: The variable `instance' is assigned but its value is never used

    В уроке 5 лучше использовать следующий скрипт.

    public GameObject thePrefab; void Start () { Instantiate(thePrefab, transform.position, transform.rotation) ; }

    Р.S. Спасибо за не видео уроки Unity на habrahabr. При моем скоростном интернете самое то.)

  • 0
    Да перенесите же вы изображения на habrastorage.org. Уже половина не отображается!
    • 0
      Странно, у меня все, кроме одного изображения показывает.
      • 0
        Ну, я конечно утрирую, но несколько изображений уже не показывается и остальные очень медленно загружаются, со временем и они перестанут быть доступны. Просто потому как подобные сервисы не расчитаны на неограниченное время доступности изображений (так же как и многие файлопомойки):

        If the image in question is not accessed a single time in one year, they will remove it.

        Что означает, если в течение года к изображению не обращаются хотя бы раз, то оно удаляется…
        Пользуйтесть habrastorage.org, он для этого и был создан.

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