Files
DeviantMobile-Rohan/Assets/Scripts/AI/Actions/AIAction.cs

73 lines
2.9 KiB
C#

using UnityEngine;
/// <summary>
/// AIAction — Abstract base class for all AI actions.
/// Each action knows how to score itself (utility) and execute.
/// Stateless scoring — all context comes from AIBlackboard.
///
/// Subclasses: CollectBagAction, DepositBagAction, AttackEnemyAction,
/// DefendVaultAction, PatrolAction, RetreatAction,
/// EscortCarrierAction, InterceptCarrierAction
/// </summary>
public abstract class AIAction
{
/// <summary>Display name for debug.</summary>
public abstract string Name { get; }
/// <summary>
/// Evaluate how desirable this action is (0-1 range, higher = more desirable).
/// Called every AI decision tick. Must be allocation-free.
/// </summary>
/// <param name="blackboard">Per-AI knowledge store</param>
/// <param name="teamBoard">Shared team knowledge</param>
/// <returns>Utility score 0-1</returns>
public abstract float Score(AIBlackboard blackboard, TeamBlackboard teamBoard);
/// <summary>
/// Execute this action for one tick.
/// Called every AI tick while this is the active action.
/// </summary>
/// <param name="brain">The AI brain executing this action</param>
/// <param name="blackboard">Per-AI knowledge</param>
/// <param name="teamBoard">Team knowledge</param>
public abstract void Execute(AIBrain brain, AIBlackboard blackboard, TeamBlackboard teamBoard);
/// <summary>Called when this action becomes active (optional setup).</summary>
public virtual void OnEnter(AIBrain brain, AIBlackboard blackboard, TeamBlackboard teamBoard) { }
/// <summary>Called when this action is replaced by another (optional cleanup).</summary>
public virtual void OnExit(AIBrain brain, AIBlackboard blackboard, TeamBlackboard teamBoard) { }
/// <summary>
/// Whether this action can interrupt the current action.
/// High-priority actions (defend vault, retreat) return true.
/// </summary>
public virtual bool CanInterrupt => false;
// ─── Utility Helpers ─────────────────────────────────────
/// <summary>Smooth curve: high when value is low, low when value is high.</summary>
protected float InverseCurve(float value, float max)
{
return Mathf.Clamp01(1f - (value / max));
}
/// <summary>Smooth curve: high when value is high.</summary>
protected float LinearCurve(float value, float max)
{
return Mathf.Clamp01(value / max);
}
/// <summary>Step function: 1 if above threshold, 0 otherwise.</summary>
protected float StepAbove(float value, float threshold)
{
return value >= threshold ? 1f : 0f;
}
/// <summary>Step function: 1 if below threshold, 0 otherwise.</summary>
protected float StepBelow(float value, float threshold)
{
return value < threshold ? 1f : 0f;
}
}