- Home /
Trouble rotating/turning on sloped surfaces
Hey there! I've been at this for who knows how long to no success trying to finagle a solution to this. So here's my issue in a nutshell (Video)
Notice how when the car is on a slanted surface, the yaw rotation doesn't rotate with the car.
The player is split up into three parts, each a child of the object before: Player (positioning, and rotation) > CarNormal (aligning with surface, fake gravity) > CarMesh (aesthetic changes to enhance gameplay).
The controls work absolutely perfectly, it's just that this one thing is driving me nuts (no pun intended). I can see the issue right here:
//Steering
transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, new Vector3(0, transform.eulerAngles.y + currentRotate, 0), Time.deltaTime * 5f);
The Player object doesn't rotate with the car, so "transform.eulerAngles.y" is always Vector3.up, essentially, which I believe is the root of the problem. However rather than a simple solution of changing it to carNormal.eulerAngles, or transform.rotation = carNormal.rotation, it becomes tricky since I'm also rotating carNormal to check for the track below it:
//Normal Rotation
if (magnetized)
{
carNormal.up = Vector3.Lerp(carNormal.up, avNorm, Time.deltaTime * alignSpeed);
carNormal.Rotate(0, transform.eulerAngles.y, 0);
}
if (!magnetized)
{
carNormal.up = Vector3.Lerp(carNormal.up, Vector3.up, Time.deltaTime * (alignSpeed / 2));
carNormal.Rotate(0, transform.eulerAngles.y, 0);
}
Where avNorm is the average normal between two raycasts.
Any change to the eulerAngles reference usually causes it to spin rapidly out of control.
Those are the only two pieces of script that are handling rotation of the car. But maybe there is a better, more elegant solution. And/or maybe some advice on how to move forward. Any advice/solutions would be appreciated! Thanks!
Answer by 12toe · Dec 07, 2020 at 09:38 PM
I GOT IT! Oh my goodness, after so many hours, it finally happened. Because I have objects nestled within other objects, the difference between transform.position and transform.localposition is a world of difference.
Here is the code now for anyone interested in building a game like this:
Align to the ground
Physics.Raycast(transform.position + (transform.up * .1f) + (carNormal.transform.forward * 0.5f), -transform.up, out hitNear, 2.0f);
Physics.Raycast(transform.position + (transform.up * .1f) + (carNormal.transform.forward * -0.5f), -transform.up, out hitOn, 2.0f);
Vector3 avNorm = (hitNear.normal + hitOn.normal) / 2f;
//Normal Rotation
if (magnetized)
{
transform.up = Vector3.Lerp(transform.up, avNorm, Time.deltaTime * alignSpeed);
sphere.AddForce(-carNormal.transform.up * magnetForce, ForceMode.Acceleration);
}
if (!magnetized)
{
transform.up = Vector3.Lerp(transform.up, Vector3.up, Time.deltaTime * (alignSpeed/12f));
sphere.AddForce(Vector3.down * gravity, ForceMode.Acceleration);
}
Turn/Steering
carNormal.localEulerAngles = Vector3.Lerp(carNormal.localEulerAngles, new Vector3(0, carNormal.localEulerAngles.y + currentRotate, 0), Time.deltaTime * 5f);
Essentially, we're keeping two rotation axes separate. There's the align to the ground, which controls the entire player object including the car. Then there's the local rotation to "carNormal" which is controlled by user input.
Bear in $$anonymous$$d, it's not a PERFECT solution, as playing around with it I see some janky-ness. But as long as the tracks are designed in a way to mitigate those situations, this solution works flawlessly.
Your answer
Follow this Question
Related Questions
Hi , how to move car from point A to B rotate then B to A using C#. 0 Answers
Object's vectors are not moving with the object, what did i do wrong? 1 Answer
On Network GameObject Movment and Rotation Problem. 1 Answer
Player Instantiate rotaion problem 0 Answers
Problems caused by non-unique Euler angle solutions 1 Answer