AI/ActionSystem/BehaviorTree/Nodes/TimedSequenceNode.cs
using System;
namespace HC3;
/// <summary>
/// A node that performs an animated action with a specific sequence.
/// </summary>
public class TimedSequenceNode : Node
{
private readonly Agent _agent;
private readonly string _animationSequence;
private readonly float _animationDuration;
private readonly string _reason;
private readonly Action _onStart;
private readonly Action _onComplete;
private readonly Func<bool> _conditionCheck;
private RealTimeSince _timeSinceStarted;
private bool _animationComplete;
private readonly string _icon;
/// <summary>
/// Creates a node that performs an animated action
/// </summary>
/// <param name="agent">The agent performing the animation</param>
/// <param name="animationSequence">The animation sequence to play</param>
/// <param name="animationDuration">How long the animation lasts</param>
/// <param name="onStart">Action to perform when animation starts</param>
/// <param name="onComplete">Action to perform when animation completes</param>
/// <param name="conditionCheck">Optional condition that must be true for the action to continue</param>
/// <param name="reason">Display reason for this action</param>
/// <param name="icon">Material icon to display</param>
public TimedSequenceNode(
Agent agent,
string animationSequence,
float animationDuration,
Action onStart = null,
Action onComplete = null,
Func<bool> conditionCheck = null,
string reason = "Performing action...",
string icon = "movie" )
{
_agent = agent;
_animationSequence = animationSequence;
_animationDuration = animationDuration;
_onStart = onStart;
_onComplete = onComplete;
_conditionCheck = conditionCheck ?? (() => true);
_reason = reason;
_icon = icon;
}
protected override void OnStart()
{
_timeSinceStarted = 0;
_animationComplete = false;
// Play animation
_agent.SetSequenceOverride( _animationSequence, 1.0f );
// Execute start action
_onStart?.Invoke();
}
public override Status Tick()
{
// If condition check fails, return failure
if ( !_conditionCheck() )
{
_agent.SetSequenceOverride( null );
return Status.Failure;
}
// Wait for animation to complete
if ( _timeSinceStarted < _animationDuration )
return Status.Running;
// Animation is complete
if ( !_animationComplete )
{
_agent.SetSequenceOverride( null );
_onComplete?.Invoke();
_animationComplete = true;
}
return Status.Success;
}
protected override void OnStop()
{
// Ensure animation is cleared when node stops
if ( !_animationComplete )
{
_agent.SetSequenceOverride( null );
}
}
public override ActionDisplayInfo? GetDisplay()
{
float progress = (_timeSinceStarted / _animationDuration).Clamp( 0f, 1f );
return new ActionDisplayInfo( _icon, _reason, progress );
}
}