한 발에 죽던 적에게 체력을 부여해서 n발 맞아야 죽도록 변경하고,
죽을 때 이펙트와 함께 사라지는 연출을 추가한 과정을 기록한다.
1. 변경 전 vs 변경 후
변경 전
총알 맞음 → OnHit() → 무조건 Die() = 그냥 멈춰있음
변경 후
총알 맞음 → OnHit() → HP 감소
→ HP > 0: 넉백 + 0.5초 후 행동 재개
→ HP <= 0: Die() → 0.5초 후 이펙트 + 사라짐
2. HP 시스템 구현
추가된 변수
[SerializeField]
[Tooltip("최대 체력")]
private int maxHp = 3;
[SerializeField]
[Tooltip("넉백 후 다시 행동을 재개하기까지의 시간 (초)")]
private float stunDuration = 0.5f;
private int _hp;
- maxHp: Inspector에서 조절 가능 (기본 3 = 3발 맞으면 사망)
- stunDuration: 넉백 후 멍한 시간
- _hp: 현재 남은 체력
Start()에서 초기화
_hp = maxHp;
3. OnHit() 확장
public void OnHit(Vector3 knockbackForce, int damage = 1)
{
if (state == State.Die) return;
_hp -= damage;
// 넉백 적용 (NavMeshAgent 끄기 → Rigidbody 활성화 → 힘 가하기)
// ... (이전과 동일)
if (_hp <= 0)
{
nextState = State.Die; // 죽음
}
else
{
StartCoroutine(RecoverFromHit()); // 회복
}
}
핵심: damage = 1 (기본값 파라미터)
enemy.OnHit(힘); // damage = 1 (기본값)
enemy.OnHit(힘, 5); // damage = 5 (강한 무기)
Bullet.cs를 수정하지 않아도 기본 1 데미지가 적용된다.
나중에 강한 무기를 만들면 damage 값만 바꾸면 된다.
4. 코루틴으로 넉백 회복
private IEnumerator RecoverFromHit()
{
yield return new WaitForSeconds(stunDuration); // 0.5초 대기
// Rigidbody 초기화 (물리 비활성화)
Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
{
rb.linearVelocity = Vector3.zero;
rb.isKinematic = true;
rb.constraints = RigidbodyConstraints.None;
}
// NavMeshAgent 다시 켜기 → 행동 재개
_agent.enabled = true;
nextState = State.Idle;
}
코루틴(Coroutine)이란?
일반 함수는 한 프레임 안에서 전부 실행된다. 코루틴은 중간에 멈추고 나중에 이어할 수 있는 특수한 함수다.
일반 함수: 실행 → → → → → 끝 (한 프레임에 전부)
코루틴: 실행 → → 멈춤(0.5초 대기) → → → 끝 (여러 프레임에 걸쳐)
yield return new WaitForSeconds(0.5f) = "0.5초 기다려, 그 다음 줄부터 다시 실행해"
회복 흐름
맞음 → 넉백으로 밀림 → 0.5초 멍 → Rigidbody 정지 → NavMeshAgent 재시작 → Idle 상태
→ 다시 순찰/추적 시작!
5. 죽음 연출: 이펙트 + 사라짐
private IEnumerator DieAndDisappear()
{
yield return new WaitForSeconds(0.5f); // 죽는 애니메이션 잠깐 보여주기
if (splashFx != null)
Instantiate(splashFx, transform.position, Quaternion.identity);
gameObject.SetActive(false); // 사라짐
}
흐름은 다음과 같다.
Die 상태 → stun 애니메이션 재생 → 0.5초 대기 → 이펙트(OrangeHit) 터짐 → 오브젝트 비활성화
6. 넉백 방향 수정
문제: 적이 앞으로 당겨짐
처음엔 enemy.position - bullet.position으로 방향을 계산했는데, 충돌 시점에 총알이 이미 적을 통과한 뒤라서 방향이 반대가 될 수 있었다.
해결: 총알의 실제 이동 방향(velocity) 사용
// 변경 전: 위치 기반 (부정확)
Vector3 dir = enemy.transform.position - transform.position;
// 변경 후: 속도 기반 (정확)
Vector3 dir = bulletRb.linearVelocity.normalized;
총알이 날아가던 방향 그대로 적을 미니까 항상 정확하다.
7. 이번 작업에서 배운 것 요약
- HP 시스템 = _hp 변수 + OnHit()에서 감소 + 0 체크
- 기본값 파라미터 (damage = 1) = 호출하는 쪽을 수정 안 해도 됨
- 코루틴 = yield return으로 시간을 두고 실행하는 함수
- 넉백 회복 = Rigidbody 정지 → isKinematic 복원 → Agent 재시작
- 죽음 연출 = 코루틴으로 딜레이 후 이펙트 + SetActive(false)
- 넉백 방향은 위치 뺄셈보다 velocity가 정확함
'Unity 궁둥이 쪼물쪼물' 카테고리의 다른 글
| 011. 싱글톤 GameManager & 승리 조건 (0) | 2026.04.15 |
|---|---|
| 010. 플레이어 체력 & 게임오버 (0) | 2026.04.13 |
| 008. 넉백 코드 리팩토링 (0) | 2026.04.13 |
| 007. 넉백(Knockback) 구현 (0) | 2026.04.06 |
| 006. 총알에 오브젝트 풀링 적용하기 (0) | 2026.04.06 |