105 lines
2.6 KiB
C#
105 lines
2.6 KiB
C#
using Invector.vCharacterController.AI.FSMBehaviour;
|
|
using UnityEngine;
|
|
|
|
namespace ArcherEnemy
|
|
{
|
|
/// <summary>
|
|
/// State action that makes archer shoot an arrow
|
|
/// Should be called in OnStateEnter or OnStateUpdate
|
|
/// </summary>
|
|
[CreateAssetMenu(menuName = "Invector/FSM/Actions/Archer/Shoot Arrow")]
|
|
public class SA_ShootArrow : vStateAction
|
|
{
|
|
public override string categoryName => "Archer/Combat";
|
|
public override string defaultName => "Shoot Arrow";
|
|
|
|
[Header("Configuration")]
|
|
[Tooltip("Shoot once per state enter, or continuously?")]
|
|
public bool shootOnce = true;
|
|
|
|
[Tooltip("Time between shots when shooting continuously")]
|
|
public float shootInterval = 2f;
|
|
|
|
[Header("Debug")]
|
|
[Tooltip("Enable debug logging")]
|
|
public bool enableDebug = false;
|
|
|
|
private float lastShootTime = -999f;
|
|
private bool hasShotThisState = false;
|
|
|
|
public override void DoAction(vIFSMBehaviourController fsmBehaviour, vFSMComponentExecutionType executionType = vFSMComponentExecutionType.OnStateUpdate)
|
|
{
|
|
if (executionType == vFSMComponentExecutionType.OnStateEnter)
|
|
{
|
|
OnEnter(fsmBehaviour);
|
|
}
|
|
else if (executionType == vFSMComponentExecutionType.OnStateUpdate)
|
|
{
|
|
OnUpdate(fsmBehaviour);
|
|
}
|
|
else if (executionType == vFSMComponentExecutionType.OnStateExit)
|
|
{
|
|
OnExit(fsmBehaviour);
|
|
}
|
|
}
|
|
|
|
private void OnEnter(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
hasShotThisState = false;
|
|
|
|
if (shootOnce)
|
|
{
|
|
TryShoot(fsmBehaviour);
|
|
}
|
|
}
|
|
|
|
private void OnUpdate(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
if (shootOnce && hasShotThisState)
|
|
{
|
|
return; // Already shot once this state
|
|
}
|
|
|
|
// Check interval for continuous shooting
|
|
if (!shootOnce && Time.time >= lastShootTime + shootInterval)
|
|
{
|
|
TryShoot(fsmBehaviour);
|
|
}
|
|
}
|
|
|
|
private void OnExit(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
// Stop any shooting sequence
|
|
var shootingAI = fsmBehaviour.gameObject.GetComponent<ArcherShootingAI>();
|
|
if (shootingAI != null)
|
|
{
|
|
shootingAI.StopShooting();
|
|
}
|
|
}
|
|
|
|
private void TryShoot(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
var shootingAI = fsmBehaviour.gameObject.GetComponent<ArcherShootingAI>();
|
|
|
|
if (shootingAI == null)
|
|
{
|
|
if (enableDebug) Debug.LogError("[SA_ShootArrow] No ArcherShootingAI component found!");
|
|
return;
|
|
}
|
|
|
|
// Attempt to shoot
|
|
if (shootingAI.CanShoot())
|
|
{
|
|
shootingAI.StartShooting();
|
|
hasShotThisState = true;
|
|
lastShootTime = Time.time;
|
|
|
|
if (enableDebug) Debug.Log("[SA_ShootArrow] Shooting arrow");
|
|
}
|
|
else
|
|
{
|
|
if (enableDebug) Debug.Log("[SA_ShootArrow] Cannot shoot - conditions not met");
|
|
}
|
|
}
|
|
}
|
|
} |