Rotating a player to match terrain slope

Hello everyone,

I know this is a common question but unfortunately the common solutions aren’t working. I’m building a snowboarding game and I’m trying to align my player to match the slope of my terrain object. I have a Rigidbody on my object to handle the physics. I have rotation locked on all three axis so that the object just slides down the slope. However this means that the object doesn’t line up properly with the terrain and causes the front end to stick up as shown in the picture.

I’ve tried using Raycasts from transform.position as well as from two empty game objects, one on the front and the back of the board and even trying to rotate the rigidbody itself. I don’t know whether to try removing the rigidbody and generating the physics myself.

Does anyone have any ideas on what else I can try?

You’ll want to find the normal of the ground below and then make your body rotate based on that.
Here is some simple code.

	RaycastHit hit;			
	if(Physics.SphereCast(transform.position, 0.5f, -(transform.up), out hit, yourDistenceToGroundYouWant, yourGroundLayers)) {  
     transform.rotation = Quaternion.LookRotation(Vector3.Cross(transform.right, hit2.normal)  
				}

I use a Sphere cast, but I think a normal ray cast will work too.
If you need more help with the vector math let me know!
Hope this helps.

Hope it helps.

  1. Create a child and attach all the physics components you want the player to have. Add a sphere collider to it so that it can roll down the mountain smoothly along with your constraints.

  2. Now the mesh of your fat guy on the ironing board is parent of this.

  3. Find the angle of the slope your player is in.

  4. Rotate the player according to the slope smoothly with Vector3.SmoothDamp()

I recently found a solution to a similar problem where I wanted to get the up vector for a golfer game object where the left foot, right foot, and club head would always be touching the ground.

            Transform leftFoot = golfer.transform.Find("Game_engine/Root/pelvis/thigh_l/calf_l/foot_l");
	Transform rightFoot = golfer.transform.Find("Game_engine/Root/pelvis/thigh_r/calf_r/foot_r");

	RaycastHit lf;
	RaycastHit rf;
	RaycastHit gb;

	Physics.Raycast(leftFoot.position + Vector3.up, Vector3.down, out lf);
	Physics.Raycast(rightFoot.position + Vector3.up, Vector3.down, out rf);
	Physics.Raycast(golfBall.position + Vector3.up, Vector3.down, out gb);
	Vector3 side1 = lf.point - gb.point;
	Vector3 side2 = rf.point - gb.point;
	Vector3 perpUp = Vector3.Cross (side2, side1).normalized;

This works if you have three points as defined in the Unity Documentation on Vector3.Cross. This may help you if you can find another point on the plane of your snowboard.