AI/ActionSystem/BehaviorTree/Nodes/TimedActionNode.cs
using System;
namespace HC3;
/// <summary>
/// A node that performs an action after a specified time period, with a condition check.
/// </summary>
public class TimedActionNode : Node
{
private readonly string _reason;
private readonly float _duration;
private readonly Func<bool> _conditionCheck;
private readonly Action _onComplete;
private TimeUntil _timer;
private bool _started;
private readonly string _icon;
/// <summary>
/// Creates a node that performs an action after a delay
/// </summary>
/// <param name="duration">How long to wait before completing the action</param>
/// <param name="onComplete">Action to perform when timer completes</param>
/// <param name="conditionCheck">Optional condition that must be true for the action to continue</param>
/// <param name="reason">Display reason for this timed action</param>
/// <param name="icon">Material icon to display</param>
public TimedActionNode( float duration, Action onComplete, Func<bool> conditionCheck = null, string reason = "Waiting...", string icon = "timer" )
{
_duration = duration;
_onComplete = onComplete;
_conditionCheck = conditionCheck ?? (() => true);
_reason = reason;
_icon = icon;
}
protected override void OnStart()
{
_timer = _duration;
_started = true;
}
public override Status Tick()
{
// If condition check fails, return failure
if ( !_conditionCheck() )
return Status.Failure;
// Wait for timer to complete
if ( !_timer )
{
if ( _started )
{
_onComplete?.Invoke();
_started = false;
}
return Status.Success;
}
return Status.Running;
}
public override ActionDisplayInfo? GetDisplay()
{
float progress = 1f - (_timer / _duration).Clamp( 0f, 1f );
return new ActionDisplayInfo( _icon, _reason, progress );
}
}