Пробовал разные способы которые нашёл в интернете, умножение на Time.deltaTime, пробовав изменить импульс на Time.deltaTime, отслеживал нажатие в FixedUpdate() вместо Update() и используя Time.FixedDeltaTime. Впрочем, ни один из способов не увенчался успехом. Подскажите как исправить данную проблему?
1. Параметр Time.deltaTime - это временной промежуток между последним и текущим кадром. Умножая на него, например, скорость, вы говорите коду, что хотите сделать привязку скорости не к кадрам (столько-то метров за кадр), а к секундам (столько же метров, но уже за секунду). Это довольно удобно, когда вы делаете физическую симуляцию игре.
2. У прыжка есть два
режима (Force и Impulse).
Force обычно используется для продолжительных воздействий. Например, с её помощью можно реализовать занос в гонках. А
Impulse нужна для разового приложения силы - разгон пули, удар по мячу, прыжок, и т.д.
3. Функция отслеживания нажатий. Используйте для этого всегда Update, вместо FixedUpdate. Дело в том, что класс Input предоставляет информацию, которая опирается именно на период обновления экрана (ему соответствует Update). Например, вот в этом кадре вы нажали пробел и продолжаете удерживать кнопку вправо. FixedUpdate же лучше использовать для применения постоянных сил (вроде движения).
Просто из-за разного периода работы вполне может быть такая ситуация, что ваш ввод просто потеряется или, наоборот, данные о нём останутся на следующую итерацию приложения сил, когда игрок уже перестал нажимать. Чтобы переносить данные между ними, воспользуйтесь полем класса.
Вот примерно так будет выглядеть простое движение с Rigidbody2D:
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[DisallowMultipleComponent]
public class PlayerMovementDemo : MonoBehaviour {
private Rigidbody2D _Controller;
private float _MovementInput;
public float movementSpeed;
public float jumpingForce;
[Space(10)]
public Transform groundCheckPoint;
public float groundCheckDistance;
public LayerMask groundIdentity;
private void Start() {
_Controller = GetComponent<Rigidbody2D>();
}
private void Update() {
_MovementInput = Input.GetAxis("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
_Controller.AddForce(Vector2.up * jumpingForce, ForceMode2D.Impulse);
}
private void FixedUpdate() {
_Controller.velocity = new Vector2(_MovementInput * movementSpeed, _Controller.velocity.y);
}
private bool IsGrounded() {
return Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckDistance, groundIdentity);
}
}