ノックバックアニメーション追加

This commit is contained in:
KawakamiKento
2026-06-02 12:35:45 +09:00
parent 1568a27840
commit 6aaaca800b
8 changed files with 293 additions and 44 deletions

View File

@@ -1,6 +1,7 @@
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
using System;
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(Animator))]
@@ -49,6 +50,8 @@ public class EnemyAI : MonoBehaviour
private bool isCooldown = false;
private bool isAttacking = false;
private bool isWandering = false;
private bool isKnockbacking = false;
private bool isDead = false;
private void Start()
{
@@ -61,6 +64,8 @@ public class EnemyAI : MonoBehaviour
private void Update()
{
if(isDead) return;
// 毎フレームのアニメーションパラメータ更新処理
UpdateAnimation();
@@ -73,14 +78,16 @@ public class EnemyAI : MonoBehaviour
{
while (true)
{
if(isDead) yield break;
// プレイヤーが未検出の場合はタグから検索
if (playerTransform == null)
{
FindPlayer();
}
// 攻撃アニメーションの再生中でない場合のみ、ステートに応じた行動を実行
if (!isAttacking)
// 攻撃、のけぞりアニメーションの再生中でない場合のみ、ステートに応じた行動を実行
if (!isAttacking && !isKnockbacking)
{
switch (currentState)
{
@@ -164,8 +171,11 @@ public class EnemyAI : MonoBehaviour
return;
}
// クールダウン中であっても、追跡ステートである限りはプレイヤーの現在位置を追い続け
agent.SetDestination(playerTransform.position);
// のけぞり中でない場合、追跡の目的地を更新す
if(!isKnockbacking)
{
agent.SetDestination(playerTransform.position);
}
}
/// 【攻撃状態】の思考ロジック
@@ -201,7 +211,7 @@ public class EnemyAI : MonoBehaviour
float targetSpeed = 0f;
// 攻撃中でなく、経路が存在し、かつ実際に一定以上の速度で移動している場合のみSpeedを1にする
if (!isAttacking && agent.hasPath && agent.velocity.magnitude > 0.1f)
if (!isAttacking && !isKnockbacking && agent.hasPath && agent.velocity.magnitude > 0.1f)
{
targetSpeed = 1f;
}
@@ -213,7 +223,7 @@ public class EnemyAI : MonoBehaviour
/// 攻撃ステートの際、プレイヤーの方向へ滑らかに旋回させる
private void UpdateRotationOnAttack()
{
if (currentState == AIState.Attack && playerTransform != null)
if (currentState == AIState.Attack && playerTransform != null && !isKnockbacking)
{
Vector3 direction = (playerTransform.position - transform.position).normalized;
direction.y = 0; // 上下方向の傾き(ピッチ回転)を無視
@@ -227,6 +237,60 @@ public class EnemyAI : MonoBehaviour
}
#endregion
// ダメージを受けた際に、EnemyhHealthから呼び出されるのけぞり開始メソッド
public void TriggerKnockback(float duration)
{
if(isDead) return;
StopAllCoroutines();
isAttacking = false;
isWandering = false;
isKnockbacking = false;
if(agent.isOnNavMesh)
{
agent.isStopped = false;
}
StartCoroutine(KnockbackRoutine(duration));
}
public void DisableAIOnDeath()
{
isDead = true;
StopAllCoroutines();
if(agent != null && agent.isOnNavMesh)
{
agent.isStopped = true;
agent.ResetPath();
}
}
private IEnumerator KnockbackRoutine(float duration)
{
isKnockbacking = true;
if(agent.isOnNavMesh)
{
agent.isStopped = true;
agent.ResetPath();
}
anim.SetTrigger("Hit");
yield return new WaitForSeconds(duration);
if(agent.isOnNavMesh)
{
agent.isStopped = false;
}
isKnockbacking = false;
isCooldown = false;
StartCoroutine(AILoop());
}
#region
/// 徘徊時のランダム移動を制御するコルーチン
private IEnumerator WanderMoveRoutine()
@@ -274,7 +338,7 @@ public class EnemyAI : MonoBehaviour
}
// 到着または諦めた後、ランダムな時間その場で待機
yield return new WaitForSeconds(Random.Range(minWaitTime, maxWaitTime));
yield return new WaitForSeconds(UnityEngine.Random.Range(minWaitTime, maxWaitTime));
isWandering = false;
}
@@ -289,6 +353,8 @@ public class EnemyAI : MonoBehaviour
yield return new WaitForSeconds(telegraphDuration);
if(isKnockbacking) yield break;
anim.SetTrigger("Attack");
}
@@ -313,7 +379,7 @@ public class EnemyAI : MonoBehaviour
/// 攻撃アニメーションのヒットフレームで実行されるヒット判定Animation Eventから呼び出し
public void OnPunchHit()
{
if (playerTransform == null) return;
if (isKnockbacking || playerTransform == null) return;
float distanceToPlayer = Vector3.Distance(transform.position, playerTransform.position);
@@ -327,6 +393,7 @@ public class EnemyAI : MonoBehaviour
/// Recovery硬直アニメーションの終了時に実行される処理Animation Eventから呼び出し
public void OnRecoveryEnd()
{
if(isKnockbacking) return;
isAttacking = false;
if (playerTransform == null)
@@ -358,7 +425,7 @@ public class EnemyAI : MonoBehaviour
/// 指定された中心座標の範囲内から、NavMesh上の有効なランダム座標を取得する
private Vector3 GetRandomNavMeshPoint(Vector3 center, float radius)
{
Vector3 randomDirection = Random.insideUnitSphere * radius;
Vector3 randomDirection = UnityEngine.Random.insideUnitSphere * radius;
randomDirection += center;
NavMeshHit hit;

View File

@@ -6,13 +6,13 @@ public class EnemyHealth : MonoBehaviour, IDamageble
[SerializeField] private float maxHealth = 100f;
private float currentHealth;
[SerializeField] private float knockbackForce = 5f;
private Rigidbody rb;
[SerializeField] private float knockbackDuration = 0.5f;
private EnemyAI enemyAI;
void Start()
{
currentHealth = maxHealth; //HPを代入
rb = GetComponent<Rigidbody>();
enemyAI = GetComponent<EnemyAI>();
}
public void TakeDamage(DamageInfo damageInfo)
@@ -26,19 +26,26 @@ public class EnemyHealth : MonoBehaviour, IDamageble
Debug.Log("構えボーナス");
}
if(rb != null) //ノックバック
{
rb.AddForce(damageInfo.punchDirection * knockbackForce, ForceMode.Impulse); //パンチが飛んできた方向に力を加える
}
if(currentHealth <= 0)
{
Die();
}
else
{
if(enemyAI != null)
{
enemyAI.TriggerKnockback(knockbackDuration);
}
}
}
private void Die()
{
if(enemyAI != null)
{
enemyAI.DisableAIOnDeath();
}
Destroy(gameObject, 0.5f);
}
}