# Some skate physics problem

Discussion in 'Physics' started by Mehd, Aug 9, 2018.

1. ### Mehd

Joined:
Apr 29, 2016
Posts:
73
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
Code (CSharp):
1. Quaternion GetPhysicsRotation()
2.     {
3.         Vector3 target_vec = Vector3.up;
4.         Ray ray = new Ray(transform.position, Vector3.down);
5.
6.         if(Physics.Raycast(ray, out hit, 1.05f*height))
7.         {
8.             target_vec = hit.normal;
9.         }
10.
11.         return Quaternion.FromToRotation(transform.up, target_vec);
12.     }
• A velocity rotation: So that the character faces the direction he's going. This rotation is contrained to a plane
Code (CSharp):
1. Quaternion GetVelocityRot()
2.     {
3.         Vector3 vel = rb.velocity;
4.         if(vel.magnitude > 0.2f)
5.         {
6.             vel.y = 0;
7.             Vector3 dir = transform.forward;
8.             dir.y = 0;
9.             Quaternion vel_rot = Quaternion.FromToRotation(dir.normalized, vel.normalized);
10.             return vel_rot;
11.         }
12.         else
13.             return Quaternion.identity;
14.     }
• And finally, I an InputRotation that rotates the force applied for moving
• All of this is then tied in this function:
Code (CSharp):
1. void SkaterMove(Vector2 inputs)
2.     {
3.
4.
5.         Quaternion PhysicsRotation = aerial ? Quaternion.identity : GetPhysicsRotation(); // Rotation according to ground normal
6.         Quaternion VelocityRotation = GetVelocityRot();
7.         Quaternion InputRotation = Quaternion.identity;
8.         Quaternion ComputedRotation = Quaternion.identity;
9.
10.
11.         if(inputs.magnitude > 0.1f)
12.         {
14.             Vector3 planar_direction = transform.forward;
15.             planar_direction.y = 0;
17.
18.             if(!aerial)
19.             {
20.                 Vector3 Direction = InputRotation*transform.forward*Speed;
22.             }
23.         }
24.
25.         ComputedRotation = PhysicsRotation*VelocityRotation*transform.rotation;
26.         transform.rotation = Quaternion.Lerp(transform.rotation, ComputedRotation, RotatingSpeed*Time.deltaTime);
27.
28.
29.
30.     }

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 !

2. ### David_Liebemann

Joined:
Apr 29, 2018
Posts:
1
Hey - at around 0:30 you demonstrate a case that's working (slow speed, player is touching the ramp at all time) and around 0:39 there's a case that's not working (higher speed, player is airborne for a short time). Could it be the part
Code (CSharp):
1.  Quaternion PhysicsRotation = aerial ? Quaternion.identity : GetPhysicsRotation(); // Rotation according to ground normal
that's causing the PhysicsRotation to be an identity quaternion for a moment, and then return to rotation according to ground normal?

3. ### Mehd

Joined:
Apr 29, 2016
Posts:
73
But if it's the identity quaternion, shouldn''t it just keep its current rotation ? That was actually what I was expecting.

4. ### GoodByte

Joined:
Dec 14, 2013
Posts:
2
You are right, the way you are concatenating the rotations that should work.
Look at exactly 0:10 in the video - the instant you get airborne, the charakters rotation returns to horizontal. At that point it doesn't really feel weird, but I guess the same happens on the ramp, which then leads to unexpected behaviour.
That rotation is not in the code you have shown - all rotations in the code shown are limited by the Lerp you are using, so they can't cause instant rotations as seen in the video.

5. ### Mehd

Joined:
Apr 29, 2016
Posts:
73
Your comment led me to an idea. Because the rotation is never touched outside of this Lerp. So, I monitored the difference between my current rotation and the computed rotation and sometimes, the difference amounts to 100 degrees. So I'm gonna try to clamp it to a max threshold, see if it improves. I'll let you know !

Thanks !

GoodByte likes this.
6. ### MisterMashu

Joined:
Oct 23, 2012
Posts:
3
Hi! Try increasing the length of the downward raycast. I paused the video at 0:38 and you can see an arc on the red downward rays. To me, that makes me think they're not touching the ground, which would make your PhysicsRotation be do nothing

7. ### Mehd

Joined:
Apr 29, 2016
Posts:
73
Thanks y'all for your ideas. I think I figured it out. The Lerp speed was actually very high. A feature needed to for the quarter, but dreadful when moving in the air. Hence, I just added a AerialRotationSpeed and I just select which speed to use based on aerial boolean.

I'm implementing input rotation in the air, I'll let you guys know !

Thanks to all of you !

GoodByte likes this.
8. ### GoodByte

Joined:
Dec 14, 2013
Posts:
2
Nice, good luck then with the rest of the project! Looks really good by the way

9. ### Mehd

Joined:
Apr 29, 2016
Posts:
73
Hey ! Here's an update ! (