Hi there,
I am trying to make my own player movement script for a 2.5D metroidvania game (using a 3D physics engine, but the movement is 2D).
I've been using AddForce() to move the player, however, when I use it, I don't get the desired behaviour.
I want the character's movement to be snappy, with instant acceleration and deceleration on the x-axis.
I have sort of achieved that with the code below, but with a strange caveat. The character moves faster or slower based on what I have the runningAcceleration set to, not maxSpeed.
I don't think I understand AddForce correctly... What I want is for the character to immediately start moving at the velocity set in maxSpeed. I set runningAcceleration to a really high number because I want it to be instant, but why does the character move faster or slower based on the runningAcceleration, shouldn't it be clamped to maxSpeed regardless?
public class Test3d : MonoBehaviour
{
public Rigidbody rb;
public Vector3 velocity;
public float runningAcceleration;
public float maxSpeed;
void Awake(){
rb = GetComponent<Rigidbody>();
}
void FixedUpdate(){
Vector3 direction = new(Input.GetAxisRaw("Horizontal"), 0, 0);
Vector3 targetVelocity = direction + velocity;
// if the player is changing direction (signs are different), ignore the current velocity
if (Math.Sign(direction.x) != Math.Sign(velocity.x)){
targetVelocity.x = direction.x;
}
rb.AddForce(targetVelocity * runningAcceleration, ForceMode.VelocityChange);
// stop the player, AddForce doesnt stop when the input is 0
if (targetVelocity.x == 0){
rb.velocity = new Vector3(0, rb.velocity.y, 0);
}
// clamp rb.velocity to max speed
rb.velocity = new Vector3(Mathf.Clamp(rb.velocity.x, -maxSpeed, maxSpeed), rb.velocity.y, 0);
velocity = rb.velocity;
}
}