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!

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.