Unity3D. Создание RPG. Урок 2. Движение и анимация персонажа. Управление камерой.
Пролог. И снова здравствуйте. Это второй урок по созданию RPG на Unity3D. Изначально я хотел написать его не много по другому но планы у меня изменились и пришлось все предумывать. Сначала задумывалось делать 2 камеры с видо от первого лица и от 3, но в итоге я оставил только от третьего. Сегодня я все скрипты покажу вам полностью сразу и постораюсь объяснить малопонятные вещи в коде дабы экономить свое время и ваше. В прошлом уроке я забыл написать о «build», то есть непосредственно компиляции проекта.По этому мы сделаем это сейчас. Откроем наш проект. Если открылась пустая сцена нажмем «Ctrl+o» и откроем сцену которую мы делали на прошлом уроке. Нажмем «Ctrl+Shift+b» и в открывшемся окне нажмем «Add Current». Это поставит наше меню в список компилирования и даст ему порядковый номер. При открытии компилированного проекта первой открывается сцена под номером 0. Если нажмем «Build And Run» наш проект скомпилируется и запустится. План урока. 1) Импорт персонажа. 2) Передвижение персонажа. 3) Настройка камеры 4) Анимация персонажа. Импорт персонажа. Сцена. Создаем «Terrain» с размерами 200х200. Вешаем какую-нибудь текстуру для удобства отображения. Создадим источник света. Персонаж Возьмем заранее подготовленного персонажа с анимациями, я взял из «Asset Store»(«Window>>Asset Store» или Ctrl+9) персонажа с названием Blade Girl NPC. Эта моделька стоит 15$ Она у меня уже есть и я буду использовать именно её. Вы можете там же поискать бесплатные(Среди них есть достойные). или же просто в интернете поискать какие нибудь. В эту модель уже впихнута анимация различных действий, атака, бег и тд. и тп. и даже танец Гангнам Стайл))). После импорта находим находим в окне «Project» префаб персонажа, у меня он называется «Balde_girl_Prefab» и находится в папке «Blade_girl». Перетаскиваем этот префаб на сцену, и видим наш персонаж, только каойто он большой через чур, это не беда. В инспекторе в пункте «Scale» выставим все по единичке, и все хорошо становиться, моделька стала нормальных размеров, можно работать дальше
«Префаб — это один из типов ресурсов, предназначений для многократного использования и хранящийся в Project View. Префаб может быть вставлен в любое количество сцен и многократно в одну сцену. Когда префаб добавляется в сцену, создаётся его экземпляр. Все экземпляры являются ссылками на оригинальный префаб и фактически его клонами. Независимо от того, как много экземпляров в проекте, при изменении префаба изменяются соответственно и все его экземпляры.»
Нажимаем «Add component>>Physics>>Rigidbody» и «Add component>>Physics>>Capsule Collider». В «Capsule Collider» Выставляем размеры нашей капсулы что бы получилось как на картинке, слегка чуть больше модельки самой. В «Rigidbody» ставим галочку «Use gravity». Раскрываем вкладку «Constraints» и ставим все 3 галочки на «Freeze Rotation». Это нужно для того что бы наш персонаж не проваливался сквозь землю, не падал на землю если вдруг окажется на неровности и тому подобное. Программируем персонажа на перемещение. Создадим c# скрипт «movePlayer».
Код
using UnityEngine; using System.Collections;
public class movePlayer : MonoBehaviour {
private GameObject player; //Переменна объекта персонажа с которым будем работать.
public static int speed = 6; //Скорость перемещения персонажа. Запись public static обозначает что мы сможем обращаться к этой переменной из любого скрипта public static int _speed; //постоянная скорость перемещения персонажа public int rotation = 250; //Скорость пповорота персонажа public int jump = 3; //Высота прыжка
public static bool IsDrawWeapon; //Двоичная переменная, которая будет отвечать достануто ли у нас оружие. public static float x = 0.0f; //угол поворота персонажа по оси x void Start () { IsDrawWeapon = false; //По умолчанию оружие у нас спрятано. _speed = speed; //Задаем постоянное стандартное значение скорости персонажа player = (GameObject)this.gameObject; //Задаем что наш персонаж это объект на котором расположен скрипт }
void Update () { if(IsDrawWeapon == true) //Если оружие вытащено { speed = _speed * 2; // Меняем скорость передвижени(я это сделал потому что, у этой моделки нету анимаций движения простым шагом с мечом. а понижать скорость анимации у бега получиться не красиво) if(Input.GetKey(KeyCode.W)) //Если нажать W { player.transform.position += player.transform.forward * speed * Time.deltaTime; //Перемещаем персонажа в перед, с заданой скорость. Time.deltaTime ставится для плавного перемещения персонажа, если этого не будет он будет двигаться рывками } if(Input.GetKey(KeyCode.S)) { speed = _speed / 2; //При передвижениии назад снижаем скорость перемещения player.transform.position -= player.transform.forward * speed * Time.deltaTime; //Перемещаем назад } if(Input.GetKeyUp (KeyCode.S)) { speed = _speed * 2; //Возвращаем cтандартное значение } if(Input.GetKey (KeyCode.A)) { player.transform.position -= player.transform.right * speed * Time.deltaTime; //перемещаем в лево } if(Input.GetKey (KeyCode.D)) { player.transform.position += player.transform.right * speed * Time.deltaTime; //перемещаем в право } if(Input.GetKey (KeyCode.Space)) { player.transform.position += player.transform.up * jump * Time.deltaTime; //Прыгаем }
if(Input.GetKey (KeyCode.Tab)) //При нажатии и на кнопку Tab { IsDrawWeapon = false; //Мы спрячем наше оружие. } } else if(IsDrawWeapon == false) //Если оружие не спрятано. |||||| Сделано разделение на движения в зависимости от того вытащено ли у нас оружие или нет, потому что персонаж будет перемещаться сразной скорость у меня в этих случаях, как я уже написал из за отсутсвия некоторых анимаций у модельки. { speed = _speed;//Скорость в стандартное значение if(Input.GetKey (KeyCode.LeftShift)) //Если зажать левый Shift { speed = _speed * 2; //Увеличиваем скорость перемещения(бег) } if(Input.GetKeyUp (KeyCode.LeftShift)) //Если отпустить { speed = _speed; //Возвращаем стандартное значение } if(Input.GetKey(KeyCode.W)) //Если нажать W { player.transform.position += player.transform.forward * speed * Time.deltaTime; //Перемещаем персонажа в перед. } if(Input.GetKey(KeyCode.S)) { speed = _speed / 2; player.transform.position -= player.transform.forward * speed * Time.deltaTime; //Перемещаем назад } if(Input.GetKeyUp (KeyCode.S)) { speed = _speed; //Возвращаем cтандартное значение } if(Input.GetKey (KeyCode.A)) { player.transform.position -= player.transform.right * speed * Time.deltaTime; //перемещаем в лево } if(Input.GetKey (KeyCode.D)) { player.transform.position += player.transform.right * speed * Time.deltaTime; //перемещаем в право } if(Input.GetKey (KeyCode.Space)) { player.transform.position += player.transform.up * jump * Time.deltaTime; //Прыгаем } if(Input.GetKey (KeyCode.Tab)) //при нажатии на кнопку таб { IsDrawWeapon = true; //Мы вытащим наше оружие } }
//Поворачиваем персонажа. Так как наша переменная x глобальна, из скрипта камеры в неё будем записывать длину на сколько сместился указатель мыши и по оси X и относительно этого будет повернут наш персонаж Quaternion rotate = Quaternion.Euler (0,x,0); //Создаем новую переменную типа Quaternion для задавания угла поворота player.transform.rotation = rotate; //Поворачиваем персонаж
} }
Скрипт помещаем на персонажа. Управление камерой. Создадим еще один c# скрипт, и назовем его «moveCam»
Код
codeusing UnityEngine; using System.Collections;
public class CamMove : MonoBehaviour { public Transform target; //Объект за которым летаем(Наш персонаж) public float distance = 3.0f; //На каком ратоянии от него public float xSpeed = 125.0f; //Чуствительность по Х public float ySpeed = 50.0f; //Y Чуствительность public float targetHeight = 2.0f; //Высота относительно объекта //Минимальный и максимальный угол поворота Y инче камеру разверет, Дальше у нас будет простая функция для инвертации их в обратные числа public float yMinLimit = -40; public float yMaxLimit = 80; //Максимальное удаление и приближение камеры к персонажу, искорость. public float maxDistance = 10.0f; public float minDistance = 0.5f; public float zoomRote = 90.0f;
private float x = 0.0f; //Угол поворота по Y? private float y = 0.0f; //Уго поворота по X?
[AddComponentMenu("Scripts/Mouse Orbit")] //Добавляем в меню
public void Start() { //переворачивам углы Vector3 angles = transform.eulerAngles; x = angles.y; y = angles.x;
public void LateUpdate() { if (target) {//Если цель установлена(Персонаж) //Меняем углы согласно положению мыши x += Input.GetAxis("Mouse X") * xSpeed * 0.02f; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; //Меняем дистанция до персонажа. distance -= (Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime) * zoomRote * Mathf.Abs(distance); distance = Mathf.Clamp (distance, minDistance, maxDistance);
y = ClampAngle(y,yMinLimit, yMaxLimit); //Вызыв самописной функции для ограничения углов поврот movePlayer.x = x; //Повернуть камеру согласно поченым данным Quaternion rotation = Quaternion.Euler(y, x, 0); transform.rotation = rotation;
//Двигаем камеру и следим за персонажем Vector3 position = rotation * new Vector3(0.0f, targetHeight+0.5f, -distance) + target.position; transform.position = position;
//Следуйщи код нужен что бы камера не проваливалась по ланшафт RaycastHit hit; Vector3 trueTargetPosition = target.transform.position - new Vector3(0, -targetHeight,0); if(Physics.Linecast (trueTargetPosition, transform.position, out hit)) { float tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28f; position = target.position - (rotation * Vector3.forward * tempDistance + new Vector3(0, -targetHeight, 0)); transform.position = position; } }
Скрипт кидаем на камеру. Камера должна быть перемещена в префаб персонажа в окне «Hierarchy». А в компоненте скрипта на камере в поле «Target» долже быть помещен наш префаб из окна «Hierarchy». Анимация Создадим новый скрипт и назовем его «AnimatePlayer»
Код
using UnityEngine; using System.Collections;
public class AnimatePlayer : MonoBehaviour {
public void Start () { // Устанавливаем все клипы анимации в режим цикла animation.wrapMode = WrapMode.Loop; // Кроме следующих animation["Attack01"].wrapMode = WrapMode.Once; animation["jump"].wrapMode = WrapMode.Once; animation["Skill"].wrapMode = WrapMode.Once; //У них одиночное выполнение
//Останавливаем выполнение анимаций. animation.Stop(); }
public void Update () { // На основе нажатой клавиши выполняем анимацию if(movePlayer.IsDrawWeapon == false) //Если оружие не вытащено { if (Input.GetAxis("Vertical") > 0.0f) //Проверяем на изминениея позиции персонажа повертикали, если да { if(movePlayer.speed == movePlayer._speed * 2) //Проверяем скорость Передвижения персонажа, { animation.CrossFade ("Run00"); //Если зажата клавиша shift, значит грузим анимацию бега } else { animation.CrossFade("Walk"); //В противном случаее ходьбу } } else if(Input.GetAxis("Vertical") < 0.0f) //Далее все по анологии { if(movePlayer.speed == movePlayer._speed * 2) { animation.CrossFade ("B_Run00"); //бег назад } else { animation.CrossFade ("B_Walk"); //ходьба назад } } else if (Input.GetAxis("Horizontal") > 0.0f) { if(movePlayer.speed == movePlayer._speed * 2) { animation.CrossFade ("R_Run00"); //бег в право } else { animation.CrossFade ("R_Walk"); //Шагание в право }
//Анимация атаки if (Input.GetMouseButton (0)) //Если нажать маус 1 animation.CrossFade("Attack01"); //Включаем анимацию атаки if (Input.GetMouseButton (1)) //Если нажать маус 2 animation.CrossFade("Skill"); //Включаем анимацию скила } } }
Скрипт должен быть помещен на персонажа. В окне «Project» создадим папку «Prefab» и перетащим в нее префаб персонажа из окна «Hierarchy» что бы сохранить все на будущее и не повторять все заново. На сегодня все всем надеюсь моя статья вам будет полезна.
Категория: Создание игр | Добавил: rak (09 Ноября 2013)
| Автор: rak
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:
Игровые объявления и предложения:
Если вас заинтересовал материал «Unity3D. Создание RPG. Урок 2. Движение и анимация персонажа. Управление камерой.», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела.
Предлагаются такие схожие материалы:
Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.
Ребята, а у кого то персонаж является шариком? Мой персонаж (шарик) не катается а ползает по земле Как мне исправить? А так статья классная, все довольно доходчиво. Вот только не могу проблему решить с катанием..
Автор, умоляю исправь ошибку. "moveCam" и "CamMove" не одно и то же. У меня 4 часа жизни ушло чтобы найти ее. Ну и "codeusing" заодно, на нее ушло минут 5.
Писалось для версии Unity 4.3 если я не ошибаюсь(таки больше 2х лет прошло), ищи аналогичные функции для своей версии в справке, да и по факту тут описан фактичекски стандартный CharacterController так что ковырни стандартные ассеты