Smooth Rotation Around 1 Axis Not Working

Hello Experts,

My search for a solution here was not successful, so here is my question please:

I have a plane in a game scene, and i want to rotate it only around Z axis, in a response to mouse x location (vertical movement of mouse, should rotate it).

I want it to be rotated, exactly as i manualy rotate it around it’s Z axis in the inspector (x and y rotation facots should remain unchanged.) Or in other words, when I run the game, I want to see the plane rotation degree is just changing arount z axis and and x and y are not changing.

I tried 2 logics in the code attached to my plane:

void Update()
{
     float tiltDegree = (Input.mousePosition.x - (Screen.width / 2))  * tiltFactor;
     //solution 1:
     Quaternion target = Quaternion.Euler(0  , 0, tiltDegree);
     transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);
     //solution 2:
     transform.rotation = Quaternion.Euler(new Vector3(transform.rotation.x, transform.rotation.y, tiltDegree)); 
}

Just assume “tiltDegree” is working properly.
The problem i have is that in both versions when i run the game, the plane x and y rotation degree changes to 49 and 56 and then it is fixed, and the rotation works around z axis.

Anyone knows the problem? it is a mater of pivot/center problem?

p.s. This plane is located in a parent empty object that has the desired location and rotation. As a result, my plane location, as well as rotation is (0,0,0).

Thank you so much :slight_smile:

The problem with code above, is that the natural orientation of the rotated needs to be (0,0,0). Your object starts out with a rotation of (83, 148, 337). In your comment above, I though you said you were using an empty game object, but I don’t see an empty game object. Here are the steps I recommend:

  • Create an empty game object
  • By copying and pasting the x,y,z components of the object’s position, place the empty game object at the same position as the visible object.
  • Make the visible object a child of the empty game object.
  • Delete the CBoxTiltControl script from the visible game object.
  • Add the CBoxTiltControl script to the empty game object and set Max Rotation Angle.
  • Hit Play

Note the position, object rotation and the camera rotation is very strange. I don’t know your game mechanic, but typically the camera would be axes aligned and looking at the origin (as is true in a new scene). An when dealing with 2D-like things, they would be place near the origin with a ‘z’ value of 0. If you did this, you could use a Quad, or a plane created by the CreatePlane editor script and not have to use an empty game object.

@robertbu
Thank you for your reply. Actually in the sample game, I do have an empty GameObject. In my game, there is another problem, the parent empty game object is a child for another master object and all of them are rotating together! :)) I’m in big trouble!

So, based on your very helpful comment, it seems there is only one specific config that leads to solution:

  1. Create your visible game object (in my example a plane) and locate/rotate it as desired.
  2. Create an empty object, copy and paste (x, y, z) location from plane to empty object location, so it will be in the same location as the child.
  3. Place the plane as a child for the empty obj.
    Now here are the important steps:
  4. Set the rotation of parent to (0, 0, 0) and set the position of child to (0, 0, 0). So, in the hierarchy you have the position on the parent, and rotation on the child. (It is the only way it works!)
    Add this MonoBehavior script to the parent:

private float smooth = 2.0F;
private float tiltFactor;

public float MaxiumRotationAngle;

void Start()
{
tiltFactor = MaxiumRotationAngle / (Screen.width / 2);
}

// This code will tilt your object around Y axis,
// from -MaxiumRotationAngle to +MaxiumRotationAngle degree
// based on your mouse location relative to screen center
void Update()
{
float tiltDegree = (Input.mousePosition.x - (Screen.width / 2)) * tiltFactor;

Quaternion target = Quaternion.Euler(0, tiltDegree, 0);
transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);

}