User Tools
Sidebar
Using RAIN
AI Characters
Environment
Table of Contents
Expressions
Expressions in RAIN are fairly similar to what you might see in C#, C++, and C. They are used throughout RAIN behavior trees in Constraint and Expression nodes and on any field that is marked with an e.
Variables
Variables are words (always starting with a letter or _
with no spaces) that can store values to be referenced later. They are stored in the AI Basic Memory and can be set and accessed throughout all of your components.
To speed up development in a behavior tree, variables can represent any type of value at any time (float, int, GameObject, etc), and can be created at any time just by using them. This can lead to a few problems to watch out for:
- It is possible to call operators that don't make sense, like
myTarget += 1
wheremyTarget
is a GameObject. If this happens RAIN will just ignore the expression. - If you misspell a variable name it will create a new variable at that moment and use it, giving you results that may not make sense.
- If variables are used before they are assigned they will take on a default value. Depending on the equation they are in this will change.
Use the Behavior Tree debugging and watch the AI BasicMemory during playback to help figure out what is going on with your expressions. Good naming habits will also help you keep track of variables better.
Unary Operators
To negate a boolean you can use a !
(bang) and to negate a float or integer you can use a -
(negate).
shouldJump = !shouldJump
x = -y * deltaTime()
Assignment Operators
For assignment you can use =
(assignment), +=
(addition assignment), -=
(subtraction assignment), *=
(multiplication assignment), and /=
(division assignment).
movementSpeed = 10
movementSpeed += 100
Logical Operators
For logical operations you can use &&
(AND), ||
(OR), or ^
(XOR).
shouldJump = x || y
x ^ y
Relational Operators
For relation operations you can use ==
(equal), !=
(not equal), ~~
(approximately), !~
(not approximately), >
(greater than), >=
(greater than or equal), <
(less than), and <=
(less than or equal). ~~
and !~
only apply to decimal numbers (in any useful way at least) and means that the two values are pretty much equal (within a small amount).
shouldJump = x ~~ 10
x < 10
Arithmetic Operators
For arithmetic you can use +
(addition), -
(subtraction), *
(multiplication), or /
(division).
x = y + 10
x = (y + 10) * deltaTime()
Increment, Decrement
To increment or decrement you can use ++
(increment) and --
(decrement). Currently RAIN only supports pre-increment and pre-decrement (vs. post-increment and post-decrement).
shouldJump = ++x == 10
++x
--x
Multiple Expressions
You can use ;
(separator) to execute multiple statements.
x = 5; y = 10
x = false; ++y
Built in Functions
There are also several built in functions for use in your expressions:
- deltaTime: Behavior trees are evaluated every Update step, so deltaTime will return whatever UnityEngine.Time.deltaTime would have been in the Update call.
x = 5 * deltaTime()
y += deltaTime()
- currentTime: currentTime will return whatever UnityEngine.Time.time would have been in the Update call.
x = currentTime()
x > currentTime()
- clamp: Similar to the Mathf.Clamp function in Unity.
x = clamp(x, 0, 1)
x = clamp(x, 0.5, 10.0)
- min: Similar to the Mathf.Min function in Unity.
x = min(0, 1)
x = min(x, 10)
- max: Similar to the Mathf.Max function in Unity.
x = max(0, 1)
x = max(10, x)
- debug: Similar to Debug.Log function in Unity.
debug("My value is: " + x)
debug(x)
- random: Similar to Random.value property and Random.Range function in Unity.
x = random()
x = random(0, 10)
- gameobject: Finds a game object in the scene and returns it.
x = gameobject("Player")
- waypoints: Returns a Waypoint Route or Waypoint Network with the given name.
x = waypoints("Patrol Route")
x = waypoints("Walkable Path")
- position: Returns the Vector3 position associated with an object. The object can be a GameObject, Transform, RAINAspect, NavigationTarget, MoveLookTarget, or Vector3.
x = position(enemy)
- navigationtarget: Returns a Navigation Target with the given name.
x = navigationtarget("SpawnPoint1")
Keywords
Within any expression you can use the following keywords:
null
: Useful when assigning to or checking a variable that contains a GameObject.true
: Useful when assigning to or checking a variable that contains a boolean.false
: Useful when assigning to or checking a variable that contains a boolean.
Supported Types
- int: Short types will be used as ints. Any whole number in an expression will be treated as an int.
- long: Only settable from code.
- float: Any decimal number in an expression will be treated as a float.
- double: Only settable from code.
- bool: Usually represented by a
true
orfalse
keyword. Any number can be treated as a bool as well, where 0 isfalse
and everything else istrue
. - string: Anything in
""
in an expression will be treated as a string. - Vector2: Represented by
(x, y)
in an expression. - Vector3: Represented by
(x, y, z)
in an expression. - Vector4: Represented by
(x, y, z, w)
in an expression. - GameObject: Cannot be represented in an expression directly, but can be assigned to a variable in code.
Default Values
In the event that a variable is used but is undefined it will take on the default value required for the equation. Some examples:
myVariable + 1
will be 1 (myVariable
is changed to0
)"Hello" + myVariable + "World"
will be"HelloWorld"
(myVariable
is changed to""
)!myVariable
will betrue
(myVariable
is changed tofalse
)
The default values are as follows:
- int:
0
- float:
0.0
- bool:
false
- string:
""
- Vector2: Vector2.zero
- Vector3: Vector3.zero
- Vector4: Vector4.zero
- GameObject:
null
Valid Operations
Not all operators work with all types. Most of the Unary Operators won't attempt a conversion because they lack any hints. In most cases this results in a return value of null
(or whatever default type you try to convert it to).
On the other hand, some operators and functions will attempt to do a conversion no matter what. For instance, almost any type can become a string. Some examples:
"someString"++
returns""
because++
isn't compatible with strings"someString" + 0.55
returns"someString0.55"
debug(prettyMuchAnyVariable)
prints the string representation of that variable to the logmin("one string", "another string")
will return""
because it isn't compatible with strings