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 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:
myTarget += 1
where myTarget
is a GameObject. If this happens RAIN will just ignore the expression.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.
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()
For assignment you can use =
(assignment), +=
(addition assignment), -=
(subtraction assignment), *=
(multiplication assignment), and /=
(division assignment).
movementSpeed = 10
movementSpeed += 100
For logical operations you can use &&
(AND), ||
(OR), or ^
(XOR).
shouldJump = x || y
x ^ y
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
For arithmetic you can use +
(addition), -
(subtraction), *
(multiplication), or /
(division).
x = y + 10
x = (y + 10) * deltaTime()
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
You can use ;
(separator) to execute multiple statements.
x = 5; y = 10
x = false; ++y
There are also several built in functions for use in your expressions:
x = 5 * deltaTime()
y += deltaTime()
x = currentTime()
x > currentTime()
x = clamp(x, 0, 1)
x = clamp(x, 0.5, 10.0)
x = min(0, 1)
x = min(x, 10)
x = max(0, 1)
x = max(10, x)
debug("My value is: " + x)
debug(x)
x = random()
x = random(0, 10)
x = gameobject("Player")
x = waypoints("Patrol Route")
x = waypoints("Walkable Path")
x = position(enemy)
x = navigationtarget("SpawnPoint1")
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.true
or false
keyword. Any number can be treated as a bool as well, where 0 is false
and everything else is true
.""
in an expression will be treated as a string.(x, y)
in an expression.(x, y, z)
in an expression.(x, y, z, w)
in an expression.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 to 0
)"Hello" + myVariable + "World"
will be "HelloWorld"
(myVariable
is changed to ""
)!myVariable
will be true
(myVariable
is changed to false
)The default values are as follows:
0
0.0
false
""
null
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