UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
FAQ
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
CIGI Client Plugin
Rendering-Related Classes

Operators

Once we know of the existence of variables, we can begin to operate with them. For that purpose, UnigineScript integrates operators. Operators are mostly made of signs that are not part of the alphabet but are available in all keyboards.

Numerical Operators#

Operation Operator Type Description Operand Types
Negation - unary Returns a negated value of the operand (changes its sign to the opposite) Scalars, vectors
Increment ++ unary Increments the operand by 1 (both prefix and postfix notations are supported) Scalars
Decrement -- unary Decrements the operand by 1 (both prefix and postfix notations are supported) Scalars
Multiplication * binary Multiplies one operand by another Scalars, vectors
Division / binary Divides the first operand by the second operand Scalars, vectors
Modulo % binary Returns a remainder after numerical division of the first operand by the second operand int, long, float and double
Addition + binary Adds one operand to another Scalars, vectors, string
Subtraction - binary Subtracts the second operand from the first operand Scalars, vectors

Source code (UnigineScript)
int a = 0, b = 0;
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",a,b);

/* Output:
 * 1 0
 * 2 1
 * 2 2
 */

Scalar Operands#

All numerical operators that take two operands of different types perform an automatic conversion of scalars. The result is always the biggest type of two.

Vector Operands#

Some of numerical operators are applicable to vector types. All vector types can be added to, subtracted from and multiplied by operands of the same type. However, when performing operations on different types of vector operands or vectors and scalars, only specific combinations of operands are possible, because vector types are mostly nonconvertible.

First operand Operator Second operand Result
All vector types:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
+
-
*
The same as of the first operand Type of the operands
vec3
vec4
dvec3
dvec4
ivec3
ivec4
/ The same as of the first operand Type of the operands
All vector types:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
*
/
int Type of the first operand
vec3
vec4
dvec3
dvec4
mat4
dmat4
quat
*
/
long
float
Type of the first operand
dvec3
dvec4
mat4
dmat4
quat
*
/
double Type of the first operand
vec3 *
/
double
dvec3
dvec3
vec4 *
/
double
dvec4
dvec4
vec3 +
-
dvec3 dvec3
vec4 +
-
dvec4 dvec4
dvec3 *
/
+
-
vec3 dvec3
dvec4 *
/
+
-
vec4 dvec4
mat4 * vec3
vec4
dvec3
dvec4
dmat4
Type of the second operand
mat4
dmat4
* quat Type of the first operand
dmat4 * vec3
dvec3
dvec3
dmat4 * vec4
dvec4
dvec4
dmat4 * mat4 dmat4
quat * vec3
vec4
dvec3
dvec4
mat4
dmat4
Type of the second operand

String Operators#

These operators take only string variables as operands.

Operation Operator Type Description
Concatenation + binary A string into which two operands are joined

Strings can be concatenated not only with strings but with variables of any base type due to type casting.

Source code (UnigineScript)
float a = -3.9;
string str = "there can be a mixture";
str = str + " of integer (" + 56 + ") and floating point values (" + a + ")";
log.message("%s\n", str);

/* Output: 
 * there can be a mixture of integer (56) and floating point values (-3.9)
 */

Logical and Bitwise Operators#

These operators take only the following types of variables as operands:

Operation Operator Type Description Operand Types
Logical NOT ! unary Negates a boolean expression int, long
Logical AND && binary true, if both operands are true int, long
Logical OR || binary true, if one or both operands are true int, long
Bitwise NOT (complement) ~ unary Logical negation of each bit int, long
Bitwise AND & binary Logical AND operation on each pair of corresponding bits int, long
Bitwise inclusive OR | binary Logical OR operation on each pair of corresponding bits int, long
Bitwise exclusive OR ^ binary Logical XOR operation on each pair of corresponding bits int, long
Shift left << binary Shift bit pattern in the first operand to the left by the number of bits specified by the second operand int, long
ivec3 or ivec4 can also be the 1st operand
Shift right >> binary Shift bit pattern in the first operand to the right by the number of bits specified by the second operand int, long
ivec3 or ivec4 can also be the 1st operand

All non-zero values are equal to true, however, if true should be returned as a result of some operation, it will be always 1. false is always 0.

Notice
When expressions with logical operators are evaluated, usually, short-circuit evaluation is used. That is, the second operand is only evaluated if the first operand does not suffice to determine the value of the whole expression. However, if the whole expression is enclosed in parentheses, all operands will be evaluated.

Comparison Operators#

Notice
Two float numbers are considered to be equal, if the difference between their values is less than 1E-6.

Operation Operator Description Operand Types
Equal to == Tests if both operands are equal Scalars, vectors, string
int(0) can be compared to an empty string and v.v.
Not equal to != Tests if both operands are not equal Scalars, vectors, string
int(0) can be compared to an empty string and v.v.
Less than < Tests if the first operand is less than the second operand Scalars, string
Greater > Tests if the first operand is greater than the second operand Scalars, string
Less than or equal to <= Tests if the first operand is less than the second operand or equal to it Scalars, string
Greater than or equal to >= Tests if the first operand is greater than the second operand or equal to it Scalars, string

If the statement is true, the operator returns 1, otherwise 0.

Assignment Operators#

Operation Operator Type Description
Assignment = binary Assign a value of the second operand to the first operand
"If-then-else" replacement ? : ternary Can be used for conditional assignment, if this whole expression is the second operand of the assignment

The conditional operator ?: can be used as a shorthand for what would normally be single-line blocks of the "if-then-else" construction. If used appropriately, this operator can enhance readability of code. Its syntax is the following: test_expression1 ? then_expression : else_expression.

Source code (UnigineScript)
int a = 10;
int b;
b = (a > 9) ? 100 : 200; // ternary operator usage

// this expression is equal to the previous one
if(a > 9) {
	b = 100;
} else {
	b = 200;
}
log.message("b =" + (b))
/* Output:
 * b = 200
 */

It is also possible to use the ?: operator in expressions. For example:

Source code (UnigineScript)
int a = 1;
int b = 2;
int c = 3;
int d = 4;

log.message("%s\n","test 1: " + (a == b) ? "a == b" : "a != b" + " final");
log.message("%s\n","test 2: " + ((c == d) ? "c == d" : "c != d") + " final");
log.message("%s\n","test 3: " + (a == b) ? "a == b and " + ((c == d) ? "c == d" : "c != d") : ("a != b and " + ((c == d) ? "c == d" : "c != d")));
The output of the example is:
Output
test1: a != b final
test2: c != d final
test3: a != b and c != d

The assignment operator = can be combined with +, -, *, /, %, &, |, and ^. These combined operators (+=, -=, *=, /=, %=, &=, |=, and ^=) assign the result of the operation to the first operand (which must be a variable).

Notice
UnigineScript does not support multiple assignments in an expression:
Source code (UnigineScript)
int a = 10;
int b, c;
a = b = c; // this won't work
a = b += c; // this won't work either

Access Operators#

Operation Operator Type Description
Member access . binary Access a member (the second operand) of the first operand. Can be used with:
Scope resolution ::
  • unary - for identifiers with the global scope
  • binary - for identifiers with the class or namespace scope (class/namespace members).
Access an identifier outside its scope. For details, see scope resolution operator.
Access by index [] binary Access an element by it index. Can be used with classes, vectors, maps, vec3, vec4, mat4, and quat

Type Testing Operator#

The type testing operator is serves to check the type of a given variable. The operator returns1 when:

  • A given variable belongs to a specified type
  • A given object is an instance of a specified class
  • A given object is an instance of a class that derives from a specified class

The syntax of the operator is the following:

Source code (UnigineScript)
i is int

Notice
The second operand can only be the type or class name, namely:
  • One of the scalar types
  • One of the vector types
  • String
  • User-defined class name
  • External class name

For example, this operator can be used in an if-else statement:

Source code (UnigineScript)
class Foo { };

class Bar : Foo { };

void check(int v) {
	string s = typeinfo(v);
	// both the is operator and the is_int() function check if v is of the int type
	if(v is int) log.message("%s is int\n",s);
	if(is_int(v)) log.message("%s is int\n",s);
	// check if v is of the float type
	if(v is float) log.message("%s is float\n",s);
	if(is_float(v)) log.message("%s is float\n",s);
	// check if v is an instance of the Stream class or class derived from the Stream
	if(v is Stream) log.message("%s is Stream\n",s);
	// check if v is an instance of the File class
	if(v is File) log.message("%s is File\n",s);
	// check if v is an instance of the Foo or Bar class
	if(v is Foo) log.message("%s is Foo\n",s);
	// check if v is an instance of the Bar class
	if(v is Bar) log.message("%s is Bar\n",s);
}

check(1);
check(1.0f);
check(new File());
check(new Foo());
check(new Bar());
The output is the following:
Output
int: 1 is int
int: 1 is int
float: 1 is int
float: 1 is int
File 000000000E9330E0 internal (5:0:0) is Stream
File 000000000E9330E0 internal (5:0:0) is File
Foo 000000000D06FCD0 (131072:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Bar

Operator Precedence#

If an expression contains several operators, they will be evaluated in the order shown below, from the top to the bottom.

Operation Operator
Parentheses ()
Access operators [] .
Unary operators ! - + ++ --
Multiplicative operators * /
Additive operators, string concatenation + -
Bitwise shift << >>
Comparison operators == != < > <= >=
Bitwise NOT ~
Bitwise AND &
Bitwise exclusive OR ^
Bitwise OR |
Logical NOT !
Logical AND &&
Logical OR ||
Assignment operators = += -= *= /= %= &= |= ^= ?:

Operator Overloading#

You can read about operator overloading here.

Last update: 2019-08-16