Разработка игр
Unity3D
19 сентября 2011

Погружение в скрипты игрового движка Unity3d, ч.1

Из песочницы
Доброго времени суток, уважаемый читатель! На Хабре неоднократно публиковались статьи о разработке игр с использованием замечательного движка Unity3d. Большинство этих статей были посвящены вполне определенным задачам, я же хотел сделать общий экскурс в данный движок. Данная часть будет посвящена наиболее часто используемым скриптовым методам и объектам, которые используются мной в процессе разработки на данном движке. Примеры я буду приводить на JavaScript, как на наиболее близком мне языке.

Игровой объект


Создание нового игрового объекта с именем MyObject.
var myObject = new GameObject("MyObject");
Созданный объект будет доступен по ссылку myObject.

Поиск объекта по его имени.
var myObject = GameObject.Find("MyObject");


Теги можно использовать для помечания группы объектов со сходными свойствами, либо использующиеся в единой сцене.
Поиск объекта по тегу, возвращает единственный объект:
var myObject = GameObject.FindWithTag("MyTag");


Возвращает список всех объектов с указанным тегом:
var objectList = GameObject.FindGameObjectsWithTag("MyTag");


Проверка на наличие у объекта требуемого тега. Возвращает true, если у указанного объекта имеется тег MyTag:
var isCompare = GameObject.CompareTag("MyTag");


Уничтожение объекта:
Destroy(myObject);


Уничтожение объекта через минуту, после его создания:
Destroy(myObject, 60);


Возвращает компонент component, привязанный к объекту GameObject, либо null, если объект не содержит данного компонента. Может использоваться, например, для доступа к другим скриптам, привязанным к объекту.
var objectComponent = GameObject.GetComponent(component);


Возвращает все имеющиеся у объекта компоненты типа componentType.
var objectComponents = GameObject.GetComponents(componentType);


Привязать компонент myComponent к объекту GameObject и получить ссылку на него.
var component = GameObject.AddComponent(myComponent);


Положение игрового объекта



Свойство transform объекта GameObject содержит в себе данные о положении объекта в игровом мире.

Возвращает глобальные координаты объекта в игровом мире. Возвращаемая величина имеет тип Vector3, который представляет из себя список из 3 координат — x, y и z:

var position = GameObject.transform.position; 
var x = position.x;


Переместить объект в точку 0, 10, 0 игрового мира.
GameObject.transform.position = Vector3(0, 10, 0);


Тоже самое, что и в случае глобальных координат, но с локальными. Локальные координаты расситываются относительно родительского объекта. В случае отсутствия родительского объекта локальные координаты совпадают с глобальными:
var localPosition = GameObject.transform.localPosition; 
var x = localPosition.x;


Поворот объекта в углах Эйлера. Метод также возвращает координаты в виде объекта Vector3:
var eulerAngle = GameObject.transform.eulerAngles;


Тоже самое, что и предыдущий пример, но поворот объекта рассчитывается относительно родительского объекта:
var localEulerAngle = GameObject.transform.localEulerAngles;


Текущий угол поворота объекта, основанный на кватернионах. Возвращает объект типа Quaternion.
var quaternionAngle = GameObject.transform.rotation;


Текущий поворот объекта, основанный на кватернионах, но относительно родительского объекта:
var localQuaternionAngle = GameObject.transform.localRotation;


Сброс угла поворота объекта:
GameObject.transform.rotation = Quaternion.identity;
GameObject.transform.localRotation = Quaternion.identity;


Вращаем наш объект в указанную сторону со скоростью 1 градус в секунду. Принимает в качестве координат объект типа Vector3. Метод deltaTime объекта Time содержит время в секундах, затраченное на выполнение предыдущего кадра:
GameObject.transform.Rotate(Vector3.left * Time.deltaTime);


Тоже самое, что и предыдущий пример, но вращение объекта относительно координат родителя:
GameObject.transform.localRotate(Vector3.left * Time.deltaTime);


Перемещаем наш объект в указанном направлении со скоростью 1 юнит в секунду. Также принимает в качестве координат объект класса Vector3:
GameObject.transform.Translate(Vector3.up * Time.deltaTime);


Физические свойства игрового объекта


Метод rigidbody объекта GameObject хранит в себе его физические свойства. Прежде, чем использовать метод rigidbody, его необходимо добавить к игровому объекту.

Получаем/задаем вектор скорости объекта:
var velocity = GameObject.rigidbody.velocity;
GameObject.rigidbody.velocity = Vector3(0, 1, 0);


Сила противодействия объекта. Может использоваться для замедления скорости, в среде с отсутствующей силой трения. Наиболее часто используется для замедления падающих объектов, например при создании парашюта. Принимает в качестве параметра целое число:
GameObject.rigidbody.drag = 100;


Задание массы объекту. Рекомендуется использовать массу в пределах от 0.1 до 10. Использование слишком больших значений может привести к непредсказуемым результатам при расчете физики:
GameObject.rigidbody.mass = 5;


Влияние на объект гравитации. Принимает в качестве параметра булево значение. Позволяет отключить влияние гравитации на отдельные объекты:
GameObject.rigidbody.useGravity = false;


Влияние физики на игровой объект. Позволяет отключить частично, либо полностью влияние физических законов на объект:
GameObject.rigidbody.isKinematic = true;


Запрет на вращение объекта. Наиболее часто используется, когда необходимо сохранить определенный угол поворота даже после столкновения с другими объектами:
GameObject.rigidbody.freezeRotation = true;


Указание координат точки центра массы объекта. Применяет координаты в виде уже знакомого нам объекта Vector3.
GameObject.rigidbody.centerOfMass = Vector3(1, 0, 0);


Использовать ли для объекта обнаружение столкновений с другими объектами. Можно выключить, тогда ваш объект будет игнорировать любые столкновения:
GameObject.rigidbody.detectCollisions = false;


Режим определения столкновений между объектами. Можно указать несколько разных режимов:
CollisionDetectionMode.ContinuousDynamic для быстро движущихся объектов;
CollisionDetectionMode.Continuous для столкновений с быстро движущимися объектами;
CollisionDetectionMode.Discrete (по умолчанию) для обычных столкновений;
В случае отсутствия проблем с определением столкновений рекомендуется использовать свойство по умолчанию.

Задать плотность объекта:
GameObject.rigidbody.SetDensity(1.5);


Применить импульс к объекту с указанным вектором. В результате применения импульса объект придет в движение пропорционально силе импульса.
GameObject.rigidbody.AddForce(5, 0, 0);


Применить импульс к объекту с вектором в его (объекта) системы координат:
GameObject.rigidbody.AddRelativeForce(0, 0, 5);


Добавить объекту крутящий момент. Применение данного метода заставит объект вращаться вокруг своего центра масс GameObject.rigidbody.centerOfMass.
GameObject.rigidbody.AddTorque(0, 1, 0);


Тоже самое, что и предыдущий пример, но относительно координат объекта:
GameObject.rigidbody.AddRelativeTorque (1, 0, 0);


Применение импульса к объекту из внешней указанной точки. Заставляет объект двигаться и вращаться одновременно. Может использоваться, например, для симуляции попадания в объект пули. Первый параметр указывает вектор направления силы, второй параметр — исходную точку направления силы.
GameObject.rigidbody.AddForceAtPosition(Vector3(0, 5, 7), Bomb.transform.position);


Для полноценной симуляции объемных взрывов в Unity3D есть отдельный метод. Первый параметр метода позволяет указать мощность импульса, второй параметр — точку, из которой исходит импульс, третий параметр — радиус распространения импульса, четвертый параметр — модификатор сжатия сферы распространения силы, пятый, необязательный, параметр указывает тип используемого импульса:
GameObject.rigidbody.AddExplosionForce(power, explosionPos, radius, 2.0);


Заставить объект «уснуть», и запретить дальнейший расчет физических показателей для него:
GameObject.rigidbody.Sleep();


Проверить «заснул» ли объект:
GameObject.rigidbody.IsSleeping();


«Разбудить» объект для возможности дальнейшего применения влияния физики на него:
GameObject.rigidbody.WakeUp();


Трассировка лучей


Один из самых часто используемых в разработке на Unity3D объект, это Ray. Данный объект позволяет выпустить луч из указанной точки, в указанном направлении, и вернуть некоторые свойства объектов, которых он смог достичь.

Создаем объект класса RaycastHit, который содержит информацию об объекте, с которым столкнулся луч:
var hit : RaycastHit;


Отправляем луч длиной в 50 юнитов из позиции rayPosition в направлении rayVector, и заносим объект, с которым столкнулся луч в переменную hit:
Physics.Raycast(rayPosition, rayVector.forward, hit, 50);


Получаем дистанцию до объекта, с которым столкнулся луч. Дистанция не может быть больше, чем протяженность луча:
var distance = hit.distance;


Иногда бывает необходимо получить имя объекта, с которым произошло столкновение луча. Наиболее простой способ это сделать:
var objectName = hit.collider.gameObject.name;


Для получения тега объекта используем следующий способ:
var Tag = hit.collider.tag;


Unity3D содержит еще множество различных методов и объектов, полезных и не очень. К сожалению полный их обзор увеличил бы и без того объемную статью, поэтому я постараюсь рассказать об остальном более подробно в будущем, если мне представится такая возможность. Я бы хотел пожелать опытным разработчикам побольше интересных проектов, а начинающим — успехов и интересных открытий. Спасибо, что уделили внимание данной статье.

UPD. вторая часть (скриптовые события).
+34
190,6k 285
Комментарии 34