Часть 1 Часть 2 Прежде чем мы начнём, хочу предложить скрипты, переписанные на C#.
Поскольку половина скриптов написана на JS, я решил переписать их на C# (C# мне более родной).
Скачать Также ведется активный «разбор» проекта для новичков.
«Проект: Шутер на выживание» , видеоуроки представлены ниже Плейлист , дополнительные видеоуроки по шутеру на выживание .
Я лично выражаю благодарность этому каналу за их нелегкий труд. п.
с.
в конце данного руководства есть видеообзор, в котором на примерах сравниваются два реализованных способа управления автомобилем.
Итак, давайте начнем с нашего руководства.
Часть 3: Под капотом Мы уже видели, как собрать работающую машину из 3D-модели, скриптов и встроенных компонентов.
Мы также узнали об общедоступных переменных и о том, как их можно использовать для точной настройки автомобиля.
Теперь поговорим об изучении сценария Машина .
• Дважды щелкните сценарий.
Автомобиль.
js чтобы открыть его в редакторе кода.
Поначалу этот сценарий может показаться немного пугающим: он содержит более 500 строк кода и комментариев, а также множество переменных и функций.
Не отчаивайся.
Наш скрипт структурирован таким образом, что у нас есть относительно небольшие функции со значимыми именами, указывающими, что делает каждая функция.
Код также содержит комментарии, поясняющие определенный участок кода.
Поэтому мы предлагаем вам взглянуть на него, начиная с «входных» точек изучения сценария и следуя далее по руководству.
В данном случае этими точками входа будут Начинать() , Обновлять() И ФиксированноеОбновление() функции.
Каждая из этих «основных» функций вызывает другие функции.
Итак, когда мы начинаем с функции Начинать() , мы увидим, что функция впервые вызвала функцию НастройкаWheelColliders() .
Найдите эту функцию в коде и изучите, что она делает, а затем вернитесь к функции.
Начинать() и переходим к следующей функции НастройкаЦентраМасс() .
Изучив этот код, вы поймете, как функционирует автомобиль.
В дальнейшем мы рассмотрим все эти функции.
Мы не будем объяснять каждую строку кода, но рассмотрим каждую функцию по порядку.
Какие вещи вам нужно знать? Работать в Единство во многом легко, благодаря таким вещам: встроенным компонентам, редактору, возможностям D&D. Настроить машину – это полдела.
Единство заботится об импорте модели , компоненты столкновение , рендеринг И физика можно добавить к объекту, нажав кнопку «Добавить компоненты».
Внутри нашего скрипта мы будем работать в основном над манипулированием этими компонентами.
Вы, конечно, встретите множество расчетов и формул, которые мы используем, чтобы определить, что происходит с автомобилем.
Это неизбежная часть, которая делает игры реалистичными: вам нужно установить некоторую логику, например, написав скрипты, если вы хотите выполнять больше, чем просто базовые функции.
Эти формулы и расчеты используются в наших компонентах.
Если вы видите, что код совсем не знаком и не знаете, с чего начать, вы можете попробовать наш подход, который заключается в том, чтобы сосредоточиться на следующих моментах, а также рассмотреть, как и что работает: • Жесткое тело • Колесные коллайдеры • Расчеты и формулы, которые мы делаем, а также их порядок.
Подумайте об этом так: • При добавлении Жесткое тело В нашей модели автомобиля у нас есть возможность контролировать его физические способности.
Мы можем сделать это, рассчитав силы, которые двигают его вперед и замедляют. • При добавлении Колесные коллайдеры мы получаем контроль над тем, где машина выезжает на дорогу.
Пуск() - Установка Здесь мы делаем необходимую для автомобиля инициализацию.
Функция Начинать() выполняется только один раз, в начале скрипта, перед функциями Обновлять .
Вот почему Начинать() часто используется для установки начальных значений, необходимых для компонентов в коде.
НастройкаWheelColliders()
К нашей машине прикреплены четыре колеса, и мы поместили их в ПередниеКолеса И Задние колеса массивы в инспекторе.В этой функции мы создаем реальные коллайдеры , создавая возможность взаимодействия колес с поверхностью и автомобилем.
Начнем с функции НастройкаКриваяТрикцииКолеса().
НастройкаWheelFrictionCurve()
В НастройкаWheelFrictionCurve() мы просто создаем новый КолесоТрениеКривая и присвоим ему те значения, которые считаем подходящими для нашей машины.КолесоТрениеКривая использует КолесоКоллайдеры описать фрикционные свойства покрышек колес.
Если вы хотите изучить процесс создания автомобиля в Единство более подробно, построено с использованием КолесоКоллайдеры , затем прочтите документацию.
Колесо настройки()
После установки изгиб , мы вернулись к сценарию НастройкаWheelColliders() , теперь мы готовы создать коллайдеры и объекты колеса (Колесо) .Это делается с помощью вызова функции Колесо настройки() для каждого нашего колеса.
Если вы посмотрите на эту функцию, то увидите, что она имеет два параметра: Трансформировать И логическое значение и возвращает объект колеса .
Это нам нужно для того, чтобы изменить расположение колес, а также указать, принадлежит колесо передней части автомобиля или нет. Затем функция создает и возвращает объект колесо , который мы помещаем в массив колеса содержащий все наши колеса для остальной части скрипта:
В этом цикле мы создаем новый игровой объект и вызываем функцию Колесо настройки() , в качестве первого аргумента передаем координаты объекта, в качестве второго параметра указываем истинный или ЛОЖЬ , Если истинный — тогда созданное колесо будет передним, если ЛОЖЬ потом зад. Затем добавляем компонент КолесоКоллайдер к этому игровому объекту.for (var t : Transform in frontWheels) { wheels[wheelCount] = SetupWheel(t, true); wheelCount++; }
Устанавливаем свойства КолесоКоллайдер из переменных приостановка который мы обсуждали, когда настраивали машину (линейка подвески, пружина и амортизатор).
Обязательные свойства: коллайдер мы уже создали КолесоТрениеКривая создается в функции Кривая трения колеса() , графика для колеса (объект Дисковый тормоз мы втащили инспектор, когда создавали машину) и графику шин (которая является дочерним элементом Дисковый тормоз ).
Радиус колеса установим автоматически в зависимости от размера покрышки: wheel.collider.radius = wheel.tireGraphic.renderer.bounds.size.y / 2;
Наконец, мы проверяем только что созданное колесо, является ли оно передним или задним, посмотрев на истинный или ЛОЖЬ значение.
Далее в коде мы должны проверить, что автомобиль касается земли хотя бы одним передним и одним задним колесом.
Кроме того, делаем небольшой трюк для переднего колеса, создав дополнительный игровой объект, который устанавливаем между кузовом автомобиля и колесом.
Этот Рулевая колонка (передняя стойка) который мы будем использовать позже для вращения колеса при повороте.
В конечном итоге мы создаем колесо, которое возвращаем в массив.
«Колесные» колеса и когда мы обработали все колеса возвращаемся к функции Начинать() .
НастройкаЦентраМасс()
Это следующая функция, которую мы рассмотрим.Это очень маленькая функция, которая установит центр масс на Жесткое тело К Центр массы , который мы создали ранее.
Если центр массы не был установлен Жесткое тело буду использовать центр массы по умолчанию, который будет рассчитывать Единство автоматически.
Затем преобразуем введенную в инспекторе максимальную скорость с помощью небольшой полезной функции: topSpeed = Convert_Miles_Per_Hour_To_Meters_Per_Second(topSpeed);
Функция просто умножает переменную Максимальная скорость за номер 0,44704, который преобразует его в метры в секунду.
Это настройка, позволяющая ввести в инспекторе желаемую скорость в милях/час.
При расчетах физики мы работаем с м/с.
У нас также есть небольшая функция, которая выполняет обратный расчет, что очень полезно, если вы хотите вывести скорость автомобиля в милях в час.
НастройкаGears()
В этой функции автоматически рассчитывается передача, присваивая каждой передаче максимальную скорость и вычисляя, сколько мощности необходимо для ускорения автомобиля до заданной скорости на каждой передаче.Мощность рассчитывается с использованием значений трения и сопротивления, переданных в некоторые переменные, что означает, что основные расчеты происходят по оси Z, расчеты трения происходят в функции Update().
Коэффициент умножается на значение этой мощности, чтобы автомобиль разогнался до большой скорости.
НастройкаSkidmarks()
Эта функция находит игровой объект Skidmark на сцене и сохраняет ссылку на него, используя ЧастицаЭмиттер создает дым.Код для отметок не рассматривается в этом руководстве, но это не должно помешать вам открыть скрипт и изучить его по своему усмотрению.
В конце Начинать() мы присваиваем значения Икс наш массив перетаскиваниеМультипликатор в переменную: initialDragMultiplierX = dragMultiplier.x;
Оно сохраняется, потому что мы меняемся Икс переменная перетаскиваниеМультипликатор когда мы используем ручной тормоз А затем нужно снова вернуться к исходному значению, когда мы не используем ручной тормоз .
Для установки начальных значений используйте функцию Начинать() .
Чтобы регулярно менять эти значения, используйте функцию Обновлять() .
Обновлять() Обновлять() вызывается каждый кадр игры, если МоноПоведение включено.
Обновлять() — наиболее часто используемая функция для реализации игрового процесса.
ПолучитьВвод()
Первое, что мы делаем в каждом кадре — это разные действия с клавиатурой с помощью вызова функции.ПолучитьВвод() .
Первые две строки читаются из вертикальный (вертикальный) и горизонтальный (горизонтальный) оси и хранятся в переменных дроссель И управлять : throttle = Input.GetAxis(“Vertical”);
steer = Input.GetAxis(“Horizontal”);
Вертикальный (вертикальный) и горизонтальный (горизонтальный) оси могут быть установлены в Менеджер ввода Unity (Правка -> Настройки проекта -> Ввод) .
По умолчанию вертикальный Ось настроена на клавиши «W», «стрелка вверх» для перемещения вперед и клавиши «S» и «стрелка вниз» для перемещения назад, а значение, которое мы здесь используем, сохраняется в переменной.
дроссель .
Горизонтальная ось установлена как клавиши «A» и «стрелка влево» для поворота налево, а клавиши «D» и «стрелка вправо» для поворота направо.
ПроверитьРучной тормоз()
После учебы GetInput для управления автомобилем вызываем функцию ПроверитьРучной тормоз() .Это специальная функция, которая проверяет, нажата ли клавиша.
Космос или нет, и соответственно применяет определенную логику: Когда мы впервые нажали Космос (космос) , мы устанавливаем переменную ручной тормоз В истинный , это запускает механизм ручной тормоз и меняет значение перетаскиваниеMultiplier.x (создает вибрацию при торможении на дороге, напоминающую настоящий ручник).
Когда Космос (космос) не нажата, код будет выполняться по-другому, пока клавиша не будет нажата.
Это еще раз означает, что код ручной тормоз не будет работать только тогда, когда пользователь выпускает первый раз Космос (космос) потому что мы устанавливаем переменную (ручной тормоз) ручной тормоз В ЛОЖЬ внутри блока.
Функция СтопРучной Тормоз() будет активировано: StartCoroutine(StopHandbraking(Mathf.Min(5, Time.time - handbrakeTime)));
СтопРучной Тормоз()
СтопРучной Тормоз() принимает входную переменную, определяющую количество секунд, которое потребуется для возврата перетаскиваниеMultiplier.x вернуться в это исходное состояние.Это значение должно быть не менее 5 для таймера ручник (ручной тормоз) , который мы только что запустили.
Затем функция отсчитывает указанное количество секунд, после чего устанавливает значение переменной перетаскиваниеMultiplier.x по умолчанию это снова делает движение автомобиля нормальным.
Check_If_Car_Is_Flipped()
Вернемся к функции Обновлять() теперь мы рассмотрим функцию Check_If_Car_Is_Flipped() чтобы проверить, не перевернулась ли машина.Внутри этой функции мы проверим наличие перевернутой машины.
Это абсолютно справедливо для автомобиля, который будет переворачиваться или переворачиваться, например на крайних поворотах, если мы попадем в аварию или совершим какие-то трюки, но мы хотим исключить возможность переворота автомобиля.
Итак, мы проверяем, перевернулась ли машина на определенный угол, под которым машина больше не движется, и если да, то добавляем в переменную время с момента последнего кадра.
сбростаймер .
Если это значение в конечном итоге сведется к превышению значения, которое мы установили для время сброса (по умолчанию 5 секунд), вызываем функцию ФлипАвто() .
Если машина находится под углом, по которому можно двигаться, мы устанавливаем таймер обратно на ноль.
ФлипАвто()
В ФлипАвто() мы возвращаем машину на колеса и устанавливаем ее скорость на 0, чтобы мы могли снова начать движение с этой точки.
ОбновлениеWheelGraphics()
Это самая длинная и сложная функция, которая вызывается из Обновлять() .К счастью, есть большой раздел, посвященный только размещению.
следы шин .
Важную роль по отношению к колесам играет обновление их расположения и угла поворота в этой функции.
Мы запустим каждое колесо, проверив, касается ли оно земли или нет. Если он касается земли, то устанавливаем колесоГрафика (изображение колеса) в положение, в котором оно должно находиться, это зависит от высоты и радиуса колеса.
Это переместит центр колеса в правильное положение относительно шасси автомобиля.
w.wheelGraphic.localPosition = wheel.transform.up * (wheelRadius + wheel.transform.InverseTransformPoint(wh.point).
y);
После установки колеса мы получаем скорость RigidBody в точке контакта с землей, чтобы перевести его в локальное пространство и сохранить его координаты в нашем объекте.
w.wheelVelo = rigidbody.GetPointVelocity(wh.point);
w.groundSpeed = w.wheelGraphic.InverseTransformDirection(w.wheelVelo);
Если колесо в данный момент не касается земли, то задаем положение колеса исходя из этого координаты, дальность подвески и сама подвеска «Родительские колеса»
ОбновлениеГир()
Последняя функция, вызванная в функции Обновлять() является ОбновлениеГир() , который рассчитывает текущую «передачу» автомобиля, исходя из заданных значений в НастройкаGears() и текущая скорость.В последнем разделе руководства мы должны рассмотреть остальную часть основного цикла, а именно физические вычисления, которые происходят внутри функции.
ФиксированноеОбновление() .
FixUpdate() — Вся наша физика Занимаясь физикой, важно, чтобы расчеты и действия строго контролировались, чтобы результат получился хороший.
ФиксированноеОбновление() созданный для этой цели.
Это гарантирует выполнение кода через фиксированный интервал времени.
Частота вызова функции ФиксированноеОбновление() : «Его можно вызвать несколько раз в кадре, если частота кадров низкая; или может быть вызван после нескольких кадров, если частота кадров высока.
Все расчеты и обновления физики вызываются непосредственно перед ФиксированноеОбновление() «У нас есть ряд функций, выполняемых внутри компании ФиксированноеОбновление() , и все они связаны с расчетом и применением силы к транспортному средству.
ОбновлениеПеретаскивание()
Это означает, что с увеличением скорости сопротивление увеличивается еще больше.Квадрат скорости при расчете сопротивления основан на реальной формуле сопротивления, используемой в физике.
После относительное перетаскивание и масштабируемый dragMultiplier (множители перетаскивания) который мы уже рассматривали, учли, что вид автомобиля в профиль сильно отличается от видов спереди, сбоку и сверху.
Если мы ручной тормоз Мы применяем дополнительные силы к значениям бокового и лобового сопротивления в зависимости от скорости движения автомобиля.
Обратите внимание, как мы используем скалярное произведение скорости и направления впереди автомобиля для расчета дополнительного сопротивления.
Это уравнение приводит к дополнительному сопротивлению передней части автомобиля, когда автомобиль движется вперед без поворота (более быстрое торможение) и к более медленному торможению при заносах и поворотах.
По цене Икс сопротивление то же: для автомобиля при скольжении вбок.
После этого постепенно увеличиваем значение сопротивления Икс замедлить машину вместо того, чтобы позволить ей вечно скользить по дороге.
Если мы не будем использовать ручной тормоз , мы обновим только значение Икс : drag.x *= topSpeed / relativeVelocity.magnitude;
Это сделано для комфортной езды на автомобиле - увеличиваем боковое сопротивление, это постепенно замедляет машину при заносе, пока машина не завершит занос.
В конце функции мы прикладываем силы к Жесткое тело : rigidbody.AddForce(transform.TransformDirection(drag) * rigidbody.mass * Time.deltaTime);
Сила сопротивления противоположна скорости автомобиля, приложим ее к Жесткое тело , что приводит к замедлению автомобиля.
ОбновлениеТрение()
Эта функция отслеживает трение, которое создается между колесами автомобиля и поверхностью нашей трассы.Это очень просто, потому что мы используем функцию КолесоТрениеКривая который был установлен в самом начале.
Трение колес обеспечивает силу на «выходе» функции, основанную на измерениях проскальзывания шин, которые мы передали в функцию.
Эта сила делится на два направления: лобовое трение (отвечает за ускорение и торможение) и боковое трение (отвечает за правильное удержание автомобиля на земле).
Ранее мы задали значение трения колеса, теперь нам нужно позаботиться об обновлении трения между колесом и поверхностью: w.collider.sidewaysFriction = wfc;
w.collider.forwardFriction = wfc;
Совершаем одно действие — меняем величину трения автомобиля исходя из текущей скорости автомобиля и направления движения автомобиля (обычное вождение — ВпередТрение , и исходя из заноса машины - «езда боком» боковое трение ).
ВычислитьМощность двигателя()
Расчет мощности двигателя, который мы позже будем использовать для приложения силы к Жесткое тело относительно простой, но имеет несколько особенностей.• Если мы этого не сделаем дросселирование , мы просто уменьшим мощность двигателя, тем самым замедлив машину.
• Если мы дросселирование в том же направлении, в котором в данный момент движется автомобиль (проверяем это с помощью функции ИметьСамеСигн() ) и посчитаем значение, которое мы добавим к мощности двигателя.
То, что мы видим, может показаться немного странным: мы вычисляем коэффициент силы, который представляет собой произведение текущей мощности двигателя, деленной на максимальную мощность двигателя (давая результат от 0 до 1), а затем умножаем на коэффициент 2. результат будет между 0 (когда мы стоим на месте или едим очень медленно) и 2 (когда едим на максимальной мощности).
Затем мы вызываем вспомогательную функцию ОценитьНормПауэр() .
Эта функция проверяет переданное значение и возвращает число от 1 до 0, если уровень мощности находится в диапазоне от 0 до 1. Если уровень мощности находится в диапазоне от 1 до 2, функция вернет значение от 0 до 1. Удивлены? Число, используемое в формуле, прибавляющей силу к двигателю, равно: currentEnginePower += Time.deltaTime * 200 * EvaluateNormPower(normPower);
Конечным результатом является то, что мы добавляем больше силы, когда нажимаем кнопку газа, и машина трогается с места медленно, постепенно ускоряясь.
В конце концов, когда автомобиль достигает максимальной скорости, никакие дополнительные силы, увеличивающие скорость, не используются.
мощность двигателя.
• Если вы дросселируете в противоположном направлении, это эквивалентно торможению.
В данном случае мы вычтем мощность двигателя за определенный период времени.
Наконец, рассчитывается мощность двигателя между текущей передачей и предыдущей передачей, чтобы избежать возможности резкого изменения значений в формуле расчета.
ВычислитьСостояние()
Это небольшая функция, которую мы сейчас рассмотрим, поскольку нам нужно знать, какие колеса автомобиля находятся на земле.Это делает эту проверку очень простой: • Мы устанавливаем переменные могу водить И может управлять В ЛОЖЬ по умолчанию.
• Затем мы проверяем каждое колесо в массиве Wheels, чтобы определить, какое колесо касается земли, а какое нет: if(w.collider.isGrounded)
Если колесо стоит на земле, проверяем, что это за колесо.
Если это переднее колесо, то могу водить установлен в Истинный .
Если это заднее колесо, то рулевое колесо установлен Истинный .
Данная функция сделала свое дело, если хотя бы одно колесо (заднее) коснется земли, то мы сможем управлять нашей машиной.
Если хотя бы одно колесо (переднее) коснется земли, мы сможем повернуть.
Осталось рассмотреть две последние функции, которые собственно и относятся к нашим расчетам для Жесткое тело машина.
Здесь мы остановимся немного подробнее, чтобы вы поняли логику операции и формулы расчета, которые в конечном итоге определяют движение транспортного средства.
ПрименитьДроссель()
Эта функция будет работать, если функция ВычислитьСостояние() установит переменную могу водить В Истинный (это означает, что хотя бы одно ведомое колесо находится на дороге).Если мы сможем контролировать, мы начнем со сравнения переменной дроссель (это нажатие клавиши на клавиатуре) и переменная относительная скорость.
z где скорость автомобиля.
Если эти значения имеют одинаковый знак – определено в функции ИметьСамеСигн() - это означает, что мы дросселируем в том же направлении, в котором движется автомобиль, и в этом случае мы добавляем усилие газа к Жесткое тело : throttleForce = Mathf.Sign(throttle) * currentEnginePower * rigidbody.mass;
Если значение газа отрицательное (пользователь нажимает кнопку тормоза), знак будет -1, и мы рассчитаем отрицательную силу газа, которую мы добавляем к автомобилю.
Мы также знаем, что сила газа имеет отрицательную скорость.
Так что мы будем снижать скорость быстрее.
Противоположный эффект возникает, когда пользователь нажимает кнопку газа.
Затем мы добавляем «положительную» силу газа к машине, которая уже движется вперед. ЕслиrelativeVelocity.z и throttle имеют разные знаки, то это должно означать, что мы добавим силу газа в направлении, противоположном тому, в котором в данный момент движется автомобиль.
Другими словами, машина тормозит или тормозит. Мы делаем это, устанавливая переменную Brakeforce в зависимости от веса автомобиля и силы первой передачи двигателя: brakeForce = Mathf.Sign(throttle) * engineForceValues[0] * rigidbody.mass;
Мы снова используем дроссель потому что мы знаем дроссель в данном случае имеет противоположный знак скорости, в результате чего вычисляем силу, противоположную силе, приводящей в движение автомобиль.
Когда мы закончим определять, нужно ли автомобилю ускоряться или замедляться, мы применяем рассчитанные силы в направлении движения Rigidbody: rigidbody.AddForce(transform.forward * Time.deltaTime * (throttleForce + brakeForce));
применить рулевое управление()
Если вы не создаете игру о дрэг-рейсинге, в которой пытаетесь установить мировой рекорд скорости на прямой, рулевое управление так же важно, как и дросселирование, поэтому давайте рассмотрим эту функцию.Мы не применяем никакого усилия дроссельной заслонки до тех пор, пока ведущие колеса не коснулся земли, и то же самое и с этой функцией, где мы не можем управлять автомобилем до тех пор, пока управляемые колеса не касайся земли.
В начале функции мы вычисляем значение переменной с именем радиус поворота , на основе входных данных.
Уравнение увеличивает значение радиус поворота когда вы поворачиваетесь в любую сторону.
Мы рассчитываем стоимость минМаксТурн вызвав функцию ОценитьСкоростьТурн() .
ОценитьСкоростьТурн()
Эта функция возвращает значение повернуть в зависимости от того, насколько быстро едет машина, подробнее это описано во второй главе нашего руководства.Если автомобиль едет быстро, это значение будет ближе к Минимальный поворот , что затрудняет поворот автомобиля при быстром движении.
Вернемся к функции применить рулевое управление() , там скорость поворота относится непосредственно к расчету радиус поворота в машине.
Чем больше радиус, тем меньше угол поворота, поскольку радиус поворота больше.
Поворачиваем машину по формуле: transform.RotateAround( transform.position + transform.right * turnRadius * steer, transform.up, turnSpeed * Mathf.Rad2Deg * Time.deltaTime * steer );
Функция ПовернутьВокруг() вращается вокруг преобразованной оси в заданной точке и принимает угол, равный сумме поворотов (поворачивается) .
• Точка поворота находится ровно посередине автомобиля, когда мы вообще не поворачиваем машину.
Когда мы начинаем нажимать на клавишу управления, точка убирается с автомобиля в ту сторону, в которую мы поворачиваем.
Помните, что переменная Управлять было извлечено из горизонтальной оси, которая является отрицательной, когда мы поворачиваем налево, и положительной, когда мы поворачиваем направо.
Радиус поворота будет расти все больше и больше, если мы повернем в одном направлении.
Когда Радиус поворота умножить на вектор Transform.right мы получаем точку, которая базируется в центре автомобиля и перемещается в сторону, в которую мы поворачиваем, как показано на следующих изображениях:
• Оси вращаются вокруг оси Ага) , это значит, что мы разворачиваем машину в плоскости Икс - повернем машину в сторону линии, показанной на изображении.
• Угол поворота рассчитывается на основе скорость поворота умножается на Управлять вращать лево право .
Теперь посмотрим изнутри: if(initialDragMultiplierX > dragMultiplier.x)
Как мы помним, в функции ручника мы проверяли, касается ли земли хотя бы одно переднее колесо или нет.
Если машина не стоит на месте, то проверяем, поворачивает ли машина в данный момент или нет, посмотрев значения angularVelocity.y В Жесткое тело .
Если это значение равно нулю или очень мало, мы не вращаемся или поворачиваемся на очень несколько градусов, а затем применяем случайное значение к направлению, в котором производится поворот. Это будет имитировать шатание автомобиля во время использования.
ручной тормоз .
Если значение не очень низкое, вместо этого примените фактическое значение angularVelocity.y в направлении вращения.
При повороте налево значение будет -1, при повороте направо значение будет 1.
При использовании ручника автомобиль поворачивает, но для торможения используется другая точка опоры: frontWheels[0].
localPosition + frontWheels[1].
localPosition) * 0.5
Эта точка находится между двумя передними колесами, когда автомобиль вращается, в результате задняя часть автомобиля движется в сторону поворота автомобиля, а передняя часть удерживает свое положение, что позволяет автомобилю скользить на высокой скорости при использовании.
ручной тормоз .
Теперь круг замкнут и функции Обновлять() И ПозднееОбновление() будем работать вместе.
Надеюсь, вам понравилось учиться создавать автомобиль, играть с его переменными и заглядывать вместе с нами в код. Реальная физическая модель В панели проекта (вид проекта) вы найдете папку с именем ~ Альтернативная физическая модель .
Ээта папка содержит несколько скриптов и примеров Префабы симулировать реалистичную физику автомобиля в Единство .
Представленное здесь моделирование не использует колесные коллайдеры Unity , но вместо этого реализуем наши собственные коллайдеры колес в сценарии, основанном на Физика.
Raycast .
Затем использует скрипт Пачейка «Волшебная формула».
- на основе модели шины для расчета силы колеса, применимой к автомобилю, это даст наилучшие результаты.
Скорее всего, вам не нужно знать о внутренней работе физической модели.
Вы можете просто поэкспериментировать с настройками уже созданных Префабы .
Если вы откроете скрипты, то увидите, что все параметры объяснены в комментариях.
Попробуйте немного изменить настройки и покататься на машине.
Включенные префабы
В папке пять автомобилей в Префабы И следы от скольжения В Префабы .Чтобы опробовать их, просто перетащите одну из машин и тормозные знаки (Skidmarks Prefab) на сцене (конечно Отметки префабов вероятно, уже в сцене).
Теперь вы сможете передвигаться по автомобильной сцене, используя клавиши со стрелками.
Есть и даже Теги: #уроки unity3d #C++ #разработка игр #разработка игр #учебник #руководство разработчика #разработка игр #C++ #unity
-
Правила Хорошего Собеседования
19 Oct, 24 -
Настройка Archlinux На Asus Eee 1201Nl
19 Oct, 24 -
Мобильные Заметки
19 Oct, 24