Создание физического автомобиля

Как создать автомобиль с физикой.

Требования


Требования физической модели

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

Требования к контенту.


Минимальный набор элементов для автомобиля.

Для того чтобы отобразить автомобиль на экране вам понадобится геометрия кузова автомобиля. для колёс вам нужно два колеса - левое и правое, мы будем использовать их экземпляры для задних и передних колёс.

Для этого урока, Christophe Desse поделился своей моделью автомобиля.
François Gutherz уменьшил количество полигонов таим образом возможно визуализировать модель в реальном времени с приемлемой частотой кадров.

Настройка сцены


Первое что нужно сделать, это скачать проект по этой ссылке:
Скачать проект урока

Распакуйте этот архив в любое удобное место на вашем диске.
Запустите редактор и откройте этот проект. Создайте новую сцену и назовите её "Vehicle".


Мастер новой сцены. Щелкните по кнопке Finish для создания сцены.

Созданная сцена будет открыта автоматически.

Настройка сцены.

Первая вещь которую мы сделаем, это создадим экземпляр кузова автомобиля в сцене. Для этого просто перетащите файл 'meshes/frozen_car_body.nmg' из проводника проекта в окно 3D просмотра. Проверьте что значок фильтра Geometry выше проводника проекта нажат если вы не видите ни какой геометрии в окне.


Выберите файл геометрии и перетащите в окно просмотра.

Как только вы отпустите кнопку мыши, перетащив геометрию в окно просмотра, GameStart загрузит модель, создаст элемент и присоединит геометрию к этому элементу.

Скорее всего, вы создали экземпляр геометрии не точно в центре сцены. Хотя это не имеет никакого значения, мы установим положение элемента в центре сцены. Новый элемент будет сразу выбран и его свойства отображаются с правой стороны в окне Properties. В этом окне имеется раздел Transformation который содержит поля для ввода точной позиции объекта. Установите значения полей позиции в 0. Для перехода к следующему полю вы можете использовать клавишу Tab.


Вкладка трансформации элемента.

Пока вы всё еще там, перейдите на вкладку General в окне Properties и измените имя объекта на Body.

Установка физической модели.

Перейдите на вкладку Physics в окне Properties и выберите Vehicle (Dynamic) в списке "Mode". На вкладке появятся новые поля и новая вкладка Vehicle ниже. Режим физики выбран, но но физической фигуры всё еще нету. Для добавления физической фигуры щелкните кнопку Add... на вкладке Physics и выберите Box. Подкорректируйте позицию и массу чтобы они соответствовали этим значениям:

  • Position (m) { 0, 0.3, 0 }
  • Euler (°) { 0, 0, 0 }
  • Size { 2, 0.8, 5 }
  • Mass (Kg) 500.

Простая модель для столкновения - параллелепипед

Настало время проверить наше творение! Уже? Да. Идем дальше - нажмите F5... Наша машина падает. Вы можете закрыть окно Debug. Конечно отсутствие земли не даёт нашему автомобилю упасть на нее. Создаёте экземпляр геометрии 'cube_02.nmg' в позиции { 0, -14, 0 }. Установите физический режим для этого элемента в Static Collision (Static) и добавьте физическую фигуру столкновения Box и установите размер { 25, 25, 25 }.

Попробуйте снова нажав F5. Кузов автомобиля, как и задумано, падает и останавливается. Но пока у нас отсутствуют колёса. Закройте окно Debug.

Настройка физической модели автомобиля.

Опять выберите объект Body и перейдите во вкладку Vehicle. Нажмите кнопку Add и выберите это колесо из списка. Передвиньте колесо в позицию { 0.9, 0.15, 1.5 }. Теперь пока это колесо еще выбрано, нажмите кнопку Clone. Выберите созданное колесо и инвертируйте его позицию по оси X фактически передвинув его позицию в { -0.9, -0.3, 1.5 }. Очень важно, что колесо прекрасно сбалансировано. Теперь выберите оба колеса и нажмите кнопку Clone снова. Для новых колёс установите координату Z на значение -1.4.


Модель автомобиля почти завершена.

Если вы просмотрите вашу работу на этом этапе, вы увидите что пружины автомобиля работают. Осталось их настроить.

Взаимодействие с моделью.


Визуализация моделей колёс.

Для того чтобы колёса были видны, нам нужно создать экземпляры их модели в сцене. Перетащите геометрию 'wheel_0.nmg' и 'wheel_1.nmg' два раза каждую для создания четырёх элементов колёс. Положение элементов колес не имеет значения, модель автомобиля автоматически обеспечит для них правильное положение. Оставь их таким образом.
Переименуйте первое колесо 'Wheel 0' в 'WheelFR' (это означает Front Right, Переднее правое), второе в 'WheelRR' (Rear Right Заднее Правое), далее 'Wheel 1' в 'WheelFL' (Front Left) и другое в 'WheelRL' (Rear Left).

Теперь, когда мы можем однозначно идентифицировать каждое колесо, мы должны запросить у модели автомобиля его трансформацию и направить его к соответствующему элементу. Для этого мы будем использовать короткий скрипт. В проводнике сцены выберите пункт Scene и во вкладке Script щелкните по кнопке Add... и выберите New.... Далее оставив значения по умолчанию нажмите OK.

Обратите внимание: Хотя мы должны добавить этот скрипт к элементу Body, но делать это на сцене на самом деле гораздо интереснее. Вы будете поймёте почему к концу этого урока.

В открывшемся окне редактора вставьте следующий код:


                          
  1. class Vehicle
  2. {
  3. body = 0
  4. wheels = 0
  5.  
  6. function OnUpdate(scene)
  7. {
  8. // Для каждого колеса...
  9. for (local n = 0; n < 4; ++n)
  10. {
  11. // ...запросить матрицу трансформации из модели Vehicle...
  12. local m = ItemPhysicVehicleGetWheelMatrix(body, n)
  13. // ...и назначить элементу колеса
  14. ItemSetMatrix(wheels[n], m)
  15. }
  16. }
  17.  
  18. function OnSetup(scene)
  19. {
  20. // Сохраняем ссылку на элемент Body
  21. body = SceneFindItem(scene, "Body")
  22.  
  23. // Сохраняем ссылки на каждое колесо в массиве
  24. wheels = []
  25. wheels.append(SceneFindItem(scene, "WheelFL"))
  26. wheels.append(SceneFindItem(scene, "WheelFR"))
  27. wheels.append(SceneFindItem(scene, "WheelRL"))
  28. wheels.append(SceneFindItem(scene, "WheelRR"))
  29. }
  30. }

                        

Теперь сохраните скрипт и переключитесь обратно в сцену Vehicle и нажмите F5. Теперь колёса на своих местах где им и место.

Настройка модели Vehicle.

Выберите элемент Body и перейдите во вкладку Vehicle. Мы отредактируем каждое колесо модели Vehicle чтобы оно совпало с геометрией колёс.

Далее описаны некоторые важные свойства колёс в физической модели Vehicle:

  • Friction: Трение поверхности шин колёс
  • Radius: Радиус шины колеса
  • Rest length (m): Длина подвески от позиции колёс. Это расстояние которое пружина будет пытаться сохранить.
  • Max. Travel (m): Максимальное смещение позиции подвески от его длины.
  • Stiffness: Насколько сильно подвеска будет восстанавливать её длину.
  • Damping: Пружинистость подвески.

Обратите внимание: Из всех эти параметров, нужно понять два главных параметра stiffness и damping. Они работают вместе, вы увеличиваете stiffness (жесткость) для придания подвеске большей жесткости тогда ваша машина будет прыгать, увеличение параметра damping (сдерживание) ограничит этот эффект и сохранит жесткость подвески.

Выберите все четыре колеса и введите следующие значения:

  • Friction 1.5
  • Radius 0.485
  • Rest length 0.5
  • Max. Travel 2
  • Stiffness 22
  • Damping 0.8.

Просмотрите сцену еще раз. Теперь автомобиль останавливаться более естественных образом.

Время езды

Если вы всё еще не сделали этого, добавьте свет в сцену, для этого выберите Add/Light из меню Scene.

Выберите элемент сцены в Scene Explorer и в панели свойств, на вкладке Script щелкните по кнопке Edit vehicle.nut....

Вставьте окончательную версию скрипта управления автомобилем заменив им весь имеющиеся там текст:


                          
  1. class Vehicle
  2. {
  3. body = 0
  4. wheel_items = 0
  5.  
  6. function OnUpdate(scene)
  7. {
  8. // Обновляем матрицу колёс из физической модели.
  9. ItemSetMatrix(wheel_items[0], ItemPhysicVehicleGetWheelMatrix(body, 0))
  10. ItemSetMatrix(wheel_items[1], ItemPhysicVehicleGetWheelMatrix(body, 1))
  11. ItemSetMatrix(wheel_items[2], ItemPhysicVehicleGetWheelMatrix(body, 3)) // Bullet использует другой порядок.
  12. ItemSetMatrix(wheel_items[3], ItemPhysicVehicleGetWheelMatrix(body, 2))
  13.  
  14. local device = GetKeyboardDevice()
  15.  
  16. // Поворот (направление).
  17. local steering = Deg(0)
  18. if (DeviceIsKeyDown(device, KeyLeftArrow))
  19. steering = Deg(-30)
  20. if (DeviceIsKeyDown(device, KeyRightArrow))
  21. steering = Deg(30)
  22.  
  23. ItemPhysicVehicleSetSteering(body, 0, steering)
  24. ItemPhysicVehicleSetSteering(body, 1, steering)
  25.  
  26. // Ускорение и торможение
  27. local F = 0, B = 0;
  28.  
  29. if (DeviceIsKeyDown(device, KeyDownArrow))
  30. B = 35
  31. else
  32. if (DeviceIsKeyDown(device, KeyUpArrow))
  33. F = 1800
  34.  
  35. // Передний привод
  36. ItemPhysicVehicleSetForce(body, 0, F)
  37. ItemPhysicVehicleSetForce(body, 1, F)
  38.  
  39. // Тормозят все 4 колеса
  40. for (local n = 0; n < 4; ++n)
  41. ItemPhysicVehicleSetBrake(body, n, B)
  42. }
  43.  
  44. function OnSetup(scene)
  45. {
  46. // Сохраняем ссылку на элемент кузова
  47. body = SceneFindItem(scene, "Body")
  48.  
  49. // Сохраняем колёса в массиве
  50. wheel_items = []
  51. wheel_items.append(SceneFindItem(scene, "WheelFL"))
  52. wheel_items.append(SceneFindItem(scene, "WheelFR"))
  53. wheel_items.append(SceneFindItem(scene, "WheelRL"))
  54. wheel_items.append(SceneFindItem(scene, "WheelRR"))
  55. }
  56. }

                        

Сохраните файл, переключитесь обратно в сцену и просмотрите её. Теперь вы можете управлять автомобилем используя стрелки на клавиатуре. Но для нас игровая область слишком мала.

Расширения ваших горизонтов.


Ландшафт для езды.

Создайте новую сцену и назовите её TestWorld. Создайте новый ландшафт выбором пункта Add/Terrain... из меню Scene. Оставив значения по умолчанию, нажмите кнопку OK. На вкладке Physics установите режим физики (Mode) как Static Collision (Static). Добавьте новую фигуру для столкновения Terrain. Теперь нарисуйте возвышенности но будьте осторожны со склонами, не делайте их слишком крутыми, иначе вы не сможете заехать на них. И наконец добавьте источник света в сцену.

Добавление автомобиля

Создайте экземпляр сцены Vehicle перетащив её из Project Explorer в окно просмотра.
Подправьте её позицию так чтобы колёса были над ландшафтом. Просмотрите сцену и можете проехать по ландшафту.

Совет: Помечая элементы Cube 02 и New Light как вспомогательные (helper) на вкладке General в сцене Vehicle, таким образом они не будут импортированы когда вы перетаскиваете сцену в окно. Тем не менее они будет существовать при просмотре сцены Vehicle.

Теперь создайте еще несколько экземпляров сцены Vehicle перетаскивая её в окно просмотра и просмотрите результат. Нет ничего сложного, верно? Те же самые результаты могут быть достигнуты если мы напишем скрипт для объекта Body напрямую в сцене Vehicle, нам нужно будет найти правильный экземпляр колеса среди тех экземпляров сцены Vehicle в главном дереве сцены. Когда мы пишем скрипты для сцены Vehicle и используем функции нахождения скрипта в нужном элементе GameStart автоматически ограничивает свой поиск нужным типом элементов сцены.

Результат в движении.

Щелкните для того чтобы скачать урок, видео которого вы можете видеть ниже.

Добавьте немного деталей и вы получите нечто близкое к этому.

Обратите внимание: Законченный урок использует другой подход, там закриптован объект Body напрямую. Чтобы найти нужное колесо для заданного тела, колёса сделаны дочерними по отношению к объекту Body к которому они принадлежат