Hey guys,
In porting my application over to C#, I’ve encountered another snag. This code worked just fine in JS:
if (Input.touchCount == 2) {
selectedObject.transform.up = Input.touches[0].position - Input.touches[1].position;
selectedObject.transform.rotation = new Quaternion(selectedObject.transform.rotation.x, selectedObject.transform.rotation.y, selectedObject.transform.rotation.eulerAngles.z + 90, selectedObject.transform.rotation.w);
}
but now in C# it only runs the second line. In JS, since they were both running in the same frame, the second line sort of added to the first, causing my object to snap 90 degrees over THEN rotate with the gesture. Now it just snaps and stops.
Can anyone give me a hand, or suggest another way to rotate the object?
I’m not sure what’s causing the problem you’re seeing, but I can tell you that this:
selectedObject.transform.rotation = new Quaternion(
selectedObject.transform.rotation.x,
selectedObject.transform.rotation.y,
selectedObject.transform.rotation.eulerAngles.z + 90,
selectedObject.transform.rotation.w
);
Isn’t correct. It might appear to produce the correct results because of the way Unity handles the quaternion assignment internally, but if so, it’s just happenstance, more or less.
In general, you don’t want or need to work with quaternion elements directly (which includes constructing quaternions manually as in the above example). Also, the elements of a quaternion are not angles, and so the expression ‘selectedObject.transform.rotation.eulerAngles.z + 90’ is meaningless in this context.
In any case, that’s the first problem I’d address.
Thanks Jesse! I guess my issue is this: I’ve been used to working with rotations like the following:
transform.rotation.z += 90;
But with C# I get an error every time. How could I accomplish the same thing in C#?
Well, that’s never right, regardless of what language you’re using. First of all, Transform.rotation is a quaternion, and the elements of a quaternion aren’t angles, so expressions like the above don’t have any meaning. Second of all, even if you were using Transform.eulerAngles instead (the elements of which are angles), the documentation recommends not modifying the angles additively like that due to periodicity issues.
Having said all that, the issue you’re seeing with respect to C# is that in C#, Transform.position, .rotation, etc. are properties that either return a copy of the member field in question, or assign a new value to it. A side effect of this is that you can’t modify the elements directly that way in C#; instead, you’d need to do something like this:
var angles = Transform.eulerAngles;
angles.z += 90f;
Transform.eulerAngles = angles;
Or this:
Transform.eulerAngles = new Vector3(
Transform.eulerAngles.x,
Transform.eulerAngles.y,
Transform.eulerAngles.z + 90f
);
(I don’t know without checking how Unity handles Euler-angle assignments when the input angles are outside the range [0, 360), so the above examples may or may not work as expected. But, they do demonstrate how such assignments work in C#.)
Awesome, thanks Jesse it works! That’s odd, I’ve used transform.rotation.z += whatever so many times in the past and never had a problem! Anyway, in my time on the Unity forum, you’ve rescued me from myself quite a few times, so thanks again 
It’s a common pitfall. Without going into too much detail, because Unity normalizes the quaternion after each modification (presumably), treating the elements as angles can sometimes appear to produce the correct result.
An example you’ll see often on the forums is:
transform.rotation.y = 180;
After normalization, this will yield a quaternion fairly close to [x = 0, y = 1, z = 0, w = 0], which, by sheer coincidence, happens to represent a rotation of 180 degrees about the y axis
But, the correctness is purely illusory, and sooner or later, treating the elements of a quaternion as angles will almost certainly lead to incorrect behavior.