Unity3D это игровой движок 3D-игр в основном стрелялок и аркад, но при большой сноровке можно реализовать и RPG, RTS, квесты, 2D-игры, встраиваемые в браузер, iPhone и с использованием сети. Движок понимает множество разные форматы файлов
- 3д модели и анимация из Maya, Cinema 4D, 3ds Max, Cheetah3D, Modo, Lightwave, Blender. Форматы 3ds, fbx и dae
- практически все растровые изображения для маск и текстур
- звуковые mp3, wav форматы для эффектов и фона
Профессиональная версия имеет более расширенные возможности по работе с динамическим освещением, сетевыми возможностями. Но даже без наличия блокбастерных игр о которых все бы слышали, unity успешно продвигается в плане комьюнити и «народного движка» и вполне возможно что с бесплатными плагинами можно будет написать игру ничем не уступающую платным.
IDE
Графическая оболочка разработчика (IDE) состоит из 4 основных панелей
- Графическое поле, переключающееся / вид игры (Game & Scene)
- Иерархия объектов (Hierarchy)
- Инспектор объекта (Inspector)
- Библиотека доступных ресурсов (Assets)
Создание карты
Карта (Terrain) создаётся очень просто из меню и по умолчанию уже есть. Курсором как в фотошопе можно изменять высоту рельефа (в том числе используя Shift). Более продвинутые господа придумали как импортировать карты из реального мира с помощью google earth, openTDD, делая так называемые heightmaps. Встроенный импорт работает только с raw форматами, надо использовать хак. Недавно вышел генератор карт.
Игровой объект Unity
Игровой объект может состоять из скриптов-компонентов, некоторые из них встроенные, некоторые надо писать самому, тоесть:
- Местоположения (Transform)
- Внешнего вида (Mesh)
- Модели столкновения (Collider)
- Твёрдое тело (Rigidbody)
- Управляемый пользователь (CharacterController)
Свои скрипты добавляются очень легко перетаскиванием в инспектор и публичные переменные сразу переводятся в названия с пробелами и значением по умолчанию. Для игрового объекта добавленные компоненты и с точки зрения ООП являются инкапсулированными объектами, хотя и играют в большинстве своём роль свойств (т.е. прилагательных - движущийся, крутящийся, выбираемый и тп.). По синтаксису скрипты пишутся на Javascript, C# или Boo скриптах со своими прибамбасами - глобальными объектами Unity, некоторыми своими ключевыми словами..
Взаимодействие объектов
Теперь когда понятно что игровое пространство состоит из кучи моделей у которых есть свои свойства и своё поведение встаёт вопрос а как же сама игра должна писаться. В отличие от desktop- и web- приложений, игры и сетевые приложения более асинхронны и поточны, тут как правило нет монолитных глобальных классов - объекты общаются между собой и в этом сила масштабирования - надо просто объекту написать события которые он поддерживает согласно игровой механике.
Поскольку объекты можно вкладывать друг в друга как dom-блоки, то
искать по иерархии объекты можно несколькими путями. Жалко что ребята
изобретали велосипед, вместо того что-бы взять существующие аналоги из
html/js
- Сразу писать название компонента скажем myWorkerGuy.someColorParam
- Поиск по иерархии - transform.Find("MyWorkerGuy") - аналог html'ного getElementById
- По тєгам, через GameObject.FindWithTag ("Worker")
Компонент объекта доступен через - GetComponent("Moveable").
Ещё
одно мощное решение - вместо поиска объекта с проверкой наличия метода
и затем вызова его, можно просто послать сообщение - gameObject.SendMessage("BegForFood",true), причём метод вызывается у всех компонентов.
Каждый компонент наследует класс Monobehaviour
(в Javascript синтаксисе объявлять не нужно) и именно с ним приходится
работать описывая логику и расширяя наследуемые методы которые сами
вызываются когда движок решит это нужным, например:
- Invoke - вызов третьего метода, в том числе периодический, аналог call_user_method в php + cron
- Awake - своего рода конструктор, вызывающийся когда все объекты уже существуют.
- Start - конструктор второго рода, вызывается после Awake
- Update - вызывается каждый фрейм. Сюда идёт основная логика.
- FixedUpdate - вызывается каждый n-фрейм, полезен для вычислений твёрдых тел
- LateUpdate - вызов после всех Update вызовов, полезен для камеры
- OnGui - сюда идёт показ кнопок, цифр для управления
Реальные нужды
После того как вы придумаете историю, надо продумать основные технические моменты. К этому моменту вы знаете что есть объекты и их характеристики (компоненты), но из чего состоит процесс игры?
- Рождение (Spawn) юнитов и врагов. Объект создаётся с указанием, где и с каким вращательным моментом. Как оказывается нарожать много умных юнитов с поддержкой всех фич (в частности физики) очень нагружает процессор.
GameObject go = Instantiate (building,hit.point,Quaternion.identity) as GameObject; -
Управление камерой. Существуют уже заранее сделанные компоненты-скрипты на всякие случаи жизни, которые учитывают в том числе столкновение камеры со стеной и тп. Вот часть кода для изометрической камеры (добавьте остальные направления сами)
if (Input.GetKey ("up") && transform.position.z<terrain.terrainData.size.z) {
transform.position += linearSpeed*Vector3.forward* Time.deltaTime;
}
if(Input.GetAxis("Mouse ScrollWheel")>0 && transform.position.y>1){
transform.position -= linearSpeed*Vector3.up* Time.deltaTime;
} - Выделение юнитов мышкой. Достаточно сложная задача - в кратце на камеру вешается обработчик нажатий и передвижения курсора. Независимо создаётся singleton-объект для хранения всех юнитов. При нажатии и передвижении курсора происходит проекция прямоугольника с маской ландшафта. Задача не из лёгких, потому что обрабатывать надо и deselect, учитывать клики для передвижения и атаки, рождение юнитов и тп. Возможно singleton не самое хорошее решение и лучше это сделать тэгами.
mouseButton1UpPoint = screenPosition;
var hit : RaycastHit;
ray = Camera.main.ScreenPointToRay (screenPosition);
if ( Physics.Raycast (ray, hit, raycastLength, terrainLayerMask) )
{
selectionPointEnd = hit.point;
UnitManager.GetInstance().SelectUnitsInArea(selectionPointStart, selectionPointEnd);
} - Поиск пути (Pathfinding) и передвижение юнита кликами мышки очень алгоритмически увлекательная задача. К счастью существует отличное решение Арона Гранберга. Алгоритм A* интересно в теории, но в редакторе можно и запутаться. Основная идея в том что юниты имеют дискретную сетку клеток для расчёта передвижения. Сетка генерируется из ландшафта и можно задать ограничения по углу наклона, максимальной высоте и тп. В плане кода - очень сложная штука. На практике его решение подразумевает что у каждого передвигаемого объекта есть Seeker компонент которому прицеплена цель куда надо дойти. При установки цели буквально надо выполнить
GetComponent("Seeker").StartPath (transform.position,destinationPoint);
Seeker расчитает путь по которому можно добраться до цели (обычно это ломанная кривая из 3х отрезков) и дальше уже своими силами надо реализовывать передвижение по этим точкам. - Движение юнитов. Пожалуй самое сложное, поскольку если юниты обладают физикой то это усложняет задачу. Надо просто понимать что нельзя сказать юниту x=x+1 через фиксированные участки времени. По идее надо использовать rigidbody.AddForce и учитывать ситуации OnCollision. Ещё одна проблема - повороты объекта. Они далеко не простые
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
Минусы и сложности
К этому времени вы вероятно заметили что спецификация есть, IDE работает, комьюнити и примеров хватает - можно попробовать. Но надо и холодный душ принять. Вот список недочётов что я заметил- Падения. Движок падает в разных случаях - как от неосторожного движения с интерфейсом, пробного Run с косячным скриптом, так и просто при работе. Порой обидно что «не сохранился».
- Глюки интерфейса. Это не так критично как падения, но мозги плавятся. Например проблема с зумом колёсиком мышки - камера перелетает килопиксели , не давая плавно подобраться к нужной сцене. Или например если вы импортировали модель с большим числом текстур или mesh-форм, будьте уверены что в следующий раз диалоги с таким содержанием будут забиты ненужными значениями.
- Глупый GUI. Во времена когда HTML5 реализуется всеми браузерами, тут приходится писать очень странный код, напоминающий layout в Java Swing (sic!) и порой вычитывать недокументированные особенности на форуме (например что при декларации кнопки его onclick event сразу внутри скобок, а вот как получить onmouseover и другие события или изменить её дизайн - та ещё тайна).
- Синтаксис. Согласен - трёхмерный мир это сложно и я даже могу понять почему используются математические термины типа кватерниона вместо "поворота в пространстве", но почему нельзя использовать короткие методы для основных функций, или почему нельзя в JS создавать глобальные объекты.
- Дебаг. Из-за того что код размыт на объекты-компоненты очень сложно организовывать нормально проект и как следствие сложно дебагить, даже несмотря на консоль, подсветку и возможность поменять значения на лету. Сложно и оттого что Scite который по умолчанию редактирует скрипты не знает никаких подсказок о пространстве переменных Unity, не умеет ничего подсказать, нельзя перепрыгнуть в нужное место как то привычно в других языка и IDE.
Расширения
Unity позволяет не только писать скрипты под существующие объекты, но и изменять саму IDE добавляя новые панели управления и меню, то движок можно расширить своими мини-фреймворками- Explosion- многопараметрические взрывы (цвет, взрывная волна, дым, размеры)
- Locomotion - движение людей и зверюшек c вызовом нужной анимации при соответсвующих вводах с клавиатуры
- Skydome - динамическое небо
- Last Bastion Games - диалоги, recorder, прототип RTS и гонок
- LearnMeSilly - набор основных уроков по работе с редактором, объектами
- Blender - бесплатный редактор. Можно в нём создать модели и экспортировать в 3ds
- Turbosquid - коллекции 3д моделей (в т.ч. платные)
- Unity3D Answers - своего рода база проблем и решений
Комментарии
P.S За новый дизайн сайта респект. Стильненько так
js применяю для прототипинга, позже программист перетряхивает это в C# код в студии экспрессной
unity+blender+audacity+gimp+tortouseSVN=бесплатная разработка игр)
с вашим интеллектом вам только UDK пользоваться
пишите глупости не разобравшись.
и что это за бред - "...в основном стрелялок и аркад, но при большой сноровке можно реализовать и RPG, RTS, квесты..."?
это движок а не конструктор! логика стрелялок и аркад самая простая, потому и используют её в туториалах чтобы не нагружать людей лишним кодом.
я понимаю вы не ладите с программированием, но даже если вы гейм дизайнер вы должны иметь хоть какой то опыт, прежде чем писать обзор на движок.
2) Чтобы переместиться к объекту в сцене, самый глупой вариант - это серфить к нему клавиатурой и мышью. Вначале бы хоть прочитали как интерфейс работает... Скажу по секрету, то что вы описали делается одним щелчком мыши.
дальше лень писать стало