> For the complete documentation index, see [llms.txt](https://malbersanimations.gitbook.io/animal-controller/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malbersanimations.gitbook.io/animal-controller/scriptable-architecture/scriptables/variable-listeners-and-comparers.md).

# Variable Listeners & Comparers

Last updated AC v1.5.3

## Overview

All variable listener and comparers are simple components that hold variable values, and react when these values change via Unity Events.

These are usually used to connect 3rdParty assets with AC, or Store variables that can be used by the Animal Brain.

Currently, these are available components:

* Float Listener
* Int Listener
* Bool Listener
* String Listener
* Transform Listener
* Vector3 Listener
* Float Comparer
* Int Comparer
* Object Comparer
* String Comparer
* Transform Comparer

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FCneGxbxWLfXUSjActsoL%2Fimage.png?alt=media&#x26;token=a333b9a8-6f61-478b-992a-469e89d1d21d" alt=""><figcaption></figcaption></figure>

## Inspector (Float, Int, Bool, String)

### Value

Value of the Listener, when the value changes, the events are raised.

The events are also raised On Enable

### ID

Identifier for the Listener component. This is useful to when there are more than one Listener of the same variable type attached to a GameObject.

### Show Events \[ ↑] \[↓]

The Right Button will show the events of each Listener Component.

## Inspector (Transform)

### Value

Value of the Listener, when the value changes, the events are raised.

The events are also raised On Enable

### Transform

The transform to listen to

### On Value Changed

Invoked when the value of the transform changes

### On Value Null

Invoked when the transform's value is null

## Inspector (Vector3)

### Value

The X Y and Z values. When the value changes the events are raised.

### ID

Identifier for the Listener component. This is useful to when there are more than one Listener of the same variable type attached to a GameObject.

## Comparers

A Comparer is a Listener with a decision table bolted on. It holds one value, and it also holds a **list of comparison rows** that you author. Every time that value changes — or every time you call `Compare()` yourself — each active row measures the incoming value against its own authored value using its own operator, and fires that row's Unity Event when the comparison passes.

That is the whole idea: instead of one "value changed" event that your own script has to branch on, you get as many named branches as you need, wired entirely in the inspector.

All of them live under **Add Component ▸ Malbers ▸ Variables**.

\[Insert Image - Int Comparer inspector with three comparison rows and the Response event of the selected row expanded]

### Shared parameters

The Float, Int and String Comparers all derive from the same Var Listener base and share one custom inspector, so they draw the same fields in the same order. The Object and Transform Comparers are built differently — see their own sections below.

#### Description

A free-text note drawn as a coloured text area at the very top. It is hidden by default; toggle it with the **Show Description** item in the component's context menu (the three dots).

#### Value

The value the comparer holds, and the value that gets compared. It is a Reference field, so it can be a plain inline value **or** a pointer to a Scriptable Variable asset. When it points at an asset and **Auto** is on, the comparer subscribes to that asset and re-compares whenever the asset changes anywhere in the project.

#### ID

An integer identifier for this component. Use it when a GameObject carries more than one comparer of the same type, so the AI Brain knows which one is meant.

#### Show Events \[ ↑] \[↓]

The button at the right of the Value row. Everything below — Auto, On Enable, the comparison list and the events — is hidden until you expand it.

#### Auto

When enabled, setting the Value runs the comparisons and raises the events automatically. When disabled the component only stores the value; you have to call `Compare()` or `Invoke()` yourself from a script or another Unity Event.

#### On Enable

Invokes the current value when the component is enabled, so inspector-wired listeners start from a known state.

#### Debug

The bug icon next to On Enable. Logs each comparison to the console as it happens.

#### Compare (list)

The reorderable list of comparison rows, with the column headers **Active / Name**, **Compare** and **Value**. Drag to reorder; the **+** and **−** buttons add and remove rows. Selecting a row reveals its own settings underneath.

#### Active

The checkbox at the left of each row. An inactive row is skipped entirely and is drawn greyed out. `Index_Enable(i)` and `Index_Disable(i)` flip it at runtime.

#### Name

A label for the row. It is purely cosmetic, but it is echoed in the title of the Response event below so you can tell the branches apart.

#### Compare

The operator. Float and Int rows offer **Equal, Greater, Less** and **Not Equal**. String rows offer **Equal, Not Equal, Empty, Contains** and **Does Not Contain**.

#### Value

The value this row compares against. Also a Reference field, so a row can be driven by a Scriptable Variable asset.

#### Description (row)

A free-text note for the selected row, drawn above its Response.

#### Update After Compare

After the comparison runs, the row's own Value is overwritten with the incoming value. This turns a row into a "did it change since last time" test rather than a fixed threshold.

#### Response

The Unity Event this row invokes, carrying the incoming value as its argument.

#### On Value Changed

Drawn at the bottom of the list, on the Float and Int Comparers. It fires with the new value every time Value is set while Auto is on, **before** the comparison rows run — so it is the "something happened" event, and the rows are the "what exactly happened" events.

{% hint style="info" %}
Rows are not exclusive. Every active row is evaluated on every comparison, so a value of 5 tested against rows for `Greater 0`, `Greater 3` and `Equal 5` fires all three Responses. If you want only one branch to run, use `Index_Enable_Only()` on the Float Comparer, or author operators that cannot overlap.
{% endhint %}

### Float Comparer

Rows are Advanced Float Events. On top of the shared parameters it adds:

* **Index Enable Only / Index Disable Only** — turn one row on and every other row off, or the reverse, in a single call. Handy for state-machine-style wiring.
* **Set Random Value 01** — sets the Value to a random number between 0 and 1 and runs the comparison. Useful for chance-based branches straight from a Unity Event.
* **Pin Comparer / Pin Comparer Set Value** — see the Int Comparer below; the Float Comparer has the same pair.

### Int Comparer

**New in AC v1.5.3.** It is the integer twin of the Float Comparer: same base class, same custom inspector, same column layout, and its comparison rows are **Advanced Integer Events** — the integer version of the Advanced Float Event rows, carrying Active, Name, Description, Compare, Value, Update After Compare and a typed Response.

It also carries the **pinning** pair. Pinning here means selecting one comparison row and then writing to that row's Value:

1. **`Pin_Comparer(int index)`** — remembers the row at that index.
2. **`Pin_Comparer_SetValue(value)`** — overwrites the pinned row's compare Value.

It exists because a Unity Event can only pass one argument, so "set row 2's threshold to 10" has to be split into two calls wired one after the other on the same event. `Pin_Comparer_SetValue` is overloaded for **int**, **float**, **Int Var** and **IDs**, which is what makes it selectable from the Unity Event dropdown.

\[Insert Image - a Unity Event with Pin\_Comparer(1) followed by Pin\_Comparer\_SetValue(10)]

Extra helpers: **Value Add / Value Substract / Value Multiply / Value Divide** for arithmetic straight from a Unity Event, and **Add With Bool**, which adds 1 when passed `true` and subtracts 1 when passed `false` — a one-call counter for "things currently inside my trigger".

{% hint style="info" %}
Pinning is not exclusive to the Int Comparer — the Float and String Comparers already had the same `Pin_Comparer` pair. What is new in v1.5.3 is the Int Comparer component itself, which brings the pattern to integers.
{% endhint %}

{% hint style="info" %}
The Int and Float Comparers raise their current value from their own `OnEnable`, independently of the **On Enable** toggle. Treat that toggle as controlling the plain Listeners; on these two comparers, expect an event on every enable.
{% endhint %}

### Object Comparer

The odd one out. It is a plain component, not a Var Listener, so it has no ID, no Description and no Debug — just a default inspector with three things:

* **Auto** — compare automatically when the value is set, and on enable.
* **Value** — the Unity Object being tested.
* **Compare** — a list of rows, each with a **Compare To** object and two Unity Events, **Then** and **Else**.

Every row does a straight reference equality test and calls **Then** when the objects are the same, **Else** when they are not. Each row's label is generated for you and reads like `[0] Is Object equal to [Sword] ?`, or `[0] Is Object [Null] ?` when Compare To is empty — which is how you test for null.

{% hint style="info" %}
Both branches always run: unlike the number comparers, an Object Comparer row fires **Then** or **Else** on every single comparison. Leave **Else** empty if you only care about the match.
{% endhint %}

### String Comparer

Uses the shared inspector, with String rows. Two things are specific to it:

* Each row adds **On True** and **On False** — plain argument-less Unity Events, drawn under the Response of the selected row.
* **Set Value** and **Compare** accept a Unity Object as well as a string; when you pass an object, its **name** is used as the string. That is the quick way to branch on "which prefab did I just pick up".

{% hint style="info" %}
On a String Comparer the **Response** event fires on every comparison, whatever the result — it is a "here is the value I just tested" event. Only **On True** and **On False** tell you the outcome. This is different from the Float and Int Comparers, where Response fires only when the comparison passes.
{% endhint %}

### Transform Comparer

A Var Listener with its own inspector, so it does not draw the ID, Auto or the comparison list. Instead it tests one Transform against a single condition and calls one of two events.

#### Value

The Transform being tested. The **E** button next to it is the On Enable toggle, and the bug icon is Debug.

#### Condition

What to test:

| Option        | Behavior                                                                               |
| ------------- | -------------------------------------------------------------------------------------- |
| **Null**      | True when Value is empty. Compare To is hidden.                                        |
| **Equal**     | True when Value is the same Transform as Compare To.                                   |
| **Child Of**  | True when Value is a child of Compare To, at any depth.                                |
| **Parent Of** | True when Compare To is a child of Value, at any depth.                                |
| **Name**      | True when the Value's name **contains** the Transform Name text. Compare To is hidden. |

#### Compare To

The other Transform. Hidden when the Condition is Null or Name.

#### Transform Name

The text to look for. Only shown when the Condition is Name.

#### Then / Else

Invoked when the condition passes and when it fails.

The component also exposes **Set Value** and **Set Compare To** overloads that accept a Component, a GameObject or any Unity Object and resolve the Transform for you, plus **Clear Value** and **Clear Compare To**.

{% hint style="info" %}
The **Name** condition is a substring test, not an equality test. A Transform called `Sword_Rusty` matches the name `Sword`. Use **Equal** when you need an exact object.
{% endhint %}

{% hint style="info" %}
The Transform Comparer re-tests whenever **either** side changes: it subscribes to the Scriptable Variable behind Value and to the one behind Compare To, if those fields point at assets rather than holding inline values.
{% endhint %}
