ForceMode.VelocityChange isn't working

I have a dash move and I want it to keep a fixed speed, even if its being spammed. I thought AddForce() with ForceMode set to ForceMode.VelocityChange would do this, but it doesn’t seem to be changing the velocity as much as it is adding to it.

                Vector3 camForward = new Vector3(cam.forward.x, 0, cam.forward.z);
                rb.AddForce(camForward * dashForce, ForceMode.VelocityChange);

                Debug.Log(rb.velocity);

This gives me results like this


I even tried clamping the velocity like this

                Vector3 camForward = new Vector3(cam.forward.x, 0, cam.forward.z);
                rb.AddForce(camForward * dashForce, ForceMode.VelocityChange);

                Vector3 velocity = rb.velocity;
                velocity.x = Mathf.Clamp(velocity.x, -maxVelocity, maxVelocity);
                velocity.z = Mathf.Clamp(velocity.z, -maxVelocity, maxVelocity);

                rb.velocity = velocity;
                Debug.Log(rb.velocity);

but this didn’t change anything, which seems weird to me. Even when setting maxVelocity to 0 it didn’t affect the rigidbody’s velocity at all.

I did manage to find one solution which was to set the rigidbody’s velocity directly.

                Vector3 velocity = camForward * dashForce;
                velocity.x = Mathf.Clamp(velocity.x, -maxVelocity, maxVelocity);
                velocity.z = Mathf.Clamp(velocity.z, -maxVelocity, maxVelocity);

                rb.velocity = velocity;

but this pushed the player way left and way right and never just straight forward where they were looking. I guess cause camForward is the cameras x and z both multiplied by dashForce, thus exaggerating the values? But I still don’t really know.

Anyone know what I’m doing wrong here?

I’ve had big problems with VelocityChange I think I read somewhere not to use it. You’ll be better off by multiplying dashForce by some big number and removing VelocityChange.

	void Update()
	{
		if (Input.GetKeyDown(KeyCode.Q))
			rb.AddRelativeForce(0,0,dashForce-Vector3.Dot(transform.forward,rb.velocity),ForceMode.VelocityChange);
	}
1 Like