при повороте движение велосипеда ощущается как движение велосипеда по льду

#c# #unity3d #rigid-bodies

#c# #unity3d #твердые тела

Вопрос:

всякий раз, когда я поворачиваю свой велосипед, кажется, что он скользит. Вот сценарий

     [SerializeField] float turn;
    [SerializeField] float maxSpeed;
    [SerializeField] GameObject bikeParts;
    [SerializeField] float tilt = 20f;
 
    Rigidbody rb;
    float lastY;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
    void Update()
    {
        float straightMov = Input.GetAxis("Vertical");
        float horizontalMov = Input.GetAxis("Horizontal");


        ControlStraightMov(straightMov);
        ControlWeightTurning(horizontalMov);

        lastY = transform.position.y;
    }

    private void ControlWeightTurning(float horizontalMov)
    {
        Vector3 bikePartsRot = bikeParts.transform.eulerAngles;
        bikePartsRot.x = tilt * horizontalMov;
        bikeParts.transform.eulerAngles = bikePartsRot;

        transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
    }

    private void ControlStraightMov(float straightMov)
    {
        if (straightMov > 0)
        {
            rb.AddRelativeForce((accel * Time.deltaTime) * -straightMov, 0f, 0f);
        }
        else if (straightMov < 0)
        {
            rb.AddRelativeForce(((accel / 1.3f * Time.deltaTime) * -straightMov), 0f, 0f);
        }
    }
  

Всякий раз, когда велосипед набирает скорость, становится очень сложно поворачивать велосипед, потому что добавленная сила продолжает перемещать велосипед в направлении, отличном от направления, в котором стоит велосипед, как мне применить ту силу, с которой он сталкивался раньше, в направлении, в котором он находится сейчас, чтобы он не чувствовалнравится скользить?

Я пытался решить эту проблему, но просто не могу, потому что я новичок в unity.

Ответ №1:

как мне применить ту силу, с которой он сталкивался раньше, в направлении, в котором он находится сейчас

Не уверен, что это будет правильно, но вы, вероятно, могли бы сделать это, например

 private void Update ()
{
    ...

    rb.velocity = transform.forward * rb.velocity.magnitude;
}
  

Который сохранит текущую скорость и просто перенаправит ее в новое прямое направление.


В общем, обратите внимание: всякий раз, когда возникает Rigidbody проблема, вы не хотите устанавливать какие-либо манипуляции через Transform компонент, а только через Rigidbody .

Поэтому вам не следует делать

 bikeParts.transform.eulerAngles = bikePartsRot;

transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
  

но оба раза лучше рассчитать целевое вращение и пройти, например rb.MoveRotation , in FixedUpdate .

Что может выглядеть примерно так

 float horizontalMove;

void Update()
{
    var straightMove = Input.GetAxis("Vertical");
    // Get and store the input in Update
    horizontalMove = Input.GetAxis("Horizontal");

    ControlStraightMov(straightMove);
    
    lastY = transform.position.y;
}

private void FixedUpdate ()
{
    // Handle it in FixedUpdate
    ControlWeightTurning(horizontalMove);
}

private void ControlWeightTurning(float horizontalMove)
{
    var bikePartsRot = bikeParts.transform.eulerAngles;
    bikePartsRot.x = tilt * horizontalMove;

    // Calculate the new final rotation
    var newRotation = Quaternion.Euler(bikePartsRot) * Quaternion.Euler(Vector3.up * (turn * Time.deltaTime) * horizontalMove));

    // Apply it only via the Rigidbody
    rb.MoveRotation(newRotation);
}