Decorators
Decorators modify or wrap child behavior with additional logic like repetition, inversion, or timing.
Overview
Decorators are utility nodes that wrap other nodes and modify their behavior. They use a push-then-pop stack pattern: you call a D.*() function to push a decorator, then immediately create a node which pops the decorator and wraps itself.
Critical Rule: Decorators must come BEFORE the node they decorate.
Reactive * Sequence("Guard Dog", () =>
{
var distance = Variable(() => 0f);
OnTick(() => distance.Value = DistanceToPlayer());
D.ConditionLatch("Too Close", () => distance.Value < 3f);
D.Until("Far Enough", () => distance.Value > 5f);
Chase(() => Player, () =>
{
OnEnter(() => Debug.Log("Guard Dog began chasing player!"));
OnExit(() => Debug.Log("Guard Dog stopped chasing player."));
});
Sequence(() =>
{
WaitUntil("Return To Post", () => MoveTo(Post.transform.position));
JustRunning("Idle");
});
}); Reactive * Sequence("Guard Dog", () =>
{
var distance = Variable(() => 0f);
OnTick(() => distance.Value = DistanceToPlayer());
D.ConditionLatch("Too Close", () => distance.Value < 3f);
D.Until("Far Enough", () => distance.Value > 5f);
Chase(() => Player, () =>
{
OnEnter(() => Debug.Log("Guard Dog began chasing player!"));
OnExit(() => Debug.Log("Guard Dog stopped chasing player."));
});
Sequence(() =>
{
WaitUntil("Return To Post", () => MoveTo(Post.transform.position));
JustRunning("Idle");
});
}); D.Condition(Func<bool>) / D.Condition(string, Func<bool>)
Only runs child when condition is true.
D.ConditionLatch(Func<bool>) / D.ConditionLatch(string, Func<bool>)
Latches once the condition becomes true, continuing to run until completion even if condition becomes false.
D.While(Func<bool>) / D.While(string, Func<bool>)
Runs child while a condition remains true, failing when the condition becomes false.
D.Repeat()
Repeat child infinitely until interrupted.
D.RepeatCount(int) / D.RepeatCount(Func<int>)
Repeats its child node a specified number of times.
D.Until(Status, Action) / D.Until(Func<bool>, Action)
Repeats child until it returns a target status, or runs child until a condition becomes true.
D.ForEach<T>(IEnumerable, out T) / D.ForEach<T, R>(IEnumerable, Func, out R)
Runs child for each item in a list, with optional mapping function.
D.Invert()
Flips Success ↔ Failure.
D.AlwaysFail()
Always returns Failure, regardless of the child node's actual status.
D.AlwaysSucceed()
Always returns Success, regardless of the child node's actual status.
D.Cooldown(float) / D.Cooldown(Func<float>)
Enforces a cooldown period on its child node, preventing execution until duration has elapsed after completion.
D.Timeout(float)
Fails if its child doesn't complete within the specified timeout duration.
D.Latched()
Blocks invalidation signals from propagating upward from its child to parent nodes.
D.ResetOnEnter()
Resets its child node on both entry and exit, ensuring the child always starts fresh.
D.ValueChanged<T>(Func<T>)
Invalidates when a monitored value changes, enabling reactive behavior based on value changes.