I'm currently running into an issue with my character controller using physics-based movement of rigidbodies in Unity.
Here's an illustration of the issue I'm facing:
Basically, after a jump, my character sticks to the ground for a split second after landing from a jump. While I have no idea, I just assumed this had something to do with the way Physics were being implemented, given that a portion of the character's velocity is heading downward, it makes sense that there would be some "impact time". I drew a bit of depenetration in the diagram, but that's mostly some creative thinking by me, I don't actually know if that has anything to do with it.
My current solution is to do this during the "landing" frame:
// first frame that the ground is detected
var velocity = rigidbody.velocity;
velocity.y = 0;
rigidbody.velocity = velocity;
This works nicely. However, I've now implemented custom gravity into the project, which allows for completely arbitrary gravity vectors (meaning I can't just set something to 0
and be done with it).
Is it possible to nullify all force in the "gravity" direction upon landing? It's also possible I've got a problem elsewhere if this reads like something that should be happening.
Here's a snippet that has the meat of my movement code:
var velocity = rigidbody.velocity;
var normal = CollisionHelper.GetFloorNormal(capsuleCollider, true);
Vector3 xAxis = ProjectDirectionOnPlane(rightAxis, normal);
Vector3 zAxis = ProjectDirectionOnPlane(forwardAxis, normal);
float currentX = Vector3.Dot(velocity, xAxis);
float currentZ = Vector3.Dot(velocity, zAxis);
float acceleration = isGrounded ? defaultAcceleration : airAcceleration;
float maxSpeedChange = acceleration * Time.deltaTime;
var desiredVelocity = new Vector3(wrapped.input.move_H, 0, wrapped.input.move_V) * defaultSpeed;
float newX = Mathf.MoveTowards(currentX, desiredVelocity.x, maxSpeedChange);
float newZ = Mathf.MoveTowards(currentZ, desiredVelocity.z, maxSpeedChange);
velocity += xAxis * (newX - currentX) + zAxis * (newZ - currentZ);
rigidbody.velocity = velocity;