9 ноября 2012 в 13:50
Уроки Unity3d - Скрипт FPSWalker
Для просмотра любого скрипта Unity, вам нужно открыть его в редакторе скриптов. Для этого нужно выбрать скрипт в окне проекта (Project), а затем дважды кликнуть на его значке (или нажать кнопку Edit, в Inspector-е), чтобы открыть скрипт для редактирования.
На PC, редактор скриптов по умолчанию называется Uniscite. Это автономное приложение, которое позволяет вам редактировать различные форматы текстового файла, JavaScript и C # пример двух таких форматов.
Вы можете использовать и другие, удобные для вас, текстовые редакторы, для написания скриптов Unity.
Открытие скрипта.
Выберете объект First Person Controller в окне Hierarchy, затем кликните на имени скрипта в компоненте FPSWalker (Script) в Inspector, строка выделится синим цветом:
Таким образом, скрипт в окне проекта (Project) выделиться желтым цветом (см. следующий рисунок), чтобы помочь вам найти его. Откройте его в редакторе скриптов.]
Windows PC—FPSWalker в Uniscite.
На PC, скрипт FPSWalker откроется в редакторе скриптов по умолчанию UniSciTE:
Закрепим полученные знания о скриптинге, разобрав скрипт FPSWalker:
Объявление переменных.
Как и большинство скриптов, FPSWalker начинается с объявления переменных в строках 1-6:
JavaScript: var speed = 6.0; var jumpSpeed = 8.0; var gravity = 20.0; private var moveDirection = Vector3.zero; private var grounded : boolean = false;
В строках от 1 до 3 объявлены public переменные скрипта, которые будут использоваться в дальнейшем, как множители. Все три переменные имеют значение с плавающей точкой, поэтому это будет тип данных float (так как это простой пример скрипта от Unity Technologies, не у всех переменных определен тип данных). Строки 5 и 6 private переменные, поскольку они будут использоваться только в пределах скрипта. Private переменная moveDirection отвечает за хранение текущего направления движения игрока как Vector3 (X, Y, Z координаты). Vector3.zero - краткая форма для написания Vector3 (0, 0, 0).
Private переменная grounded имеет тип данных boolean (true или false). Эта переменная используется, для отслеживания стоит ли игрок на земле (поверхности), с тем чтобы позволить движение и прыжки, которые не были бы разрешены, если игрок в воздухе (то есть, если они в настоящее время прыгает).
Хранение информации движения.
В строке 8 начинается функция FixedUpdate (). Как и о функции Update(), о ней говорилось ранее – FixedUpdate() вызывается каждый кадр с фиксированной частотой кадров (called every fixed framerate frame).
Функция FixedUpdate() выполняется в диапазоне строк 8 - 27, таким образом, мы можем предположить, что все команды и условные операторы в пределах этой функции будут проверены каждый кадр.
В книги вы можете иногда заметить одну строку кода, разделенную на две, это сделано из-за нехватки места, объедините эту строку в вашем редакторе.
Первый условный оператор if в функции выполняется в строках 9 – 18 (комментарий разработчиков удален):
JavaScript: if (grounded) { moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); moveDirection = transform.TransformDirection(moveDirection); moveDirection *= speed; if (Input.GetButton ("Jump")) { moveDirection.y = jumpSpeed; } }
Все команды и вложенный условный оператор if (строка 15), будут выполнены, если переменная grounded будет равна true, т.к. ворожение в строке 9 – if (grounded) - можно записать следующим образом:
JavaScript: if (grounded == true) {
Если переменная grounded истинна, производится три действия над переменной moveDirection (строки 11-13).
Во-первых, переменной moveDirection назначается новое значение Vector3, в котором Х = Input.GetAxis("Horizontal") , Y = 0, а Z = Input.GetAxis("Vertical").
JavaScript: moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
В этом примере Unity Technologies использовало ключевое слово 'new' в качестве префикса для Vector3, при присвоении значения
переменной moveDirection. Сделано это для более простого преобразования кода из JavaScript в C #. Однако, это не является обязательным в JavaScript, поэтому вы не увидите использования 'new' в других примерах из этой книги.
Но что делать команда Input.GetAxis? Она возвращает значение между -1 и 1 в зависимости от нажатия горизонтальных или вертикальных клавиш, по умолчанию ими являются:
• A/D или Влево/Вправо — горизонтальная ось.
• W/S или Вверх/Вниз — вертикальная ось.
Если не нажата ни одна из перечисленных клавиш, Input.GetAxis будет возвращать 0. Если нажата клавиша Влево Input.GetAxis("Horizontal") вернет -1, когда Вправо вернет 1.
Иными словами, строка:
JavaScript: moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
присваивает переменной moveDirection значение Vector3, где X и Z основаны на нажатиях клавиш, оставляя при этом Y равным 0.
Далее, в строке 12 наша переменная moveDirection вновь изменяется:
JavaScript: moveDirection = transform.TransformDirection(moveDirection);
Здесь мы устанавливаем moveDirection в значение, основанном на TransformDirection компонента Transform. Команда TransformDirection преобразует локальные координаты XYZ в мировые. Так в этой строке, мы берем координаты XYZ moveDirection и преобразовываем их во внешние координаты. Вот почему в скобках после TransformDirection указана наша переменная moveDirection.
И под конец, в строке 13. умножим moveDirection на переменную speed:
JavaScript: moveDirection *= speed;
Т.к. speed это public переменная, и мы можем редактировать ее значение в Inspector-е, а умножение moveDirection на public, пропорционально изменяет XYZ значения переменной moveDirection, следовательно, мы можем регулировать скорость передвижения персонажа, не изменяя скрипта. Это происходит потому, что полученное значение moveDirection, используются далее в скрипте для перемещения персонажа. Перед завершением условного оператора if(grounded), есть еще один вложенный условный оператор if, в строках 15-17:
JavaScript: if (Input.GetButton ("Jump")) { moveDirection.y = jumpSpeed; }
Этот условный оператор отслеживает нажатие клавиши Jump (прижок). По умолчанию, прыжок (jump) назначен на пробел (Space bar). Как только эта клавиша нажата, Y составляющей переменной moveDirection присваивается значение jumpSpeed. Поэтому, если переменная jumpSpeed не была изменена в инспекторе свойств, moveDirection.y будет установлен в значение 8.0.
Далее в скрипте, когда мы будем перемещать персонажа, это резкое изменение от 0 до 8.0 даст эффект прыжка. А как же наш персонаж возвращения на землю? Объект нашего персонажа не имеет компонента Rigidbody, поэтому он не будет контролироваться силой тяжести физического движка.
Вот почему в 21 строке мы уменьшаем значение moveDirection.y:
JavaScript: moveDirection.y -= gravity * Time.deltaTime;[code]Обратите внимание, что мы не сразу опускаем персонажа на землю, и не просто отнимаем gravity от moveDirection.y, т.к. это приведет к нежелаемым эффектам, а мы вычитания переменную gravity умноженную на команду Time.deltaTime. Умножение любого значения в пределах функций Update () или FixedUpdate () на Time.deltaTime (время в секундах, затраченное на заполнение последнего кадра), избавляет вас от зависимости основанной на частоте кадров. И так, написав: [code]JavaScript: moveDirection.y -= gravity * Time.deltaTime;
мы фактически вычитаем значение силы тяжести каждую секунду, а не каждый кадр.
Перемещение персонажа.
Moving the character.
Как говориться в комментарии на строке 23, строки 24-26 отвечают за движение персонажа.
Вначале, в 24 строке объявляется новая переменная controller и определяется ее тип данных CharacterController. После чего, при помощи команды GetComponent(),
переменной присваивается ссылка на компонент Character Controller:
JavaScript: var controller : CharacterController = GetComponent(CharacterController);
Используя GetComponent(), ы можете получить доступ к любому компоненту, прикрепленному к объекту (к которому прикреплен скрипт), просто указав в скобках его имя.
Теперь, когда у нас есть ссылка на компонент Character Controller, мы можем получить доступ к его параметрам, атак же использовать функцию Move, для перемещения объекта.
В строке 25 мы и происходит перемещение персонажа. Результат движения помещается в переменную flags:
JavaScript: var flags = controller.Move(moveDirection * Time.deltaTime);
Функция CharacterController.Move принимает в качестве параметра Vector3, для это мы используем вектор moveDirection умноженный на Time.deltaTime (что бы скорость была метры в секунду, а не метры в кадр).
Столкновение с поверхностью.
Переменная moveDirection получает значения, только если логическая переменная grounded истинна (true). Так как же мы определяем, на земле мы или нет?
Сollider нашего персонажа (это Character Controller), как и любой другой collider-ы может обнаружить столкновение с другим объектом. Однако в отличии от стандартных collider – ов, Character Controller имеет четыре различных вида столкновения описанных в CollisionFlags. К ним относятся следующие:
• None
• Sides
• Above
• Below
Они отвечают за проверку столкновений, с определенной частью collider-а, который они описывают - за исключением None - это означает, что столкновения не происходит.
Эти флаги используются для установки нашей переменной grounded в строке 26:
JavaScript: grounded = (flags & CollisionFlags.CollidedBelow) != 0;[code]Выражение может показаться сложным, но это просто сокращенный способ проверки состояния и установка значения в одной строке. В скобках мы используем логическую операцию - побитовое 'и' (&), что бы определить соответствует ли результат нашего движения flags значению CollidedBelow: [code]JavaScript: (flags & CollisionFlags.CollidedBelow)
Побитовое 'и' (&) выполняются для каждой пары бит своих операндов.
Если наш Character Controller действительно столкнулся нижней частью, результат выражения не будет равен 0. Что мы и проверяем дальше, используя операцию сравнения 'не равно' (!=). Следовательно когда наш персонаж на земле grounded будет равен true.
Команда @Script.
Функция FixedUpdate() заканчивается в 27 строке, и остается последняя команда в этом скрипте:
JavaScript: @script RequireComponent(CharacterController)
@script команды используются для выполнения действий, которые обычно необходимо выполнять вручную в Unity Editor.
В этом примере, функция RequireComponent заставляет Unity добавить компонент, указанный в скобках, если объект, к которому прикреплен скрипт, не имеет данного компонента.
Так как наш скрипт использует CharacterController в коде, необходимо обязательное его присутствие в объекте.
7 мая 2015 в 11:50
lol
31 мая 2015 в 11:34
нармуль
авторизуйтесь
или войдите через