Продолжаем программировать движение куба

Всем доброго времени суток, сегодня я продолжаю учиться делать компьютерные игры, и буду продолжать программировать ездящий куб. Начало было в прошлой статье.

 

Запускаем наш прошлый урок, и смотрим на движение куба которое вышло и мы видим что получилось у нас так себе. Двигается он дергаясь, быстрое движение, остановка, быстрое движение. Можно сделать и получше, а так же чтобы при нажатии в право и лево наш куб не просто двигался в право, лево, а поворачивался. Давайте займемся этим.

 

Открываем прошлый урок и в файл Moving пишем следующий код:

Улучшенный скрипт движения
Dante

 

Для начала в скрипте, как можем видеть, мы задаем булевые переменные W, A, S, D. Далее задаем переменные ускорения acceleration‘, текущую скорость, то есть скорость с не нажатыми клавишами curSpeed‘, максимальную скорость maxSpeedи deltaSpeedя потом объясню зачем необходимо.

 

Затем мы в функции Update, задали вывод новой функции ElaborateMoving. Ну и потом сделали непосредственно саму функцию движения void ElaborateMoving. Начало в этой функции как вы можете видеть такое же как и в движении что мы рассматривали в прошлом уроке. Мы рассматриваем кнопки, не даем возможности нажиматься двум одновременно и приравниваем true, false.

 

Теперь давайте перейдем к той части которой не было в прошлый раз. Итак что же происходит дальше? Если нажалась наша кнопка W выглядит как if(W)‘, тогда { мы сначала проверяем чтобы текущая скорость меньше максимальной curSpeed<maxSpeed, тогда выполняется уравнение где к текущей скорости прибавляется ускорение curSpeed+=acceleration‘, иначе elseтекущая скорость приравнивается к максимальной curSpeed=maxSpeed. Это приравнивание нашей скорости к максимальной может быть чрезвычайно полезно при каких-либо внезапных сбоях программы.

 

Дальше мы рассматриваем кнопку S, если она нажатаif(S)‘. Задаётся функция которая будет выполняться if и затем непосредственно наша математическая функция Mathf.Abs(curSpeed)<maxSpeedэто берет максимальную скорость maxSpeedс отрицательным значением и сравнивает ниже ли это значение чем наша текущая скорость, короче то же что и выше только с отрицательными значениями. Если наша текущая скорость выше чем максимальная скорость, напомню что здесь имеется ввиду просто движение назад, то есть более простым языком если мы назад двигаемся медленнее чем максимальная скорость движения назад то выполняется формула и текущая скорость назад увеличивается что прибавляет ускорение к ней, так же как выше. Но так как нам необходимо прибавить отрицательную скорость то выглядит это в коде curSpeed-=acceleration, кто помнит алгебру минус на минус дает плюс. Иначе elseтекущая скорость приравнивается к максимальной скорости движения назад, то бишь к максимальной скорости движения с отрицательным значением.

 

Теперь давайте рассмотрим дальше, если не нажата ни та ни другая клавиша if(!W && !S)‘. Здесь у нас задается торможение, если текущая скорость выше нуля if(curSpeed>0)то мы её будем тормозить, то есть прибавим отрицательное ускорение curSpeed-=acceleration‘, следующая строка точно тоже самое, только если скорость была назад мы прибавляем простое ускорение, для того чтобы наша скорость стала равна нулю. Точно так же если скорость ниже нуля if(curSpeed<0) мы прибавляем ускорение для того чтобы она стала равна нулю curSpeed+=acceleration‘. Теперь мы берем значение модуля Mathf.Abs(curSpeed)и сравниваем если оно меньше deltaSpeed которую мы задали довольно низким значением, то текущая скорость становится равной нулю curSpeed=0‘.

 

Дальше мы рассмотрим поворот в право, если нажата кнопка Dif(D)‘. Здесь все точно так же как с передвижением, только используется скорость поворота, я взял модуль Mathf.Abs(curRotationSpeed) и сравнил его с максимальной скоростью вращения maxRotationSpeed, если не достигли то выполняется curRotationSpeed+=accelerationRotationпока не достигнем необходимой скорости вращения, иначе elseприравниваем к максимальной скорости вращения curRotationSpeed=maxRotationSpeed.

 

С кнопкой A все точно так же только прибавляется отрицательное вращение. Стоит попробовать самому разобраться. Пойду дальше.

 

Если не нажата ни кнопка D ни кнопка A, то как и в случае с W и S мы затормаживаем вращение. К примеру если вращение больше нуля curRotationSpeed>0 то мы прибавляем отрицательное ускорение вращения curRotationSpeed-=accelerationRotation‘. Так же если вращение отрицательное curRotationSpeed<0мы прибавляем обычное ускорение для того чтобы получить ноль curRotationSpeed+=accelerationRotation‘. Ну и сверяем модуль вращения с нашим значением deltaSpeedRotation для того чтобы при медленном вращении, у нас не было странных дерганий, к примеру если у нас вращение к примеру меньше единицы там пусть -0.4 а скрипт ускорение добавляет пусть будет по 1, комп думает надо добавить скорость, и добавляет, до 0.6 а при таком должен добавить отрицательное значение и так цикл по кругу. Вот для этого и используем Mathf.Abs(curRotationSpeed)<deltaSpeedRotation где deltaSpeedRotation задан минимальной скоростью вращения, и если эта скорость меньше deltaSpeedRotation мы приравниваем текущую скорость вращения нулю curRotationSpeed=0‘.

 

Хочется верить что это было понятно. Теперь давайте рассмотрим само движение.

 

Как мы помним за перемещение отвечает transform, у нас задан transform.eulerAngles это означает вращение по осям x, y, z, то бишь вращение по 180градусов. Есть еще localRotation, но данная мне кажется проще. Итак мы прибавляем по вектору transform.eulerAngles+=new Vector3, и прибавляем по вектору Y, так как нам именно вокруг Y так как нам необходимо производить вращение вокруг оси YVector3(0,curRotationSpeed,0)‘, почему? Посмотрите в окно Unity 3d там есть показанные три оси X, Y, Z соответственно пространство трехмерное, если вращать вокруг иных осей получится вращение не вдоль земли, а в нее. Да и вообще попробуйте разобраться в перемещении в трехмерном пространстве, проще будет. Дальше мы рассматриваем активную переменную Vector3и называем её dir‘, и приравниваем ей значение transform.forward, это означает направление, куда смотрит наш объект. То есть это задает так чтобы куда бы мы не повернули объект, он будет двигаться все время вперед. Чтобы понять лучше можете после этой строки вывести в консоль значения dir‘, при помощи Debug.Log(dir);и вы сможете в консоли посмотреть какие значения меняются.

 

Ну и непосредственно движение вперед назад, transform.positionкоторый отвечает за местонахождение нашего объекта, прибавляется к dirумноженную на текущую скорость curSpeed и умноженную на Time.deltaTime, это строка transform.position+=dir*curSpeed*Time.deltaTime‘. Что такое Time.deltaTime я говорил кратко, в прошлом уроке который выполнял.

 

Надеюсь кому-то было интересно, мне так точно. Хочется верить что все доступным языком описано, кому не понятно спрашивайте в комментариях, только без явного спама, я вообще спам не приветствую, и только пару раз оставлял чужие ссылки, что посчитал разумными, но это так скорее личная прихоть. Всем спасибо и до новых статей.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *