- Home /
Rotation with a slider
I am trying to set up a slider (that starts at 0.5) that can be used to rotate around the x axis (-180 to + 180). I am not fully understanding how rotation works, however.
Here is my code
//percent is the value of the slider
float angle = 180;
float rotation = ((angle * 2) * percent) - angle;
transform.localRotation = Quaternion.Euler(rotation, transform.localEulerAngles.y, transform.localEulerAngles.z);
Since I will be adding sliders for the y and z rotation as well, I don't want them to be affected by the x slider. The code above doesn't work. It produces a seemingly random angle while sliding the slider.
EDIT: Doing this code below seems to output strange results.
Vector3 vec = new Vector3(rotation,0,0);
vec = Vector3.Scale(transform.localEulerAngles, new Vector3(0,1,1)) + vec;
transform.localEulerAngles = vec;
Debug.Log(rotation + " " + transform.localEulerAngles);
The log then outputs (going from -180)
-180 (0, 180, 180) -168 (348,0,0) -156 (336,180,180) -144 (324,0,0) -132 (312, 180,180) -120 (300,0,0) -108 (288,180,180) -84 (276,0,0) ... (the rest are actually correct)
What is happening? Why is Y and Z rotation getting set to 180? Why is the X inaccurate? It appears anything not in the range of -90 to 90 screws up. Why?????
Answer by DaveA · Jul 16, 2012 at 08:36 PM
set your slider's min value to -180, max to 180, and just stuff it in, something like this (not tested)
OnGUI()
rotx = GUI.Slider (xRect, rotx, -180f, 180f);
var temp = transform.localEulerAngles;
temp.x = rotx;
transform.localEulerAngles = temp;
I am using an NGUI slider, so that won't work. I am getting the proper angle with my formula, that is not the problem.
Also, transform.localEulerAngles.x throws an error because you are modifying a vector property that can only be read. "error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.localEulerAngles'. Consider storing the value in a temporary variable"
Ah ok. Well you can
var temp = transform.localEulerAngles;
temp.x = rotx;
transform.localEulerAngles = temp;
I modified my question above to show why that isn't working. I don't know the problem.
Eulers can be unpredictable due to 'gimble lock' when pitch is 90 or -90. If you really need Eulers, consider nesting the object in several transforms, one for each axis of rotation, and just affect the component on that axis. Or consider going with Quats for everything.
Oh, I see. How would I use Quaternions? I have tried, but I can't figure out how to rotate a single axis this way without it adding to the current rotation. I need the 0 to equal -180, and 1 to equal +180.
I have tried both of these, and neither works as intended.
//This rotates as expected, but it affects the other rotations.
Quaternion rot = Quaternion.AngleAxis(rotation, new Vector3(1,0,0));
//So I tried doing this with it, but that doesn't work. (I don't really understand what w is either).
transform.localRotation = new Quaternion(rot.x, transform.localRotation.y, transform.localRotation.z, transform.localRotation.w);
//I have also tried doing this with the rotation calculated in the question above
transform.localRotation = Quaternion.Euler(rotation, transform.localEulerAngles.y, transform.localEulerAngles.z);
Answer by DoctorWhy · Jul 18, 2012 at 07:42 AM
Ok, so I think I understand what was going on.
When things are rotated over 90, Unity acts really strange when handling how it displays it. The rotation worked, but it seemed like it was spazzing out because after you assign the Euler angles, they may get changed for whatever reason, but the rotation should still look the same. So simply doing
float angle = 180;
float rotation = ((angle * 2) * percent) - angle;
x = rotation;
transform.localEulerAngles = new Vector3(x,y,z);
Worked. Where x, y, and z are the angles calculated by the slider. Just don't read the Euler rotations or you would think something is broken. Unity has the most complicated rotation I have ever used in a game engine, and I have used several...