107 lines
6.4 KiB
C#
107 lines
6.4 KiB
C#
using UnityEngine; // 유니티 엔진의 기본 기능을 불러올거에요 -> UnityEngine을
|
|
|
|
/// <summary>
|
|
/// 만능 투사체 (화살, 마법, 돌맹이 공용)
|
|
/// </summary>
|
|
public class Projectile : MonoBehaviour // 클래스를 선언할거에요 -> MonoBehaviour를 상속받는 Projectile을
|
|
{
|
|
[Header("기본 설정")] // 인스펙터 창에 제목을 표시할거에요 -> 기본 설정 을
|
|
[SerializeField] private float lifetime = 5f; // 변수를 선언할거에요 -> 수명(5.0초)을 lifetime에
|
|
[SerializeField] private GameObject hitEffectPrefab; // 변수를 선언할거에요 -> 충돌 이펙트 프리팹을 hitEffectPrefab에
|
|
[SerializeField] private bool destroyOnHit = true; // 변수를 선언할거에요 -> 충돌 시 삭제 여부를 destroyOnHit에
|
|
|
|
// 내부 변수
|
|
private Vector3 _direction; // 변수를 선언할거에요 -> 날아갈 방향을 _direction에
|
|
private float _speed; // 변수를 선언할거에요 -> 이동 속도를 _speed에
|
|
private float _damage; // 변수를 선언할거에요 -> 공격 데미지를 _damage에
|
|
private bool _isInitialized = false; // 변수를 초기화할거에요 -> 초기화 여부를 거짓(false)으로
|
|
private Rigidbody _rigidbody; // 변수를 선언할거에요 -> 물리 컴포넌트 _rigidbody를
|
|
|
|
private void Awake() // 함수를 실행할거에요 -> 스크립트 시작 시 호출되는 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) // 함수를 선언할거에요 -> 투사체 정보를 설정하는 Initialize를
|
|
{
|
|
_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) // 조건이 맞으면 실행할거에요 -> 리지드바디가 있고 속도가 0이라면
|
|
{
|
|
_rigidbody.useGravity = true; // 설정을 바꿀거에요 -> 중력 영향을 켜기로 (포물선 비행)
|
|
}
|
|
|
|
// 수명 지나면 자동 삭제
|
|
Destroy(gameObject, lifetime); // 파괴할거에요 -> 이 오브젝트를 수명 시간이 지나면
|
|
}
|
|
|
|
private void FixedUpdate() // 함수를 실행할거에요 -> 물리 연산 주기로 호출되는 FixedUpdate를
|
|
{
|
|
if (!_isInitialized) return; // 조건이 맞으면 중단할거에요 -> 초기화되지 않았다면
|
|
|
|
// 리지드바디가 없거나, Kinematic인 경우 (강제 이동 보정)
|
|
if (_rigidbody == null || _rigidbody.isKinematic) // 조건이 맞으면 실행할거에요 -> 물리 이동을 안 쓰는 상태라면
|
|
{
|
|
if (_speed > 0) // 조건이 맞으면 실행할거에요 -> 속도가 설정되어 있다면
|
|
{
|
|
transform.position += _direction * _speed * Time.fixedDeltaTime; // 이동시킬거에요 -> 방향과 속도에 맞춰 직접 위치를
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other) // 함수를 실행할거에요 -> 충돌이 발생했을 때 OnTriggerEnter를
|
|
{
|
|
// 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); // 함수를 실행할거에요 -> 데미지를 입히는 TakeDamage를
|
|
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); // 파괴할거에요 -> 이 투사체 오브젝트를
|
|
}
|
|
}
|
|
}
|
|
} |