using System.Collections; using UnityEngine; // 被弾時の攻撃中断、色変更、のけぞりを管理する [RequireComponent(typeof(DamageReceiver))] public class HitReaction : MonoBehaviour { [Tooltip("被弾時に中断する攻撃処理")] [SerializeField] private CharacterAttack characterAttack; [Tooltip("被弾時に色を変えるRenderer")] [SerializeField] private Renderer targetRenderer; [Tooltip("被弾中の色")] [SerializeField] private Color hitColor = Color.red; [Tooltip("被弾リアクションの時間")] [SerializeField] private float duration = 0.2f; [Tooltip("のけぞる速さ")] [SerializeField] private float knockbackPower = 4f; public bool IsReacting => _routine != null; private DamageReceiver _receiver; private Material _material; private Color _defaultColor; private Coroutine _routine; // 被弾処理に必要なコンポーネントと初期色を取得する private void Awake() { _receiver = GetComponent(); if (targetRenderer != null) { _material = targetRenderer.material; _defaultColor = _material.color; } } // 有効になったときにダメージイベントの購読を開始する private void OnEnable() { _receiver.Damaged += OnDamaged; } // イベント購読と実行中のリアクションを解除する private void OnDisable() { _receiver.Damaged -= OnDamaged; if (_routine != null) StopCoroutine(_routine); RestoreAppearance(); _routine = null; } // 攻撃を中断し、被弾リアクションを開始する private void OnDamaged(int damage, int maxHealth) { if (_routine != null) StopCoroutine(_routine); characterAttack?.CancelAttack(); _routine = StartCoroutine(PlayRoutine()); } // 一定時間、色変更とのけぞりを実行する private IEnumerator PlayRoutine() { if (_material != null) _material.color = hitColor; var knockbackDirection = -transform.forward; var elapsedTime = 0f; while (elapsedTime < duration) { transform.position += knockbackDirection * knockbackPower * Time.deltaTime; elapsedTime += Time.deltaTime; yield return null; } RestoreAppearance(); _routine = null; } // Rendererの色を被弾前の状態へ戻す private void RestoreAppearance() { if (_material != null) _material.color = _defaultColor; } // Renderer用に生成したMaterialを破棄する private void OnDestroy() { if (_material != null) Destroy(_material); } }