スタン状態追加

This commit is contained in:
KawakamiKento
2026-06-03 16:35:15 +09:00
parent 6aaaca800b
commit 69f5891a14
7 changed files with 369 additions and 44 deletions

View File

@@ -12,7 +12,8 @@ public class EnemyAI : MonoBehaviour
{
Wander, // 徘徊
Chase, // 追跡
Attack // 攻撃
Attack, // 攻撃
Stun // 怯み
}
[Header("現在の状態")]
@@ -32,6 +33,7 @@ public class EnemyAI : MonoBehaviour
[SerializeField] private float attackCooldown = 2.0f;
[Tooltip("攻撃の予兆時間 (秒)")]
[SerializeField] private float telegraphDuration = 0.6f;
[SerializeField] private Collider rightHandCollider;
[Header("ループ攻撃の調整")]
[Tooltip("連続攻撃の間に挟む最低限のインターバル (秒)")]
@@ -57,6 +59,8 @@ public class EnemyAI : MonoBehaviour
{
agent = GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
SetFistCollider(false);
// AIのメインループコルーチンを開始
StartCoroutine(AILoop());
@@ -87,7 +91,7 @@ public class EnemyAI : MonoBehaviour
}
// 攻撃、のけぞりアニメーションの再生中でない場合のみ、ステートに応じた行動を実行
if (!isAttacking && !isKnockbacking)
if (!isAttacking && !isKnockbacking && currentState != AIState.Stun)
{
switch (currentState)
{
@@ -211,7 +215,7 @@ public class EnemyAI : MonoBehaviour
float targetSpeed = 0f;
// 攻撃中でなく、経路が存在し、かつ実際に一定以上の速度で移動している場合のみSpeedを1にする
if (!isAttacking && !isKnockbacking && agent.hasPath && agent.velocity.magnitude > 0.1f)
if (!isAttacking && !isKnockbacking && currentState != AIState.Stun && agent.hasPath && agent.velocity.magnitude > 0.1f)
{
targetSpeed = 1f;
}
@@ -223,7 +227,7 @@ public class EnemyAI : MonoBehaviour
/// 攻撃ステートの際、プレイヤーの方向へ滑らかに旋回させる
private void UpdateRotationOnAttack()
{
if (currentState == AIState.Attack && playerTransform != null && !isKnockbacking)
if (currentState == AIState.Attack && playerTransform != null && !isKnockbacking && currentState != AIState.Stun)
{
Vector3 direction = (playerTransform.position - transform.position).normalized;
direction.y = 0; // 上下方向の傾き(ピッチ回転)を無視
@@ -242,6 +246,7 @@ public class EnemyAI : MonoBehaviour
{
if(isDead) return;
SetFistCollider(false);
StopAllCoroutines();
isAttacking = false;
isWandering = false;
@@ -255,6 +260,21 @@ public class EnemyAI : MonoBehaviour
StartCoroutine(KnockbackRoutine(duration));
}
public void TriggerParryStun(float duration)
{
if(isDead) return;
Debug.Log($"{gameObject.name}: parry = true Stunnow");
SetFistCollider(false);
StopAllCoroutines();
isAttacking = false;
isWandering = false;
isKnockbacking = false;
StartCoroutine(ParryStunRoutine(duration));
}
public void DisableAIOnDeath()
{
isDead = true;
@@ -266,6 +286,31 @@ public class EnemyAI : MonoBehaviour
}
}
private IEnumerator ParryStunRoutine(float duration)
{
currentState = AIState.Stun;
if(agent.isOnNavMesh)
{
agent.isStopped = true;
agent.ResetPath();
}
anim.SetTrigger("Stun");
yield return new WaitForSeconds(duration);
if(agent.isOnNavMesh)
{
agent.isStopped = false;
}
currentState = AIState.Chase;
isCooldown = false;
StartCoroutine(AILoop());
}
private IEnumerator KnockbackRoutine(float duration)
{
isKnockbacking = true;
@@ -379,21 +424,17 @@ public class EnemyAI : MonoBehaviour
/// 攻撃アニメーションのヒットフレームで実行されるヒット判定Animation Eventから呼び出し
public void OnPunchHit()
{
if (isKnockbacking || playerTransform == null) return;
if (isKnockbacking || currentState == AIState.Stun) return;
float distanceToPlayer = Vector3.Distance(transform.position, playerTransform.position);
// ヒット判定の瞬間、プレイヤーが射程内に残っているか判定猶予として0.3m加算)
if (distanceToPlayer <= attackRange + 0.3f)
{
Debug.Log($"💥 敵のパンチがヒット!");
}
SetFistCollider(true);
}
/// Recovery硬直アニメーションの終了時に実行される処理Animation Eventから呼び出し
public void OnRecoveryEnd()
{
if(isKnockbacking) return;
if(isKnockbacking || currentState == AIState.Stun) return;
SetFistCollider(false);
isAttacking = false;
if (playerTransform == null)
@@ -423,6 +464,14 @@ public class EnemyAI : MonoBehaviour
#region
/// 指定された中心座標の範囲内から、NavMesh上の有効なランダム座標を取得する
private void SetFistCollider(bool enabledState)
{
if(rightHandCollider != null)
{
rightHandCollider.enabled = enabledState;
}
}
private Vector3 GetRandomNavMeshPoint(Vector3 center, float radius)
{
Vector3 randomDirection = UnityEngine.Random.insideUnitSphere * radius;