LazyBriefcase
LazyBriefcase

Reputation: 11

Unity limit rigidbody velocity in specific direction with addforce?

I am creating a third person player movement script. The movement adds force to the rigidbody relative to the direction of the camera. I want to have a max speed limit in the forward direction (cForward), and a separate max speed limit for the horizontal/right direction (cRight). Normally I would be fine with setting the velocity directly, however this screws up gravity for the player. Is there any way to achieve this by using addforce OR is there a way to get gravity working properly when setting velocity directly? Here is what I have so far(some of my other attempts at a solution are commented out):

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

public class PlayerMovement : MonoBehaviour
{
    public Camera mainCamera;
    public float horizontalWalkSpeed = 500.0f;
    public float verticalWalkSpeed = 500.0f;
    public float horizontalSprintSpeed = 1000.0f;
    public float verticalSprintSpeed = 1000.0f;
    public bool isSprinting = false;
    public bool cannotMove = false;
    public float accelerationSpeed = 0.2f;

    private Rigidbody pRigidBody;
    private Vector2 currentInputVector;
    private Vector2 smoothInputVelocity;

    // Start is called before the first frame update
    void Start()
    {
        pRigidBody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        HandleInput();
    }

    private void FixedUpdate()
    {
        Vector3 cForward = mainCamera.transform.forward;
        Vector3 cRight = mainCamera.transform.right;

        cForward.y = 0.0f;
        cRight.y = 0.0f;
        cForward.Normalize();
        cRight.Normalize();

        

        if (!cannotMove && !isSprinting)
        {
            Vector3 vForce = cForward * currentInputVector.y * verticalWalkSpeed;
            Vector3 hForce = cRight * currentInputVector.x * horizontalWalkSpeed;
            //Vector3 gravity = Vector3.up * -9.8f;
            Vector3 force = vForce + hForce;

            //float verSpeed = Vector3.Dot(pRigidBody.velocity, cForward);
            //float horSpeed = Vector3.Dot(pRigidBody.velocity, cRight);

            //if (verSpeed >= 0 && verSpeed <= verticalWalkSpeed)
            //{
            //    pRigidBody.AddForce(vForce, ForceMode.VelocityChange);
            //}

            //if(horSpeed < horizontalWalkSpeed)
            //{
            //    pRigidBody.AddForce(hForce, ForceMode.VelocityChange);
            //}


            //float velocityInDirection = Vector3.Dot(pRigidBody.velocity, cForward);

            //if(velocityInDirection > verticalWalkSpeed)
            //{
            //    pRigidBody.AddForce(-vForce, ForceMode.VelocityChange);
            //}

            //pRigidBody.velocity = force;

            pRigidBody.AddForce(force, ForceMode.VelocityChange);
            
        }
        else if (!cannotMove && isSprinting)
        {
            pRigidBody.velocity = cForward * currentInputVector.y * verticalSprintSpeed * Time.fixedDeltaTime + cRight * currentInputVector.x * horizontalSprintSpeed * Time.fixedDeltaTime;
        }


    }

    private void HandleInput()
    {
        isSprinting = Input.GetButton("Sprint");

        Vector2 input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        currentInputVector = Vector2.SmoothDamp(currentInputVector, input, ref smoothInputVelocity, accelerationSpeed);
    }
}

Upvotes: 0

Views: 2997

Answers (1)

Seth DU - MSFT
Seth DU - MSFT

Reputation: 196

I think this thread may help --https://answers.unity.com/questions/9985/limiting-rigidbody-velocity.html. Basically, there are two methods.

  1. Add force in the opposite direction and increase with the extent to which the object exceeds the limit. This requires additional calculations and tests.
  2. simply normalize the velocity value when it exceeds the limit.

Upvotes: 1

Related Questions