User Tools

Site Tools


behaviortrees:expressions

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 where myTarget 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 or false keyword. Any number can be treated as a bool as well, where 0 is false and everything else is true.
  • 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 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:

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 log
  • min("one string", "another string") will return "" because it isn't compatible with strings
behaviortrees/expressions.txt · Last modified: 2022/02/19 16:37 by prime