using UnityEngine; /// /// 만능 투사체 (화살, 마법, 돌맹이 공용) /// public class Projectile : MonoBehaviour { [Header("기본 설정")] [SerializeField] private float lifetime = 5f; // 수명 (5초 뒤 삭제) [SerializeField] private GameObject hitEffectPrefab; // 맞으면 나오는 이펙트 (폭발 등) [SerializeField] private bool destroyOnHit = true; // 맞으면 사라짐? (관통 아니면 true) // 내부 변수 private Vector3 _direction; private float _speed; private float _damage; private bool _isInitialized = false; private Rigidbody _rigidbody; private void Awake() { _rigidbody = GetComponent(); } /// /// 몬스터가 발사할 때 호출하는 초기화 함수 /// /// 날아갈 방향 /// 속도 (0이면 물리력으로 날아감) /// 줄 데미지 public void Initialize(Vector3 direction, float speed, float damage) { _direction = direction.normalized; _speed = speed; _damage = damage; _isInitialized = true; // 속도가 있다? -> 화살/마법 (직선 운동) if (_rigidbody != null && speed > 0) { _rigidbody.velocity = _direction * _speed; _rigidbody.useGravity = false; // 마법은 보통 중력 무시 } // 속도가 0이다? -> 돌맹이 (외부에서 물리력 가함) else if (_rigidbody != null && speed == 0) { _rigidbody.useGravity = true; // 돌은 중력 받아야 함 } // 수명 지나면 자동 삭제 Destroy(gameObject, lifetime); } private void FixedUpdate() { if (!_isInitialized) return; // 리지드바디가 없거나, Kinematic인 경우 (강제 이동 보정) if (_rigidbody == null || _rigidbody.isKinematic) { if (_speed > 0) { transform.position += _direction * _speed * Time.fixedDeltaTime; } } } private void OnTriggerEnter(Collider other) { // 1. 적(몬스터)끼리 맞으면 무시 if (other.CompareTag("Enemy") || other.gameObject == gameObject) return; // 2. 투사체끼리 충돌 무시 if (other.GetComponent()) return; // 3. 플레이어 피격 처리 if (other.CompareTag("Player")) { // PlayerHealth 혹은 IDamageable 스크립트 찾기 var playerHealth = other.GetComponent(); if (playerHealth != null) { // 무적 상태 체크 (있다면) if (!playerHealth.isInvincible) { playerHealth.TakeDamage(_damage); Debug.Log($"🎯 [적중] 플레이어에게 {_damage} 데미지!"); } } } // 4. 벽이나 땅에 닿았을 때도 이펙트 if (other.CompareTag("Ground") || other.CompareTag("Wall") || other.CompareTag("Player")) { if (hitEffectPrefab != null) { Instantiate(hitEffectPrefab, transform.position, Quaternion.identity); } if (destroyOnHit) { Destroy(gameObject); } } } }