- Home /
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?
Answer by Fanttum · May 17, 2017 at 03:55 PM
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.
How Can You Do the code for 3D Objects ? It's working for "Rotation X". - Thanks!
Answer by Piyush_Pandey · May 04, 2017 at 06:38 AM
Hope it helps.
00) 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.
01) Now the mesh of your fat guy on the ironing board is parent of this.
10) Find the angle of the slope your player is in.
11) Rotate the player according to the slope smoothly with Vector3.SmoothDamp()
Hi Piyush, Thanks for your answer. I've already tried something similar to this and it didn't work. Unfortunately the way you have the parent/child set up the sphere collider rolls away without the mesh. The collider always needs to be on the parent
Answer by $$anonymous$$ · May 29, 2017 at 06:34 AM
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.