Greetings all
This is my first post here. A search on these forums for “ternary” got no results so I’m asking for help from those who might know. I’ve downloaded the 30 day trial and am trying to get my head wrapped around Unity3D’s scripting idiosyncrasies; I’m used to using Director 11 on a PC, so I’ve got the whole PC-to-Mac adjustment going on as well. Anyway, i’ve tried to use the ternary operator in one of my javaScripts but I get the following error:
“Expressions in statements must only be executed for their side-effects.”
when there was a call to a Transform’s Rotate method. The line of code:
(modelXform.rotation.z > 0) ? modelXform.Rotate(0, 0, -0.001) : modelXform.Rotate(0, 0, 0.001);
When I turned that one line into two the error went away:
var rotateAngle : float = (modelXform.rotation.z != 0) ? -0.001 : 0.001;
modelXform.Rotate(0, 0, rotateAngle);
I also tried with a custom function, got the error again. The ternay in Update():
(Input.GetAxis("Vertical")) ? bigDummy("true") : bigDummy("false");
The custom function:
//////////////// test function
function bigDummy(theValue)
{
print("I'm a big dummy: " + theValue);
}
This also generated the error. By the way, I’ve seen the print function in code examples; where does it print to? It’s not syntax colored in Unitron but throws no errors.
Are no function/method calls allowed in the ternary operator? That would be unfortunate If so. Thanks in advance for info/advice.
Nope, you can only assign values when doing ternary operations, not execute functions. But you can still use one line:
modelXform.Rotate(0, 0, (modelXform.rotation.z > 0) ? -0.001 : 0.001);
And:
bigDummy(Input.GetAxis("Vertical")? "true" : "false");
Note that GetAxis returns a float, though, not a boolean. Hints: don’t use values like “.001” when doing Rotate in Update, but rather “.1 * Time.deltaTime”, or else you get framerate-dependent speed. “transform.rotation” isn’t what you think–it’s a quaternion, so you’d want “transform.eulerAngles” instead.
–Eric
The limitation of the ternary operator isn’t just a Unity limitation, it’s just the way it works in .NET (Mono). This page from the MSDN C# docs might help to explain why it works that way - the ternary operator is only intended for basic assignments, if the statement in the second or third block can’t be evaluated by type at all then the compiler gets confused.
Also, the print function just prints to the console. It works similarly to Debug.Log, but I’m not certain if there’s any significant difference as to which console log it writes to though.
The problem is not that you can’t use functions in the branches of the conditional (ternary) operator, but that you can’t use the conditional operator as a statement on its own. For example, this is not allowed as a single statement:
(a ? b : c);
…because it’s just an expression which does nothing but throw its value away. In theory, using functions for a, b or c should at least make it into an expression with side effects, but it apparently still doesn’t allow it in either Javascript or C#.
This, however, is fine:
var result = (a ? FunctionB() : FunctionC());
…and so is this:
SomeFunction(a ? FunctionB() : FunctionC());
You are allowed to use functions which return appropriate types (as per the limitations described in dawvee’s link) providing you do something with the result of the expression.
Of course, if you really do want to throw the result away, you can just use an if-else statement.
Thanks all for the great info! Its nice to know that one can post here and get helpful and insightful replies instead of “Read The Manual”.
Seems all IDEs have little things here and there that are slightly different from each other. On the whole I’m liking Unity. It’s not too difficult to get started in. I’ll admit I was afraid it would be frustrating, but it’s not been too bad at all. Of course one of the main things I’ve learned is how little I know!
eulerAngles vs Quaternions is something that will take some getting used to.
I’ve noticed that “if” statements resolve to false when given a zero to evaluate and true for any other number, but that’s relying on “zero-or-not” and is an admittedly bad practice; I’m too used to being lazy I suppose.
Thanks again everyone.
Very old post and such but if it can help someone, in Unityscript you can doing it this way :
var foo : int = 5;
function myFunc_a(){ Debug.Log("Do this"); }
function myFunc_b(){ Debug.Log("Do that"); }
((foo == 3) ? myFunc_a : myFunc_b)();