Задать вопрос

Как сделать прыжок плавнее?

Доброго времени суток!

Я делаю игру, и уже на начальном этапе баг...
Пытался сделать плавный прыжок, а он резко присваивает y координату игроку равную "силе прыжка"
Вроде умножаю на Time.deltaTime, а всё равно!

Сам скрипт

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour { 
    [SerializeField]
    private float _speedMove; // Ск-ть движения
    [SerializeField]
    private float _speedRotate; // Ск-ть поворота камеры
    [SerializeField]
    private float _gravity; // Сила гравитации
    [SerializeField]
    private float _jumpForce; // Сила прыжка

    [SerializeField]
    private FixedJoystick _fixedJoystick;

    private CharacterController _cc; //  Контроллер движений
    private Animator _animatorCharacter; // Контроллер анимаций

    private void Start() { // Метод при загрузки игры
        _cc = gameObject.GetComponent<CharacterController>(); // Получаем контроллер
        _animatorCharacter = gameObject.GetComponent<Animator>(); // Получаем аниматор
    }

    private void FixedUpdate() { // Метод физ. вычеслений
        _movePlayer(); // Функция движения
        _gravityForce(); // Иммитация гравитации
        if (Input.GetKeyDown(KeyCode.Space)) OnJump();
    }

    private void _movePlayer () { // Создаем функцию для движения
        float _corX = _fixedJoystick.Horizontal; // Получаем x координату по нажатию
        float _corZ = _fixedJoystick.Vertical; // Получаем z координату по нажатию

        if ( _cc.isGrounded && (_corX != 0 || _corZ != 0) ) { // Если изм. координаты и если на земле
            Vector3 _dir = Vector3.zero; // Задаем нулевой вектор отн. мира
            Vector3 _dirRotate = Vector3.zero; // Задаем вектор 0 для поворота
            /* Задаем в вектор движения координаты направления */
            _dir.x = _corX; // Задаем x координату движения отн. мира
            _dir.z = _corZ; // Задаем z координату движения отн. мира
            _dir = transform.TransformDirection(_dir); // Задаем вектор отн. игрока
            /* Поворот персонажа */
            _dirRotate.y = _corX * _speedRotate; // Задаем вектор поворот в сторону
            transform.Rotate(_dirRotate); // Изм. поворот
            /* Движение персонажа */
            _cc.Move(_dir * _speedMove); // Задаем движение
            _animatorCharacter.SetBool("walk", true);
        } else {
            _animatorCharacter.SetBool("walk", false);
        }
    }

    private void _gravityForce () { // Метод гравитации
        Vector3 _gravityDir = Vector3.zero; // Создаем нулевой вектор
        _gravityDir.y -= _gravity * Time.fixedDeltaTime; // Создаем притяжение, у меньшая плавно y координату
        _cc.Move(_gravityDir); // Двигаем по y с учетом гравитации
    }

    public void OnJump() { // Метод для прыжка
        if (_cc.isGrounded) { // Если на земле
            Vector3 _jump = Vector3.zero;
            _jump.y += _jumpForce * Time.deltaTime; // Сам "плавный" прыжок
            _cc.Move(_jump); // Плавный прыжок
        }
    }

}

  • Вопрос задан
  • 1745 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 1
DanielMcRon
@DanielMcRon
C# && Unity
public float jumpSpeed = 15.0f;
public float gravity = -9.8f;
public float terminalVelocity = -10.0f;
public float minFall = -1.5f;
private float _vertSpeed;
...
void Start() {
 _vertSpeed = minFall; 
 ...
}
 void Update() {
 ...
 if (_charController.isGrounded) {
 if (Input.GetButtonDown("Jump")) { 
 _vertSpeed = jumpSpeed;
 } else {
 _vertSpeed = minFall;
 }
 } else { 
 _vertSpeed += gravity * 5 * Time.deltaTime;
 if (_vertSpeed < terminalVelocity) {
 _vertSpeed = terminalVelocity;
 }
 }
 movement.y = _vertSpeed;
 movement *= Time.deltaTime; 
 _charController.Move(movement);
 }
}

Не стал заморачиваится, взял из книги "Unity в действии"

Думаю объяснять не стоит, страница вроде 188 в книге, если что
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@maxmahsudov
Все потому что метод OnJump вызывается один раз при нажатии пробела, плюс не самая удачная идея отслеживать нажатие клавиши в FixedUpdate. Я бы решил проблему следующим способом:

public Rigidbody rb;

void Start()
{
rb = GetComponent();
}

private void Update(){
If(Input.GetKeyDown(KeyCode.Space)){
rb.AddForce(Vector3.up * _jumpForce)
}
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы