Conditionals

v1.0

Conditionals let you decide when an Action will execute — based on blackboard values, GameObject state, components, or even custom interface methods. You can build complex logic chains directly in the custom window without writing additional scripts.


🎯 Overview

Each Conditional defines a rule that can evaluate to true or false during runtime. When you attach one or more conditionals to an Action, the system evaluates them before the Action executes.

You can combine multiple conditionals using AND and OR logic to create precise control flows.

Examples:

  • Run only if the target GameObject is active.

  • Run if the Rigidbody’s drag equals 0.

  • Run if a Blackboard key HasKey is true.

  • Run if a component implementing IHealable returns NeedsHealing() = true.


🧩 Adding Conditionals in the Custom Window

1

Select an Action

Select any Action that supports conditionals.

2

Open Conditionals Tab

Switch to the Conditionals tab.

3

Add a Conditional

Click Add Conditional.

4

Choose Type

Choose a Type (e.g. Blackboard Value, Component Property, etc.).

5

Configure Fields

Configure the fields as described below.

6

Combine Conditionals

Add more conditionals as needed, using And / Or logic to link them.


⚙️ Conditional Fields

Subject

Defines which object the conditional operates on. Generally this is set at edit time, but can be modified at runtime.

Field
Description

Source

Target (the Action’s target) or GameObject (explicit reference).

GameObject

Only shown if GameObject is selected.

If you often check external managers or controllers, use GameObject to explicitly reference them.

If you'd like to modify the subject at runtime, you can specify a GameObject or the Target as the source.

public MagicPigGames.JuicyActions.Action action;   // your action asset/instance
public GameObject newSubject;                      // the GO you want to target
public int conditionalIndex = 0;                   // which conditional to change

public void PointThatOneConditionalAtNewSubject()
{
    var cond = action.Conditionals[conditionalIndex];
    cond.SetSubject(newSubject);   // switches Subject Source to Explicit GameObject
}

public void ResetThatConditionalToTarget()
{
    var cond = action.Conditionals[conditionalIndex];
    cond.SetSubject(null);         // switches Subject Source back to Target
}
    
public void PointAllConditionalsAt(GameObject go)
{
    foreach (var cond in action.Conditionals)
        cond.SetSubject(go);           // all will use this explicit GameObject
}

public void ResetAllToTarget()
{
    foreach (var cond in action.Conditionals)
        cond.SetSubject(null);         // all will use the Action’s Target again
}

// Swap dynamically (e.g., when you acquire a new target)
public void OnNewLockOn(GameObject newLockOn)
{
    // Only flip the ones that actually need a Subject
    foreach (var cond in action.Conditionals)
    {
        // Optional: check cond.ValueType here if you only want to update certain types
        cond.SetSubject(newLockOn);
    }
}

🧠 Conditional Types

Blackboard Value

Checks a value from the Action’s Blackboard.

Field
Description

Blackboard Key

Key to read from the Blackboard.

Operator

Equals, NotEquals, GreaterThan, etc.

Expected

Value to compare against (type-sensitive).

Valid Operators:

  • Bool: Equals, NotEquals

  • Int/Float: Equals, NotEquals, GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual

  • String: Equals, NotEquals, Contains, NotContains


Component Property

Checks a field or property on a Component.

Field
Description

Component Reference / Script / Type Name

How the component is identified.

Member

Property or field to evaluate.

Operator

Comparison operator.

Expected

Value to compare against.


Component Exists

Checks whether a specific component exists on the Subject.

Field
Description

Component Reference / Type

Component type to search for.

Succeeds If

Exists or Does Not Exist.


Game Object Active

Checks whether the GameObject is active in the hierarchy.

Field
Description

Succeeds If Object

Is Active or Is Not Active.


Game Object Tag

Checks the GameObject’s Tag.

Field
Description

Operator

Equals, Not Equals

Tag

Tag to compare


Game Object Layer

Checks the GameObject’s Layer.

Field
Description

Operator

Equals, Not Equals

Layer

Layer to compare


Custom Predicate

Calls a custom bool-returning method from an interface you define. For more complex checks, use the Custom Value Check below.

Field
Description

Interface Type

The interface that defines the predicate method.

Method Name

Must be a parameterless bool method.

Example interface code:

IHealable example
public interface IHealable
{
    bool NeedsHealing();
}

public class Ally : MonoBehaviour, IHealable
{
    public int HP;
    public bool NeedsHealing() => HP < 25;
}

In the Conditional, set Interface Type to IHealable and Method Name to NeedsHealing.


Custom Value Check

Calls IConditionalValue.GetConditionalValue(string) on a component and compares the returned value. This is useful for custom systems and classes not defined by standard value types.

IConditionalValue example
public interface IConditionalValue
{
    bool EvaluateCondition();
    object GetConditionalValue(string valueName);
}

public class Stats : MonoBehaviour, IConditionalValue
{
    public int Health;
    public object GetConditionalValue(string name)
        => name == "Health" ? (object)Health : null;
}
Field
Description

Value Name

Name to pass into GetConditionalValue.

Operator

Comparison operator.

Expected

Value to compare.


🔗 Combining Conditionals

When multiple conditionals are present, use Conditional Join to control evaluation:

  • And → all must be true.

  • Or → any can be true.


🧪 Runtime Evaluation

All conditionals are evaluated before the Action executes:

Runtime evaluation
if (action.ConditionalsEvaluate(executor))
    action.Execute();

Individual conditionals can be tested manually:

Manual test
var condition = new Conditional();
condition.SetSubject(myGameObject);
condition.Evaluate(executor);

Tips

  • Use Blackboard Value for quick logic references between Actions, or to reference any data shared to the common ActionBlackboard object from any other class.

  • Component Property and Exists are great for in-scene checks.

  • Keep your predicates pure — no side effects inside your bool methods.

  • When comparing strings, use lowercase or match case-insensitively for best results.

  • Complex logic? Split it across multiple actions and gate them with separate conditional groups.

Last updated

Was this helpful?