How do I rotate a Rigidbody to a surface normal AND use camera rotation?

Ok a little bit of setup. The game uses different coloured surfaces that the player can either slide along or bounce off of. What I’m looking to have is that the player will be able to rotate along these surfaces based on the surface normal. I have a screenshot here showing what it should be able to accomplish.

As you can see, the character is matching the surface normal (the blue ray being drawn). The problem is, that the game requires to match the camera rotation on the y axis, so that turning the camera left and right rotates the character to face that direction. In this image, the character rotates properly because they rotate strictly based on the surface normal and have no other rotation affecting them, resulting that all levels would essentially require that the player can only move straight and strafe left and right (which is not as fun).

Here is a screenshot of what happens when the only change I make is to have the character’s y rotation match that of the camera’s rotation.

You can see that the surface normal, the blue ray being drawn, is not the angle that the player rotates at. Heck it makes 0 sense to me why it starts rotating like that based on the surface it’s touching.

Now here is some code. There are 2 different scripts running, one is an invisible game object that should rotate to match the surface normal instantly and then the player lerp’s to the rotation of the invisible game object. This is for smoother transitions and more readable gameplay (as suggested by a mentor of mine).

Invisible game object script:

    transform.position = player.position;
		if(Physics.Raycast(transform.position, Vector3.down, out hitCast, distanceFromObject))
			Debug.DrawRay(hitCast.point,hitCast.normal * 100,;
			transform.rotation = Quaternion.FromToRotation(Vector3.up, hitCast.normal);

distanceFromObject being a float I set to determine how close to the surface I want the object to be before it reacts to the surface normal.

For the player, it takes the invisible game objects rotation and applies it to itself with this code.

        Quaternion rotateProperly;
		Quaternion rotationTarget = playerFollow.rotation;

		rotateProperly = Quaternion.Lerp (transform.rotation, rotationTarget, slideRotationTime*Time.deltaTime);
//		transform.rotation = Quaternion.Euler(new Vector3(rotateProperly.eulerAngles.x, rotateProperly.eulerAngles.y, rotateProperly.eulerAngles.z));
		transform.rotation = Quaternion.Euler(new Vector3(rotateProperly.eulerAngles.x, Camera.main.transform.localEulerAngles.y, rotateProperly.eulerAngles.z));

The playerFollow is the invisible gameobject and the one commented line is what’s used to create the first screenshot you saw. As you can see, the only different between them is the camera rotation being the y, and I’m not sure why it messes with it so much.

The camera script is similar to the one from this thread. It works great until I want to match the character’s rotation to surfaces.

Sorry that the question is kind of convoluted. I’ve been searching for quite a few hours and tried whatever I could think of to fix it, and have had some people who are on par with me at programming to help, but we haven’t gotten anywhere. I feel like I’m close to having the functionality we want, but it’s just a little short. Any help would be appreciated! I can also offer to show more code for the player controller if needed, but there are no other points in the code where the player is being rotated.


I figured it out. It’s not perfect, but it definitely gets the job done.
It’ll take a bit of work to open the project files and find exactly what I did, so I’ll leave I won’t bother unless some people are needing the help.
In the meantime, here’s our trailer that we did so that you can see it in action without having to download the build.