Эта тема специально создана для первичного обучения азам скриптинга на Unity Js. Здесь консультируемся по этим вопросам.
АЗЫ СКРИПТИНГА на UNITY Js.
Из чего состоит сам скрипт? Разобьем содержимое на части. Но начнем с того что строки скрипта комп считывает по порядку очередности (сверху, вниз), запомните это и учитывайте во избежание недоразумений. Скрипт всегда нужно начинать с обьявления переменных которые будут задействованы в данном скрипте, ибо сам унити их за вас сочинять скорее всего не станет. Рассмотрим все выше написанное на простом примере живого скрипта. Допустим мы хотим поставить на сцену простой куб и заставить его двигаться (колебаться) влево, вправо. Что нам понадобиться в 1 очередь? Как и писал выше начнем наш скрипт с обьявления переменных. Давайте подумаем какие значения нам понадобиться в них хранить (ибо известно что в коде переменная являеться своеобразным контейнером для хранения значений, которые можно изменять, проверять и присваивать другим переменным и параметрам обьектов). Для данного случая нам понадобиться прежде всего переменная - скорость движения куба, чтобы урок проще было усвоить я буду использовать самые простые методы. Двигать куб в коде мы будем только через transform, вернее мы будем изменять из кода значения в его ячейках (трансформ находиться в инспекторе, справа, вверху), как мы знаем он отвечает за позицию, поворот и массштабирование обьекта, вот на эти параметры мы и будем воздействовать. Как я и писал для скрипта нам нужна в 1 очередь скорость, из чего состоит параметр скорости - из расстояния проходящего обьектом за промежуток времени и из непосредственно отрезков времени задержки (пауз) выполнения строк кода, если не делать пауз, то обьект будет перемещаться мгновенно, и незаметно глазу. Мы же собираемся сделать его движение по возможности плавным. Поэтому для параметра скорости я создаю 2 переменные - это moveDistanse - расстояние и moveTime - отрезок времени паузы между строками действий, из этих 2 параметров будет складываться скорость передвижения обьекта. Начинаем писать скрипт, обьявляем наши переменные:
Код
var moveDistanse = 1; var moveTime = 0.1;
Сразу оговорюсь что значения пока берем от балды, их всегда можно поменять. Здесь настало время немного рассказать о типах переменных в данном концепте, а именно если мы перед переменной пишем var, то такая переменная доступна в инспекторе и ее значение можно менять не открывая скрипта, прямо там же. Если припишем перед переменной private var, то эта переменная будет работать локально внутри скрипта, но не будет доступна из инспектора (будет скрыта). И 3 тип - это static var, такая переменная недоступна в инспекторе, но работает внутри скрипта локально, а так же доступна из и видима из любого другого скрипта, иными словами - это не что иное как глобальная переменная. И вызывать ее можно так:
Код
Имя скрипта.имя переменной = ХХХ;
Для изменения значения например:
Код
Weapons.reload = true;
Для условия:
Код
if (Weapons.reload == true) { // тут наши действия по условию. }
Вернемся к нашим баранам (переменным)... мы их обьявили и дали им первичные значения. Дальше - чтобы выполнить какие либо действия в нашем скрипте, мы должны их (действия) так же описать кодом. Но! код действий обязательно должен быть прописан внутри функций. Что из себя представляет червяк по кличке *функция*? Это собственно отрезок кода, который помещаеться вовнутрь этой самой функции (между скобок {}, после вызова cамой функции), выглядет в коде примерно так:
Код
function Blabla () { // тут участок кода // тут участок кода // и т.д. }
Функции в унити вызываються, запускаються и работают по определенным правилам. Фунции деляться на встроенные специфические и те что создаем мы сами в своем коде. Внимание! Создаваемые нами функции не должны совпадать именами с встроенными! Итак немного выше мы с вами создали функцию (в примере). Вызвать ее и заставить выполниться можно выполнив действие вызова функции. Кокретно для приведенного примера код вызова будет выглядеть так:
Код
Blabla ();
такая команда введенная в скрипте, заставит запуститься участок кода между скобками этой функции и выпониться 1 раз. Если команда будет повторяться, то функция будет выполняться все время.
Это что касательно созданных нами функций. Теперь немного о встроенных функциях которые нам понадобяться для нашего урока. (об остальных, вы можете узнать, почитав скрипт референсе, когда немного научитесь стоять на ногах прогера ) Итак я перечислю несколько функций первой необходимости и опишу как они работают... 1. function Start - вызываеться движком, только один раз при старте. Очень удобно, чтоб присвоить переменным разовые значения. Например при смене оружия указать магазину на сколько патронов он должен заряжаться. 2. function Update () - вызываеться самим движком игры, каждый кадр и не зависимо от нашего желания. Самая быстрореагирующая функция, но так же и самая грузящая двиг и самая пожирающая ресурсы. Применяеться только по необходимости, например для управления контроллером и камерой. 3. function LateUpdate - тоже вызываеться движком, тоже выполняеться каждый кадр, но в самом коце скрипта, после всех остальных команд и т.д. 4. function FixedUpdate - эта функция вызываеться движком через определенные промежутки времени и скорость ее повторения не зависит от частоты кадров (fps). В основном применяеться для работы физики в игре. Наиболее рекумендуемая функция для постоянного контроля чего нибудь. Обратите внимание на большие буквы в имени функций! Все функции имеют имена с первой заглавной буквой. Функции так же можно вызывать из других скриптов, но об этом в текущем уроке мы говорить не будем... (может когда нибудь в следующем). Итак мы с вами узнали структуру скрипта, из чего он состоит и как это дело приблизительно работает. Думаю самое время попытаться нам самим что нибудь написать... Я буду писать скрипт и делать подробные коментарии к каждой строке кода (все что написано в скриптовой строке через *//* не читаеться как код), а ваша задача следить за мыслью. Итак поехали:
Код
var moveRange = 1; // обявил публичную переменную хранящую значение расстояния. var moveTime = 1; // обьявил публичную переменную хранящую значение времени. private var range = 0; // обьявил локальную переменную расстояния. private var time = 0; // обьявил локальную переменную времени.
function Start () { // запускаем функцию Старт. range = moveRange; // присваиваем значение. time = moveTime; // присваиваем значение. } // закрываем функцию.
Можно применить static function, а можно и мессаги посылать. Можно даже вызывать функции с помощью статических переменных (заглушек). Кому как нравиться. X.cor.R (Prologue)
ну вобщем да... только точно не помню... там аргументы играют важную роль - SendMessageOptions.DontRequireReceiver Если не прописать, отправитель вроде будет отклика ждать... и выводить в логе что ответ не получен, как то так... X.cor.R (Prologue)
1. Нужно учитывать, что вызываются все методы с таким именем в этом GO. Т.е. если у Вас висит несколько скриптов, то во всех скриптах вызывается метод с таким именем. 2. Вторым параметром SendMessage можно передать в этот метод любой объект (например просто число - уровень разрушения). 3. Третий параметр - именно SendMessageOptions. Если не важно чтобы получатель точно получил сообщение, то лучше писать именно endMessageOptions.DontRequireReceiver иначе выдаст ошибку при отсутствии приемника. 4. SendMessageUpwards вызывает метод с данным именем не только на данном GO, но и на его "предках" в иерархии. 5. BroadcastMessage наоборот на GO и всех его детях. 6. SendMessage -ами нужно разбрасываться с осторожностью. Очень хорошая фича, но относительно медленная. Особенно SendMessageUpwards и BroadcastMessage. Есть альтернативы - делегаты, Action, Func.
seaman, всё)) Спасибо! С функциями почти разобрался! И последнее что не понял:а как остановить функцию? Вот смотрите: Я из скрипта меняю значение переменной в другом скрипте по условию. И у меня всё меняется правильно! После того,при другом условии я снова меняю значения,но на другие(изна4альные). И второе условие не срабатывает! То есть первый раз работает,второй нет! Неплохо знаю JavaScript(Unity3D API) =)
var maximumHitPoints = 200.0; var hitPoints : float; var regenerationSpeed : float = 5; var painLittle : AudioClip; var painBig : AudioClip; var die : AudioClip; var deadReplacement : Rigidbody; private var gotHitTimer = -1.0; var healthGUI : GUITexture; private var healthGUIWidth = 100.0; var damage : GameObject; var explShake : GameObject; var xrom : AudioClip;
function Awake () { healthGUIWidth = healthGUI.pixelInset.width; }
function PlayerDamage (damage : int) { if (hitPoints < 0.0) return;
// Apply damage hitPoints -= damage;
// Play pain sound when getting hit - but don't play so often if (Time.time > gotHitTimer && painBig && painLittle) { // Play a big pain sound if (hitPoints < maximumHitPoints * 0.2 || damage > 100) { audio.PlayOneShot(painBig, 1.0 / audio.volume); gotHitTimer = Time.time + Random.Range(painBig.length * 2, painBig.length * 3); } else { // Play a small pain sound audio.PlayOneShot(painLittle, 1.0 / audio.volume); gotHitTimer = Time.time + Random.Range(painLittle.length * 2, painLittle.length * 3); } }
// Are we dead? if (hitPoints < 0.0) Die();
if (hitPoints < 25.0) Xrom();
if (hitPoints > 76.0) NetXrom(); }
function Die () { if (die && deadReplacement) AudioSource.PlayClipAtPoint(die, transform.position); var dead : Rigidbody = Instantiate(deadReplacement, transform.position, transform.rotation);
// Disable all script behaviours (Essentially deactivating player control) var coms : Component[] = GetComponentsInChildren(MonoBehaviour); for (var b in coms) { var p : MonoBehaviour = b as MonoBehaviour; if (p) p.enabled = false; } }
function LateUpdate () { UpdateGUI(); }
function Update (){ //REGENERATION and damage effect if (hitPoints < 200.0 && hitPoints > 0.0) hitPoints += Time.deltaTime * regenerationSpeed; damage.guiTexture.enabled = true;
if (hitPoints > 198.0) damage.guiTexture.enabled = false; }
function Exploasion(){ explShake.animation.Play("exploasion"); }
function UpdateGUI () { var healthFraction = Mathf.Clamp01(hitPoints / maximumHitPoints); healthGUI.pixelInset.xMax = healthGUI.pixelInset.xMin + healthGUIWidth * healthFraction; }
Ну логику в этом можно найти. Второй раз проверяем <0 уже после вычитания дамаджа. И если верно - умерли. При следующем входе проверять уже не надо - просто сразу выходим. Тут другое дело, что Xrom вызовется и сразу после смерти персонажа. Т.е. если hitPoints < 0, то вызывается и Die, и Xrom