Search code examples
c#unity-game-enginerigid-bodies

How to prevent speeding of rigidbodies used to control characters


I have a player in unity with the movement controlled by a rigidbody. The movement on the Z axis is kept contstant by the game to keep the player moving forward. However, this means that the rigidbody keeps speeding up so its speed at the start of the game is much slower than the speed at the end of the game. Here is my script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

public class Controller : MonoBehaviour
{
    [Tooltip("Rigidbody component attached to the player")]
    public Rigidbody rb;
    public float forwardMax;
    public float slowBy;

    private float movementX;
    private float movementY;
    private float gravity = -9.81f;
    private bool isJumping = false;
    private bool isSlowing = false;
    private bool isSpeeding = false;
    private float speedX = 100;
    private float speedY = 150000;
    private float speedZ = 60;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
    void Update()
    {
        // if(!controller.isGrounded)
        // {
        //     Vector3 gravityVector = new Vector3(0.0f, gravity, 0.0f);
        //     rb.AddForce(gravityVector * Time.deltaTime);
        // }
    }
    void OnCollisionEnter(Collision collision)
    {
        // SceneManager.LoadScene(1);
    }

    // Update is called once per frame
    void OnMove(InputValue movementValue)
    {
        Vector2 movementVector = movementValue.Get<Vector2>();

        movementX = movementVector.x;
        movementY = movementVector.y;
    }

    void OnJump()
    {
        isJumping = true;
    }

    void CalculateMovement()
    {
        if(rb.velocity.z > 20)
        {
            rb.drag = 20;
        }
        else
        {
            rb.drag = 0;
        }

        Vector3 movement = new Vector3(movementX * speedX, 0.0f, speedZ);
        if(isJumping)
        {
            movement.y += Mathf.Sqrt(speedY * -3.0f * gravity);
            isJumping = false;
        }
        rb.AddForce(movement);
        Debug.Log("Speed is " + rb.velocity.z);
    }
    void FixedUpdate()
    {
        CalculateMovement();
    }

}

Is there a way to keep the forward velocity constant? The problem is worse when the player jumps.

First I tried clamping the forward (z-axis) vector but that had no effect. Then, I tried adding a backward vector onto the total when the forward velocity was above a certain number but this led to it speeding up and slowing down all the time. Then I tried the same thing with the drag on the rigidbody but that had the same effect.


Solution

  • How about directly setting the z value you want at the end of FixedUpdate() ?

    ......
    
    void FixedUpdate()
    {
        CalculateMovementWithoutZMovement();
        rb.velocity = new Vector3 (rb.velocity.x, rb.velocity.y, ConstantZValue);
    }