> 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/global-components/conditions.md).

# Conditions

Last updated AC v1.5.3

## Overview

Conditions are small checks that answer one question with **true** or **false**. "Is the animal grounded?", "Is the Sword equipped?", "Is the Health Stat below 20%?", "Is this GameObject on the Animal layer?".

They are grouped in a **Conditions list** (`Conditions2`). The list is evaluated against a **Target** (a GameObject or Component) and returns a single **true** or **false**. That result is then used by the component that owns the list to allow or block an action: activate a Zone, enter a State, fire a Reaction, play a Super Item Action, and so on.

Every Condition has the same header controls: an **Active** toggle, an **Invert** toggle, an **AND/OR** connector, a **Local/Dynamic Target** switch, a **Description** field, a **Debug** toggle and a **Delete** button. The body of each Condition holds its own fields.

`[Insert Image - A Conditions list in the Inspector with three conditions, one of them disabled]`

## Where Conditions are used

The same Conditions list appears in many places of the asset. The **Dynamic Target** of the list depends on who owns it:

| Owner                                                  | Field(s)                                                                                                      | Dynamic Target                                       |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| Reactions (`Reaction2`)                                | Per-reaction **Use Condition** gate                                                                           | The object the Reaction reacts on                    |
| Zones                                                  | Activation Conditions                                                                                         | The Animal entering the Zone                         |
| States                                                 | Enter Conditions, Exit Conditions                                                                             | The `MAnimal` component                              |
| Modes                                                  | Enter, Interrupt and Exit Conditions. Each Ability also has its own Ability Condition and Interrupt Condition | The `MAnimal` component                              |
| Mode Modifier: Mode Index by Condition                 | One list per index                                                                                            | The `MAnimal` component                              |
| Combo Manager                                          | Combo Conditions                                                                                              | The `MAnimal` component                              |
| AI Brain                                               | Decision **General/Malbers Conditions2** (Check On: Self or Target)                                           | The AI Animal, or its Target                         |
| Super Item: Item Action                                | Conditions On Owner, Conditions On Target                                                                     | The character holding the Item, or the Item's Target |
| Super Item: Action Set                                 | Auto Activation On, Auto Activation Off, Set Conditions                                                       | The character holding the Item                       |
| Super Item Manager                                     | Action Conditions                                                                                             | The character                                        |
| Weapons (Weapon Manager, MWeapon)                      | Pre Attack Conditions, Pre Aim Conditions                                                                     | The character / the Weapon                           |
| Damageable                                             | Can Receive Damage                                                                                            | The Damageable                                       |
| IK                                                     | IK Processor **Check If**; Weight Processor **Check Conditions2**                                             | The Animator                                         |
| Pick Up / Pickable                                     | Pick Up Condition, Drop Condition, Can Be Picked If                                                           | The picker / the item                                |
| Rider                                                  | Mount Conditions, Dismount Conditions                                                                         | The Rider                                            |
| Triggers (Trigger Enter, Trigger Proxy) and Aim Target | Conditions / Check If                                                                                         | The Collider entering the trigger / the Aim target   |
| Conditions2 and Conditions Multiple components         | Conditions                                                                                                    | The **Target** set on the component                  |

## How it Works

### Evaluation order

The list is evaluated from top to bottom. There is no operator precedence: each Condition is combined with the **accumulated result** of everything above it, using its own **AND/OR** connector.

1. The first Condition seeds the result. Its connector is ignored.
2. Every next Condition is combined with the result so far: `result AND next` or `result OR next`.
3. The final value is returned to the owner.

So `A OR B AND C` is read as `((A OR B) AND C)`, not as `A OR (B AND C)`. Order the rows to get the logic you need.

### Invert

**Invert** flips the result of one Condition before it is combined with the rest. An inverted row shows `[NOT]` in front of its name. Use it for "is NOT grounded", "is NOT playing a Mode", "is outside the angle range".

### Active (new in 1.5.3)

Each Condition has an **Active** checkbox at the left of its header. A disabled Condition is **skipped**: it does not seed the result and its AND/OR connector is not applied either. The row is greyed out and shows `(Disabled)` after its name. Use it to mute one Condition while testing, instead of deleting it and building it again.

{% hint style="info" %}
A disabled Condition is skipped, not evaluated as **false**. If every Condition in the list is disabled the list behaves like an empty list and returns **true**.
{% endhint %}

The whole list also has its own **Active** checkbox, on the right side of the list header. When the list is turned off its label shows `(Disabled)` and the list is greyed out.

{% hint style="info" %}
An **empty** list, or a list whose own Active checkbox is off, always evaluates to **true**. Conditions can only block; a list with nothing to check never blocks anything.
{% endhint %}

### Dynamic and Local Target

Most Conditions read a component on a Target (`MAnimal`, `Stats`, `Animator`, `Collider`, `SuperItem`...).

* **Dynamic Target** (default, globe icon): the Target is handed to the list at runtime by its owner (see the table above). The Condition finds the component it needs on that object: first on the object itself, then on its parents, then on its children. The reference is cached and only resolved again when the Target changes or the cached component was lost.
* **Local Target** (local icon, blue): the Target is set by hand on the Condition and never changes. The header row shows the object field next to the name. Use it when the Condition must look at a fixed object, for example the Player while the list runs on an AI.

Conditions that compare plain values (Values/Boolean, Values/Float, Try Chance, Payload...) have no Target and ignore this switch.

### Payload values

A list can also be evaluated with a raw value instead of a Target: an `int`, `float`, `bool` or `string` coming from a UnityEvent. The **Values/Payload** Conditions compare that value. The **Conditions2** component exposes `Evaluate(int)`, `Evaluate(float)`, `Evaluate(bool)` and `Evaluate(string)` for this. Target-based and Payload Conditions can live in the same list: the Target is still passed along.

### Debug

Each Condition has a **Debug** toggle. When on, every evaluation prints one line to the Console with the Condition name, the result (cyan = true, orange = false) and the object it was evaluated on. Conditions that draw Gizmos (Check Angle, Aim Angle, Angle from Origin) only draw them while Debug is on and the Condition is Active.

### Errors

A **null** row (a row where no type was picked, or a row cleared with the trash button) logs an error every time the list is evaluated and is skipped. A Condition that throws an exception logs the exception and is skipped too.

## The Condition row

`[Insert Image - Close up of one Condition header row with every control labelled]`

Controls are listed in the order they appear, from left to right.

#### Active

Checkbox at the far left. Turns the Condition on or off without removing it. Off = skipped, row greyed out, `(Disabled)` added to the name.

#### Name (foldout)

Shows the **Dynamic Name** of the Condition: a summary built from its current values, e.g. `Animal [Grounded]`, `Stats [Health] [Value < 20]`, `[NOT] Distance from [Dynamic] to [Player] < [5]`. Click the arrow to expand the body and edit the fields. When a **Description** was typed, it replaces the Dynamic Name.

#### Type dropdown (empty row only)

A new row shows a red `[Null]` dropdown instead of a name. Click it to open the type menu and pick a Condition. The menu is grouped by category (General, Animal, Unity, Values, Super Item, Weapon Manager...).

`[Insert Image - The type menu opened from an empty Condition row]`

#### Local Target field

Only visible when **Local Target** is on and the Condition has an Object Target. Drag the object here. The field is greyed out while the Condition is disabled.

#### AND / OR

Connector between this Condition and the result of the rows above it. Green **AND**, blue **OR**. The first row has no connector.

#### Invert

Toggle with an error-style icon. Red when on. The result of this Condition is flipped and the name is prefixed with `[NOT]`.

#### Dynamic / Local Target

Globe icon = Dynamic Target (found at runtime). Local icon (blue) = Local Target (set in the Inspector). Only shown on Conditions that have a Target.

#### Edit Description

Pencil icon. Turns the name into a text field where you can type a custom description for the row. The description is stored on the Condition and replaces the Dynamic Name in the header. Conditions with a fixed description (`Unity/Animator Parameter`) start with one already filled in.

#### Debug

Bug icon. Logs the result of this Condition every time it is evaluated and enables its Gizmos.

#### Delete

Trash icon. Clears the Condition type from the row. The row stays in the list as an empty `[Null]` slot: pick a new type for it or remove the row with the list's **-** button.

{% hint style="info" %}
An empty `[Null]` row left in a list logs `[Null] Condition [i] not Allowed` on every evaluation. Always remove the row or assign a type.
{% endhint %}

## Condition Reference

`Compare` in the tables below means the number comparer: Equal, Greater, Less, Not Equal, Greater Equal, Less Equal. Fields written as `Reference` (Float Reference, Int Reference...) accept a constant or a Scriptable Variable.

### General

| Condition                           | Checks                                                                                                                                                                                                                                                                                                                   | Main fields                                                                                                            |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| Aim Angle                           | The Horizontal or Vertical angle of the `Aim` component on the Target is inside a range. The range can be rotated with **Angle Offset** (new in 1.5.3). Invert to check "outside the range". Draws an arc Gizmo.                                                                                                         | Target (`Aim`), Axis (Horizontal / Vertical), Limit (min–max, -180..180), Angle Offset (Float Reference), Gizmo Radius |
| Check Angle                         | The angle between a direction on Target and a direction on Target 2 compared to a value. Optional signed angle around an axis.                                                                                                                                                                                           | Target, Direction, Target 2, Direction 2, Compare, Angle, Use Signed Angle, Axis, Axis Target                          |
| Check Angle from Origin             | The signed angle from an Origin's direction to the Target position is between two angles.                                                                                                                                                                                                                                | Target, Origin, Direction, Up Axis, From Angle, To Angle                                                               |
| Check Distance                      | The distance between Target and Target 2 compared to a value.                                                                                                                                                                                                                                                            | Target, Target 2, Condition (Compare), Distance                                                                        |
| Input Source                        | An input of the `IInputSource` on the Target (e.g. Malbers Input) is currently pressed/held.                                                                                                                                                                                                                             | Input Name                                                                                                             |
| Local MVariable                     | A variable on the `MLocalVars` component of the Target matches a value.                                                                                                                                                                                                                                                  | Target (`MLocalVars`), Var Name, Type, then the value field for that type (Int/Float use Compare)                      |
| Malbers Tag (new in 1.5.3)          | The Target holds Malbers Tags. **Has Any Tag**: at least one tag on the Target itself. **Has Any Tag In Parent**: the closest Tags component up the hierarchy holds at least one. **Has All Tags**: every tag on the Target itself. **Has Tag In Children**: every tag is found on the Target or one of its descendants. | Target, Condition, Tags                                                                                                |
| Member Compare (get) (new in 1.5.3) | Reads a field, property or method of a component on the Target by reflection and compares it. Numbers use the number comparer, bools use True/False. Methods with one string/bool/int/float argument are supported.                                                                                                      | Target, Target Type, Member, Argument (methods only), Comparer, Value                                                  |
| Stats                               | A Stat on the `Stats` component of the Target. **Has Stat**, **Enabled**, **Full**, **Empty**, **Regenerating**, **Degenerating**, **Inmune**, or compare **Value**, **Value Normalized** (0–1), **Max Value**, **Min Value**.                                                                                           | Target (`Stats`), Condition, Stat (Stat ID), Compare, Value                                                            |
| Try Chance (0:1)                    | Random roll. True when a random number between 0 and 1 is lower or equal to Weight.                                                                                                                                                                                                                                      | Weight (0–1)                                                                                                           |

### Interactor and Pick Drop

| Condition                  | Checks                                                                              | Main fields                             |
| -------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------- |
| Interactor/Item Focused    | The `MInteractor` on the Target is focusing an Interactable. -1 = any Interactable. | Target (`MInteractor`), Interactable ID |
| PickDrop/Pickeable Focused | The `MPickUp` on the Target is focusing a Pickable. -1 = any.                       | Target (`MPickUp`), ID                  |
| PickDrop/Has Item Picked   | The `MPickUp` on the Target is holding a Pickable with this ID.                     | Target (`MPickUp`), ID                  |

### Riding

| Condition                      | Checks                                                                                                                                                                                                       | Main fields                         |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- |
| Rider is Riding (new in 1.5.3) | The `IRider` (e.g. `MRider`) found on the Target, its parents or children. **Is Riding**, **Is Mounting**, **Is Dismounting**, **Animal In Mount Trigger** (a mountable Animal is inside the mount trigger). | Target (any Rider component), State |

### Animal

All Animal Conditions look for the `MAnimal` component on the Target.

| Condition            | Checks                                                                                                                                                                                                                                                                                                                         | Main fields                                                              |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| Animal AI            | The `MAnimalAIControl` on the Target: **Enabled**, **Has Target**, **Has Next Target**, **Arrived**, **Waiting**, **In Off Mesh** (link), **Current Target** equals Value, **Next Target** equals Value.                                                                                                                       | Target (`MAnimalAIControl`), Condition, Value (Transform)                |
| General              | Boolean flags of the Animal: Grounded, Root Motion, Free Movement, Always Forward, Sleep, Additive Position, Additive Rotation, In Zone, In Ground Changer, Strafing, Can Strafe, Movement Detected, In Timeline.                                                                                                              | Condition                                                                |
| In Zone              | The Animal is inside a Zone with this Zone ID.                                                                                                                                                                                                                                                                                 | Zone ID                                                                  |
| Modes                | **Playing Any Mode**, **Playing Mode** (one of the Modes list; empty list = the single Value; both empty = any Mode), **Playing Ability** (by name; empty = any), **Playing Ability By Index**, **Has Mode**, **Has Ability** (name), **Has Ability Index**, **Enabled**, **Active Ability Index**, **Default Ability Index**. | Condition, Value (Mode ID), Modes (ID list), Ability Name, Ability Index |
| States               | **Active State**, **Enabled**, **Has State**, **Last State**, **Sleep From Mode**, **Sleep From State**, **Sleep From Stance**, **Pending**, **Is Persistent** for the State with this ID.                                                                                                                                     | Condition, Value (State ID)                                              |
| Stances              | **Current Stance**, **Default Stance**, **Last Stance**, **Has Stance** for this Stance ID.                                                                                                                                                                                                                                    | Condition, Value (Stance ID)                                             |
| Speeds               | **Vertical Speed** (compare), **Current Speed Set** (name), **Current Speed Modifier** (name), **Active Index** (value), **Is Sprinting**, **Can Sprint**.                                                                                                                                                                     | Condition, Compare, Value, Speed Name                                    |
| Strafe               | **Strafing** or **Can Strafe** (Animal, active Stance and active State all allow it).                                                                                                                                                                                                                                          | Condition                                                                |
| Move Direction Angle | The signed angle between the Animal Forward and its Move Direction is between Min and Max. Abs compares the absolute angle.                                                                                                                                                                                                    | Min Angle, Max Angle, Abs                                                |

### Unity

| Condition                       | Checks                                                                                                                                                                                                 | Main fields                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| Animator Parameter              | A Float, Int or Bool parameter of the `Animator` on the Target compared to a value.                                                                                                                    | Target (`Animator`), Parameter, Parameter Type, Compare, Value / Is True |
| Behavior                        | A `Behaviour` component on the Target is **Enabled** or **Active And Enabled**.                                                                                                                        | Target (`Behaviour`), Condition                                          |
| Collider                        | The `Collider` on the Target: **Enabled**, **Equal** to Value, **Is Trigger**, **Physic Material** equals Material, **Is Box**, **Is Capsule**, **Is Sphere**, **Is Mesh Collider**.                   | Target (`Collider`), Condition, Value, Material                          |
| GameObject                      | The Target GameObject: **Active In Hierarchy**, **Active Self**, **Null**, **Equal** to Value, **Is Prefab**, **Is Name** (name contains), **Layer** (in mask), **Is Static**, **Is Tag** (Unity tag). | Target, Condition, Value, Name/Tag (string), Layer                       |
| GameObject has Component        | The Target has a component with this type name.                                                                                                                                                        | Target, Component (string)                                               |
| Layers                          | The Target (GameObject or Component) is on a layer inside the mask.                                                                                                                                    | Target, Layer                                                            |
| Transform                       | The Target Transform: **Null**, **Equal** to Value, **Child** of Value, **Parent** of Value, **Grand Child**, **Grand Parent**, **Same Hierarchy** as Value, **Name** contains text.                   | Target, Condition, Value (Transform), Check Name                         |
| Transform Values (new in 1.5.3) | The **Position**, **Rotation** or **Scale** of the Target equals another Transform (Other Transform on) or a Vector3 value (Other Transform off). Rotation against a Vector3 compares Euler angles.    | Target, Condition, Other Transform, Value (Transform), Value (Vector3)   |

### Values and Scriptables

These Conditions compare values. Most of them have no Target.

| Condition              | Checks                                                                                                                | Main fields                                               |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| Boolean                | Value 1 equals Value 2.                                                                                               | Value 1, Value 2 (Bool Reference)                         |
| Integer                | Value 1 compared to Value 2.                                                                                          | Value 1, Condition (Compare), Value 2 (Int Reference)     |
| Float                  | Value 1 compared to Value 2.                                                                                          | Value 1, Condition (Compare), Value 2 (Float Reference)   |
| String                 | Value 1 **Equal** / **Contains** / **Contains Lower** (case-insensitive) Value 2.                                     | Value 1, Condition, Value 2 (String Reference)            |
| Vector3                | Value 1 equals Value 2, or (Use Transform) the Target position equals Value 2.                                        | Use Transform, Target, Value 1, Value 2                   |
| Vector2                | Value 1 equals Value 2.                                                                                               | Value 1, Value 2                                          |
| Bool Listener          | The `BoolVarListener` on the Target has this value. ID filters which listener when there are several (-1 = any).      | Target, ID, Value 1                                       |
| Int Listener           | The `IntVarListener` value compared to Value 1.                                                                       | Target, ID, Condition, Value 1                            |
| Float Listener         | The `FloatVarListener` value compared to Value 1.                                                                     | Target, ID, Condition, Value 1                            |
| String Listener        | The `StringVarListener` value equals Value 1.                                                                         | Target, ID, Value 1                                       |
| Payload Int            | The value sent with `Evaluate(int)` compared to Value. Floats are rounded, bools become 0/1, IDs use their ID number. | Condition (Compare), Value                                |
| Payload Float          | The value sent with `Evaluate(float)` compared to Value.                                                              | Condition (Compare), Value                                |
| Payload Bool           | The value sent with `Evaluate(bool)` equals Value. Numbers: 0 = false. Objects: null = false.                         | Value                                                     |
| Payload String         | The value sent with `Evaluate(string)`: **Equal**, **Contains**, **Contains Lower**, **Empty**.                       | Condition, Value                                          |
| Runtime GameObject Set | A Runtime GameObjects asset is **Empty**, has this **Size**, or **Has Item**.                                         | Target (Runtime GameObjects asset), Condition, Size, Item |

{% hint style="info" %}
Payload Conditions receive no value when the list is evaluated with a plain `Evaluate()` or `Evaluate(Object)`. They return **false** and, with Debug on, log that no value was received.
{% endhint %}

### Super Item

`[Super Item]` Conditions look for the `SuperItem` component on the Target (the Item). `[Manager]` Conditions look for the `SuperItemManager` on the Target (the character). `Has Any` = at least one of the listed IDs matches. `Has All` = every listed ID matches.

| Condition                                   | Checks                                                                                                                                                                                               | Main fields                                                  |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| Pouch/Has Ammo                              | The `PouchManager` on the Target has ammo for a Projectile, compared to an amount.                                                                                                                   | Target (`PouchManager`), ID (Projectile ID), Compare, Amount |
| \[Super Item] Has Target                    | The Item has a Target.                                                                                                                                                                               | —                                                            |
| \[Super Item] Has User                      | The Item has a User (a character holding it).                                                                                                                                                        | —                                                            |
| \[Super Item] Has Tag                       | The Item's own Tags component holds the Malbers Tags.                                                                                                                                                | Tags, Check If (Has Any / Has All)                           |
| \[Super Item] Is On Side                    | The Item is equipped on this hand (Left / Right), taken from its Equip Point.                                                                                                                        | Side                                                         |
| \[Super Item] Is Action Playing             | An Action of the Item's Active Set is playing. Empty Action = any.                                                                                                                                   | Action (Item Action ID)                                      |
| \[Super Item] Is Set Active                 | The Item's Active Action Set has this name. Empty = any Set active.                                                                                                                                  | Set Name                                                     |
| \[Super Item] Is Equipped                   | The Item is equipped on an Equip Point.                                                                                                                                                              | —                                                            |
| \[Super Item] Is Holstered                  | The Item is stored in a Holster of its User.                                                                                                                                                         | —                                                            |
| \[Super Item] Is Dual Wielding              | This Item is held while another Item is held on the opposite hand. The list filters the other Item's type (empty = any).                                                                             | Other Hand (Super Item ID list)                              |
| \[Manager] Has Item Equipped                | One / all of the listed Items are equipped.                                                                                                                                                          | Items (Super Item ID list), Check If                         |
| \[Manager] Has Item Equipped By Tag         | An equipped Item carries the Malbers Tags (Has All = every tag on the same Item).                                                                                                                    | Tags, Check If                                               |
| \[Manager] Has Super Item in Holster        | One / all of the listed Items are holstered. Empty list = any holster holds any Item.                                                                                                                | Items, Check If                                              |
| \[Manager] Owns Super Item                  | One / all of the listed Items are equipped **or** holstered.                                                                                                                                         | Items, Check If                                              |
| \[Manager] Holster Occupied                 | The Holster with this ID holds an Item.                                                                                                                                                              | Holster (Holster ID)                                         |
| \[Manager] Item Equipped or Holstered       | The number of Equipped, Holstered or Total Items compared to a value.                                                                                                                                | Count Type, Compare, Value                                   |
| \[Manager] Has Free Slot                    | There is a free Equip Point or a free Holster.                                                                                                                                                       | Slot Type                                                    |
| \[Manager] Is Aiming                        | The character's `Aim` component is active.                                                                                                                                                           | —                                                            |
| \[Manager] Is Locked                        | The Manager is Locked (Items put away, every Item operation refused).                                                                                                                                | —                                                            |
| \[Manager] Item In Use \[Any Action]        | Any equipped Item has an Action playing.                                                                                                                                                             | —                                                            |
| \[Manager] Action Is Playing (new in 1.5.3) | An equipped Item is playing an Action. Empty Item = any equipped Item. Empty Action = any Action. A holstered Item never plays Actions.                                                              | Item (Super Item ID), Action (Item Action ID)                |
| \[Manager] Active Action Set Is             | Any equipped Item has an active Action Set with this name.                                                                                                                                           | Set Name                                                     |
| \[Manager] Is Dual Wielding                 | Both hands hold an Item. With lists: one held Item matches First Hand and a different one matches Second Hand. Put the same ID in both lists to require two of it. Both lists empty = any two Items. | First Hand, Second Hand (Super Item ID lists)                |

### Weapon Manager and Weapon (Legacy)

| Condition                                                | Checks                                                                             | Main fields        |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------ |
| Weapon/Is Equipped                                       | The `MWeapon` on the Target is equipped.                                           | Target (`MWeapon`) |
| Weapon Manager/Has Weapon Equipped                       | The `MWeaponManager` on the Target holds a Weapon whose type is in the list.       | Weapon ID (list)   |
| Weapon Manager/Current Weapon Aiming                     | The Weapon Manager is aiming.                                                      | —                  |
| Weapon Manager/Current Weapon Action                     | The Weapon Manager's current Weapon Action equals this one (Attack, Aim, Idle...). | Current Action     |
| Weapon Manager/Has Weapon Equipped \[Tag] (new in 1.5.3) | The equipped Weapon carries any of the Malbers Tags.                               | Tags               |

## Components

Two ready-made components evaluate a Conditions list and fire a response. Both are found under **Add Component → Malbers → Interactions**.

### Conditions2 (`MConditions2`)

Evaluates one list and invokes a **Then** or **Else** response.

`[Insert Image - The Conditions2 component with the Response section showing the Reactions and Events tabs]`

#### Target

GameObject the Conditions are evaluated on (the Dynamic Target of the list). It is also the target of the Then/Else Reactions. When empty, the Reactions react on the component's own GameObject.

#### Enable / Disable / Repeat

* **Enable**: evaluate when the component is enabled.
* **Disable**: evaluate when the component is disabled.
* **Repeat**: evaluate every **Repeat Time** seconds while enabled. When Enable is also on, the first repeat waits one Repeat Time so the list is not evaluated twice on the same frame.

#### Conditions

The Conditions list.

#### Response (Then-Else)

* **Reactions** tab: **Then** and **Else** Reactions. They react on the Target (or this GameObject when the Target is empty).
* **Events** tab: **Then** and **Else** UnityEvents.

Then is invoked when the list is **true**. Else is invoked when it is **false**. Both the Reactions and the Events of that branch run.

#### Debug

Logs the final result of every evaluation. Also warns when the list's own Active checkbox is off, because the result then defaults to **true**.

In Play Mode the Inspector shows an **Evaluate All** button.

#### Public methods

Callable from UnityEvents or code:

* `Evaluate()` – evaluate using the Target.
* `Evaluate(Object)` – evaluate using another GameObject or Component as Target.
* `Evaluate(int)`, `Evaluate(float)`, `Evaluate(bool)`, `Evaluate(string)` – evaluate with a Payload value (Values/Payload Conditions). The Target is still passed to target-based Conditions in the same list.
* `TryEvaluate(Object)` – same as Evaluate but returns the `bool` result.
* `InvokeThen()`, `InvokeElse()` – fire a branch directly.
* `Target_Set(GameObject)`, `Target_Set(Component)`, `Target_Clear()` – change the Target at runtime.
* `Pause_Editor()` – pauses the Editor (`Debug.Break`).

### Conditions Multiple (`MConditionsMultiple`)

A **sequence** of Conditions lists, each with its own Then/Else events. Only the **current** list is evaluated. When it is true the sequence moves to the next one. Use it for step-by-step tutorials, puzzles or quest stages.

#### Target

GameObject every list is evaluated on.

#### Enable / Disable / Repeat

Same as Conditions2, but they evaluate the **current** list only.

#### Conditions with Responses

Each entry has a **Conditions** list and a **Response (Then-Else)** foldout with **Then** and **Else** UnityEvents. Use **Add New Condition** and **Remove** to manage the entries.

How the sequence runs:

1. On enable the current index is reset to the first entry and every entry is marked not completed.
2. Evaluating the current entry: **true** invokes Then, marks it completed and moves to the next entry. **False** invokes Else and stays on the same entry.
3. After the last entry the sequence loops back to the first and resets every entry.

In Play Mode the Inspector shows **Evaluate Current**, **Evaluate All**, **Restart Sequence**, the current index, the last result and status of each entry and a **Test Condition** button per entry.

#### Public methods

* `EvaluateCurrentCondition()` – evaluate the current entry.
* `EvaluateAll()` – evaluate every entry in order.
* `EvaluateConditionAtIndex(int)` – evaluate one entry.
* `MoveToNextCondition()`, `RestartSequence()`, `ResetAllConditions()`.
* `Evaluate_OnTrue(bool)`, `Evaluate_OnFalse(bool)` – evaluate the current entry only when the bool matches. `Evaluate_OnInt(int)` – evaluate when the int is greater than 0. Handy for wiring Var Listeners.
* `Pause_Editor()`.

## API

### Evaluating a list

`Conditions2` is a serializable struct. Declare a public field and it draws the full list in the Inspector.

```csharp
using MalbersAnimations.Conditions;
using UnityEngine;

public class OpenDoor : MonoBehaviour
{
    [Tooltip("Extra conditions to open the door. Dynamic Target: the Animal entering")]
    public Conditions2 canOpen;

    public void TryOpen(GameObject who)
    {
        // Dynamic Target: every Condition resolves its component on [who]
        if (canOpen.Evaluate(who))
            Debug.Log("Door opened");
    }

    public void OnHealthChanged(float health)
    {
        // Payload: Values/Payload Float Conditions compare [health].
        // Target-based Conditions in the same list receive [gameObject] as Target.
        if (canOpen.EvaluateValue(gameObject, health))
            Debug.Log("Health condition met");
    }

    private void OnDrawGizmos() => canOpen.Gizmos(this); // draws the Gizmos of Conditions with Debug on
}
```

Useful members of `Conditions2`:

* `conditions` – the `ConditionCore[]` array. `active` – the list's own on/off switch.
* `Count`, `Valid` (active and not empty).
* `Evaluate(Object target)` – evaluate against a Target. Returns **true** when the list is not Valid.
* `EvaluateValue(object value)` and `EvaluateValue(Object target, object value)` – evaluate with a Payload value.
* `Add(ConditionCore)`, `Add(Conditions2)`, `Remove(int)`, `RemoveFirst()`, `RemoveLast()`, `Remove(string description)` – edit the list at runtime.
* `Gizmos(Component)` – call it from `OnDrawGizmos` to see the Gizmos of your Conditions.
* `Conditions2.FindConditions2ByName(MonoBehaviour, string fieldName, out Conditions2)` – finds a list by field name by reflection (searches nested serializable classes). The struct is returned by copy.

A single Condition can also be evaluated on its own: `condition.Evaluate(target)`, `condition.Evaluate(value)` or `condition.Evaluate()` (uses the cached Target). Invert and Debug are applied in all three.

### Creating a custom Condition

Subclass `ConditionCore`. Mark the class `[System.Serializable]` and add `[AddTypeMenu("Category/Name")]` so it shows in the type menu. The script must live in a runtime assembly that references `MalbersAnimations`.

```csharp
using MalbersAnimations;
using MalbersAnimations.Conditions;
using MalbersAnimations.Scriptables;
using UnityEngine;

[System.Serializable, AddTypeMenu("Custom/Rigidbody Speed")]
public class C2_RigidbodySpeed : ConditionCore
{
    // Text shown on the Condition row
    public override string DynamicName => $"Rigidbody Speed {MTools.CompareToString(Compare)} {Speed.Value}";

    // [Hide(nameof(LocalTarget))] keeps the field out of the body when the Target is Dynamic
    [Tooltip("Rigidbody to read. Found on the Dynamic Target automatically")]
    [Hide(nameof(LocalTarget))] public Rigidbody Target;

    public ComparerNumber Compare = ComparerNumber.Greater;
    public FloatReference Speed = new(1f);

    // Resolve the component from the Dynamic Target (self, parents, then children)
    protected override void _SetTarget(Object target) => VerifyComponent(target, ref Target);

    // Lets the base class re-resolve the Target when the cached one was lost
    public override bool HasTarget => Target != null;

    // The check itself. Invert and Debug are handled by the base class
    protected override bool _Evaluate()
    {
        if (Target == null) return false;

        var result = Target.linearVelocity.magnitude.MCompare(Speed.Value, Compare);
        Debugging($"Speed: {Target.linearVelocity.magnitude:F2}", result, Target);
        return result;
    }
}
```

Members you can override:

* `DynamicName` – the header text.
* `_SetTarget(Object)` – required. Convert the incoming Target to what the Condition needs. Leave it empty for Conditions without Target.
* `HasTarget` – return whether your typed Target is resolved.
* `_Evaluate()` – required. Return the raw result; do not apply Invert yourself.
* `_SetValue(object)` – receive a Payload value (see `C2_PayloadInt` for an example).
* `TargetHasChanged()` – refresh cached data after a new Target was set.
* `OnEnable()` / `OnDisable()` – called by the Conditions2 and Conditions Multiple components.
* `DrawGizmos(Component)` / `DrawGizmosSelected(Component)` – Scene view helpers, drawn while Debug is on and the owner calls `Conditions2.Gizmos()`.

Add `[MDescription("text")]` on the class to give new rows a default description instead of the Dynamic Name.

{% hint style="info" %}
Keep runtime caches in `[System.NonSerialized]` private fields. A public field on a `[Serializable]` class is written back by the Inspector and by `Clone()`, which can silently reset a value you computed at runtime.
{% endhint %}
