Hello y’all
I’m making a small skating game, mostly because I’m interested in mechanics but I’m stuck with an orientation problem I can’t figure out.
To adapt the rotation of the skater with respect to its environment, I break the logic into several components:
- A PhysicRotation : Returns the Quaternion to go from the skater’s transform.up to the normal of the point he’s at
Quaternion GetPhysicsRotation()
{
Vector3 target_vec = Vector3.up;
Ray ray = new Ray(transform.position, Vector3.down);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 1.05f*height))
{
target_vec = hit.normal;
}
return Quaternion.FromToRotation(transform.up, target_vec);
}
- A velocity rotation: So that the character faces the direction he’s going. This rotation is contrained to a plane
Quaternion GetVelocityRot()
{
Vector3 vel = rb.velocity;
if(vel.magnitude > 0.2f)
{
vel.y = 0;
Vector3 dir = transform.forward;
dir.y = 0;
Quaternion vel_rot = Quaternion.FromToRotation(dir.normalized, vel.normalized);
return vel_rot;
}
else
return Quaternion.identity;
}
- And finally, I an InputRotation that rotates the force applied for moving
- All of this is then tied in this function:
void SkaterMove(Vector2 inputs)
{
Quaternion PhysicsRotation = aerial ? Quaternion.identity : GetPhysicsRotation(); // Rotation according to ground normal
Quaternion VelocityRotation = GetVelocityRot();
Quaternion InputRotation = Quaternion.identity;
Quaternion ComputedRotation = Quaternion.identity;
if(inputs.magnitude > 0.1f)
{
Vector3 adapted_direction = CamToPlayer(inputs);
Vector3 planar_direction = transform.forward;
planar_direction.y = 0;
InputRotation = Quaternion.FromToRotation(planar_direction, adapted_direction);
if(!aerial)
{
Vector3 Direction = InputRotation*transform.forward*Speed;
rb.AddForce(Direction);
}
}
ComputedRotation = PhysicsRotation*VelocityRotation*transform.rotation;
transform.rotation = Quaternion.Lerp(transform.rotation, ComputedRotation, RotatingSpeed*Time.deltaTime);
}
The thing works rather well, but always stumbles on one specific case. Here’s a video I made the explain it better:
Basically, when in the quarter, if the character’s speed carries him in the air, he does a strange spin and and breaks its flow. I can’t figure out where in the code I’m allowing it to do this. I’ve tried various tests, but I can’t figure out where the problem is.
Could anyone point me in the good direction ?
Thanks !