Создание гонок. Глава 1 (2)

0 3

Всем привет! Сегодня мы сделаем так, чтобы наш автомобиль мог ездить, начнем!

Колеса

Делаем 4 Whell Collider — создаем пустой объект — вешаем туда компонент Whell Collider, и подгоняем под колесо, и так 4 раза. Но, для начало добавьте к машине Box Collider и Rigidbody, Box Collider настройте под размеры автомобиля.

Вот так у вас должно получится, обязательно обратите внимание на Hierarchy. У Rigidbody измените массу, к примеру на 2 тонны.

Скрипт CarController

Создайте новый скрипт под названием CarController, и откройте скрипт, удалите там все методы. И впишите данный код:

    [SerializeField] private Transform _transformFL;
    [SerializeField] private Transform _transformFR;
    [SerializeField] private Transform _transformBL;
    [SerializeField] private Transform _transformBR;
 
    [SerializeField] private WheelCollider _colliderFL;
    [SerializeField] private WheelCollider _colliderFR;
    [SerializeField] private WheelCollider _colliderBL;
    [SerializeField] private WheelCollider _colliderBR;
 
    [SerializeField] private float _force;
    [SerializeField] private float _maxAngle;
    // Start is called before the first frame update
 
    private void FixedUpdate()
    {
        _colliderFL.motorTorque = Input.GetAxis("Vertical") * _force;
        _colliderFR.motorTorque = Input.GetAxis("Vertical") * _force;
 
        if (Input.GetKey(KeyCode.Space))
        {
            _colliderFL.brakeTorque = 3000f;
            _colliderFR.brakeTorque = 3000f;
            _colliderBL.brakeTorque = 3000f;
            _colliderBR.brakeTorque = 3000f;
        }
        else
        {
            _colliderFL.brakeTorque = 0f;
            _colliderFR.brakeTorque = 0f;
            _colliderBL.brakeTorque = 0f;
            _colliderBR.brakeTorque = 0f;
        }
 
        _colliderFL.steerAngle = _maxAngle * Input.GetAxis("Horizontal");
        _colliderFR.steerAngle = _maxAngle * Input.GetAxis("Horizontal");
 
        RotateWheel(_colliderFL, _transformFL);
        RotateWheel(_colliderFR, _transformFR);
        RotateWheel(_colliderBL, _transformBL);
        RotateWheel(_colliderBR, _transformBR);
    }
 
    private void RotateWheel(WheelCollider collider, Transform transform)
    {
        Vector3 position;
        Quaternion rotation;
 
        collider.GetWorldPose(out position, out rotation);
 
        transform.rotation = rotation;
        transform.position = position;
    }

Разбор:

  1. Создали 4 переменных типа Transform для каждого колеса.
  2. Еще 4 переменные типа WheelCollider для каждого коллайдера колеса.
  3. Дополнительные 2 переменные — мощность и максимальный угол поворота колеса.
  4. Говорим, что _colliderFL.motorTorque и _colliderFR.motorTorque это ввод клавиш W и S умноженное на мощность.
  5. Если нажимаем на пробел, то к каждому коллайдеру применяем тормозную силу 3000.
  6. Если мы не нажимаем на пробел, то к каждому коллайдеру применяем тормозную силу 0.
  7. Говорим, что _colliderFL.steerAngle и _colliderFR.steerAngle это максимальный угол поворота колеса умноженный на ввод клавиш A и D.
  8. Поворачиваем колеса
  9. Метод для поворота колес.

Сохраняем скрипт, и в юнити. Заполняем пункты. FL — Переднее — левое колесо. FR — переднее — правое колесо. BL — заднее — левое колесо. BR — заднее — правое колесо. Ставим force на 2500, а maxAngle на 60. Запускаем! Но только при повороте, у нас машина заваливается. Погнали, исправлять.

Фикс багов

Измените код, на этот:

[SerializeField] private Transform _transformFL;
    [SerializeField] private Transform _transformFR;
    [SerializeField] private Transform _transformBL;
    [SerializeField] private Transform _transformBR;
 
    [SerializeField] private WheelCollider _colliderFL;
    [SerializeField] private WheelCollider _colliderFR;
    [SerializeField] private WheelCollider _colliderBL;
    [SerializeField] private WheelCollider _colliderBR;
 
    [SerializeField] private float _force;
    [SerializeField] private float _maxAngle;

    private Rigidbody _rigidbody;
    // Start is called before the first frame update

    private void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
    }
 
    private void FixedUpdate()
    {
        _colliderFL.motorTorque = Input.GetAxis("Vertical") * _force;
        _colliderFR.motorTorque = Input.GetAxis("Vertical") * _force;
 
        if (Input.GetKey(KeyCode.Space))
        {
            _colliderFL.brakeTorque = 3000f;
            _colliderFR.brakeTorque = 3000f;
            _colliderBL.brakeTorque = 3000f;
            _colliderBR.brakeTorque = 3000f;
        }
        else
        {
            _colliderFL.brakeTorque = 0f;
            _colliderFR.brakeTorque = 0f;
            _colliderBL.brakeTorque = 0f;
            _colliderBR.brakeTorque = 0f;
        }
 
        _colliderFL.steerAngle = _maxAngle * Input.GetAxis("Horizontal");
        _colliderFR.steerAngle = _maxAngle * Input.GetAxis("Horizontal");
 
        RotateWheel(_colliderFL, _transformFL);
        RotateWheel(_colliderFR, _transformFR);
        RotateWheel(_colliderBL, _transformBL);
        RotateWheel(_colliderBR, _transformBR);

        _rigidbody.centerOfMass = new Vector3(0f, -0.3f, 0f); // Adjust the Y value as needed
    }
 
    private void RotateWheel(WheelCollider collider, Transform transform)
    {
        Vector3 position;
        Quaternion rotation;
 
        collider.GetWorldPose(out position, out rotation);
 
        transform.rotation = rotation;
        transform.position = position;
    }

Устанавливая значение Y для центра масс отрицательным, вы понижаете центр масс. После чего наш автомобиль не должен заваливаться, но вы можете сделать поменьше значение.

Фикс багов 2

У нас есть еще один баг, если мы отпустим камеру вниз, то мы увидим дно автомобиля. А plane не видно. Для этого заходим в камеру, и ищем — Blocking Layers, создаем новый слой Ground. Для этого — объект — Layer (в правом верхнем углу) — AddLayer — в свободной строчке пишем Ground и все.

Теперь устанавливаем наш слой Ground на Plane и в камере — Blocking Layers выбираем наш слой Ground. И все! Blocking Layers это настройка, указывающая через какие слои не может пройти камера.

Оставьте ответ

Ваш электронный адрес не будет опубликован.