I'm playing around with Unity, trying to make a neat 3rd person platformer movement system using rigidbodies so that I may in the future implement things like pushing boxes/physics objects, grappling hooks, etc... as well as I'm not really knowledgeable in terms of math and physics to be able to code them from scratch using CharacterController
What I've done is I've implemented some basic movement by setting velocity directly
Vector2 input = GetInput();
bool hasInput = Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon;
bool isDashing = dashCounter > 0f;
if (hasInput && !isDashing)
{
Vector3 direction = GetDirection(); // get camera direction scaled by forward & right vectors
transform.localRotation = Quaternion.LookRotation(direction);
UpdateTargetSpeed(input); // update target speed based on movement direction
Vector3 movementVector = new Vector3(input.x * TargetSpeed, 0f, input.y * TargetSpeed); // add speed to input vector
movementVector = transform.localRotation * movementVector; // rotate the vector to where the character is facing
movementVector = Vector3.ClampMagnitude(movementVector, TargetSpeed); // clamp magnitude to avoid faster speed on diagonals
body.velocity = new Vector3(movementVector.x, Velocity.y, movementVector.z);
}
And I'm also projecting velocity on ground normal for slopes so that the character doesn't fly off when moving down slopes
if (wasPreviouslyGrounded && !jumping && groundCheck.CanStick)
{
float slopeAngle = Mathf.Abs(Vector3.Angle(groundCheck.StickyContactNormal, Vector3.up));
if (slopeAngle < 85f)
{
body.velocity = Vector3.ProjectOnPlane(Velocity, groundCheck.StickyContactNormal);
}
}
I have implemented jumping and dashing using AddForce
body.AddForce(0f, movementSettings.JumpForce, 0f, ForceMode.Impulse);
This all works okay but everywhere I looked people are always claiming that setting velocity directly is a bad practice and should be avoided. I've seen suggestions to use AddForce
instead, but I haven't been able to get the same movement with it, no matter which force mode I used. I am also lost on how to control the amount of force I'm giving to the body during continuous movement. The thing I did is to check the magnitude of body's current velocity and if it's at or above the target speed then forgo applying the force but that just makes the body continuously accelerate and decelerate giving off jittery movement
if (body.velocity.sqrMagnitude < TargetSpeed * TargetSpeed)
{
body.AddForce(force, ForceMode.VelocityChange);
}
Can anyone ELI5 me the answers to the following questions:
- Why exactly is setting velocity directly a "bad practice"?
- What is the preferred alternative?
- How can I get snappy and responsive movement without setting the velocity directly?
- How can I accomplish sticking to the ground when going down slopes without projecting and setting the velocity directly?