# How to set transform.up without locking the y-axis?

I'm trying to make an object's transform.up to a normal of the raycastHit point. I tried using this line of code:

transform.up = Vector3.Lerp(transform.up, normal, 1 * Time.deltaTime);


This works well but locks the y-axis rotation as a result the object can't rotate and just keeps going forward. I tried using Quaternion.LookRotation. But I couldn't make it affect the object's rotation. Here is what I tried:

bodyRotation = Quaternion.LookRotation(transform.forward, normal);
transform.rotation = Quaternion.Slerp(transform.rotation, bodyRotation, 100 * Time.deltaTime);


How can I set the transform.up without locking the y-axis?

When you assign a value to transform.right/up/forward, you're implicitly telling Unity "I care only about the direction of this one axis - do whatever is cheap and easy with the other two". If you care about both the up and forward direction, then you need to take responsibility for constructing a quaternion with your desired orientation.

Fortunately, this is easy, as I've covered in several past answers:

Quaternion TurretLookRotation(Vector3 approximateForward, Vector3 exactUp) {
Quaternion zToUp = Quaternion.LookRotation(exactUp, -approximateForward);
Quaternion yToz = Quaternion.Euler(90, 0, 0);
return zToUp * yToz;
}


You can incorporate this like so:

var targetRotation = TurretLookRotation(transform.forward, normal);

transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, speed * Time.deltaTime);


I've used RotateTowards in place of Lerp/Slerp here, because your lerping expressions were not not correctly adjusting for deltaTime.

• It does unlock the y-axis. But the rotation is a bit jittery on terrain: youtu.be/XHmikK0MXiA Jul 13, 2021 at 15:55
• Then you can reduce the speed variable. If that doesn't solve it, then you may have another script fighting with this one for control of the rotation. Jul 13, 2021 at 15:58