Skip to main content
Flow Core Documentation
Menu

Extension

Authoring Custom Conditions

Add a supported typed pass/fail check for Guards and decision logic.

Audience
Unity developers
Time
25 minutes
Requires
C#, Flow Core runtime assembly access, and codegen access
Modules
Flow Core, C#
On this page

Create a custom Condition when a project-specific rule must return pass or fail inside a Guard or another supported decision surface. A Condition reports a decision; it should not perform gameplay side effects.

Define the Condition

This example checks whether a typed float exceeds an authored threshold:

using System;
using System.Threading.Tasks;
using TwoCatsCode.FlowCore;

[FlowCondition("Float Above Threshold", "Project", "Check a float value.")]
public sealed class ConditionFloatAboveThreshold : ICondition
{
    [Serializable]
    public sealed class Data : ConditionData
    {
        public FlowValueGetFloatData Value = new();
        public float Threshold = 0.5f;

        public override ConditionData Clone()
        {
            return new Data
            {
                Value = Value?.Clone() as FlowValueGetFloatData
                    ?? new FlowValueGetFloatData(),
                Threshold = Threshold
            };
        }

        public override string Summary(FlowContext context)
        {
            return $"{Value?.Summary(context)} > {Threshold}";
        }
    }

    private readonly Data data;

    public ConditionFloatAboveThreshold(Data data)
    {
        this.data = data ?? new Data();
        this.data.Value ??= new FlowValueGetFloatData();
    }

    public ValueTask<bool> EvaluateAsync(FlowContext context)
    {
        if (!FlowValueResolveHelper.TryResolveValue(
                data.Value, context, out float value, out _))
        {
            return new ValueTask<bool>(false);
        }

        return new ValueTask<bool>(value > data.Threshold);
    }

    public string Summary(FlowContext context) => string.Empty;
}

Decide failure behavior

Return false when the rule does not pass or when required data cannot resolve. The node or host that evaluates the Condition decides what false means through Guard logic, Reject Result, or module-specific behavior.

Do not mutate Blackboard state to force a later evaluation. Put state changes in an Instruction, then let the Condition read the resulting state explicitly.

Register and test

  1. Run the project code-generation and registry workflow.
  2. Add a Guard to a test Action.
  3. Add Project > Float Above Threshold.
  4. Bind Value to a Local Blackboard Float.
  5. Route the Action to a visible result.
  6. Test one value below and one value above the threshold.
  7. Test the missing-key failure case.
Image 05_03_01Screenshot production note

此处插图应该是 Action Guard 中 Project > Float Above Threshold 的截图;显示 Blackboard Float 绑定、Threshold、Reject Result,并并排展示低于与高于阈值的运行调试结果。

Common Mistakes

  • Performing an operation inside EvaluateAsync that should be an Instruction.
  • Treating a missing typed value as an arbitrary default that passes.
  • Forgetting to clone nested Flow value data.
  • Assuming Guard rejection and busy-node Invoke Mode are the same result.
  • Placing the Condition in an editor-only assembly.

What You Built

You added a typed, side-effect-free rule that designers can reuse in Guards and other supported decision surfaces, with predictable behavior for passing, failing, and missing data.