Projext/Assets/Scripts/Enemy/AI/Rangedbase.cs
2026-02-06 00:42:48 +09:00

107 lines
3.4 KiB
C#

using UnityEngine;
/// <summary>
/// 만능 투사체 (화살, 마법, 돌맹이 공용)
/// </summary>
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<Rigidbody>();
}
/// <summary>
/// 몬스터가 발사할 때 호출하는 초기화 함수
/// </summary>
/// <param name="direction">날아갈 방향</param>
/// <param name="speed">속도 (0이면 물리력으로 날아감)</param>
/// <param name="damage">줄 데미지</param>
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<Projectile>()) return;
// 3. 플레이어 피격 처리
if (other.CompareTag("Player"))
{
// PlayerHealth 혹은 IDamageable 스크립트 찾기
var playerHealth = other.GetComponent<PlayerHealth>();
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);
}
}
}
}