3-4. 캐릭터 체력 및 점수 관리 시스템 구현하기
1. 캐릭터 체력 시스템 구현하기
캐릭터 클래스에 체력 변수 및 함수 선언
PlayerState를 쓰지 않는 이유
- 주로 멀티플레이 환경에서 각 플레이어 간 데이터 동기화를 위해 사용
- 싱글 플레이 게임에서는 동기화가 필요 없음
캐릭터 클래스에 체력 관리 로직 추가
싱글 플레이 환경을 가정하여, 플레이어 캐릭터를 담당하는 SpartaCharacter 클래스에 체력 관리용 변수를 선언
- MaxHealth: 캐릭터의 최대 체력
- Health: 캐릭터의 현재 체력
- TakeDamage(): 데미지를 받았을 때 호출되는 함수, 내부에서 체력을 감소시키는 로직을 처리
- AddHealth(): 아이템 등을 통해 체력을 회복할 때 호출하는 함수, 내부에서 체력을 회복
- OnDeath(): 체력이 0 이하가 되었을 때 호출되는 사망 처리 함수


데미지 및 회복 처리
AddHealth(float Amount)
- 체력을 일정 양만큼 회복
- FMath::Clamp를 통해 최대 체력을 초과하지 않도록 제한
TakeDamage(...)
- 언리얼 엔진의 기본 데미지 시스템을 사용하는 대표적인 함수
- DamageAmount: 데미지 값
- ActualDamage: 캐릭터가 입는 데미지 값 (예시: 데미지 30 - 방어력 20 = 10)
- EventInstigator: 데미지를 유발한 주체(Controller)
- DamageCauser: 데미지를 직접 발생시킨 오브젝트(총알, 폭발물 등)
- 반환값: 실제 적용된 데미지(기본 로직에서는 DamageAmount와 동일한 경우가 많지만, 게임 상황에 따라 감소 또는 증폭 등을 처리할 수도 있음)
OnDeath()
- 체력이 0 이하로 떨어졌을 때 사망 로직을 처리하는 함수
- 입력 비활성화, Ragdoll 적용, 사망 애니메이션 재생 등을 수행


지뢰 아이템 데미지 함수 수정
MineItem 이 폭발할 때, 주변 액터에게 데미지를 주려면 UGameplayStatics::ApplyDamage 함수를 호출
해당 액터의 TakeDamage()가 실행되도록 하면 됨
ApplyDamage()
- 대상 Actor 가 존재하는지 확인
- 대상 액터의 TakeDamage() 함수를 호출
- DamageType 은 여러 가지 파생 클래스를 만들어 물리/화염/독 등 다양한 데미지 유형을 정의할 수 있음 (지금은 기본값 사용)
지뢰는 독립적으로 스폰된 뒤 폭발하므로 EventInstigator를 nullptr로 둡니다.
멀티플레이에서 “누가 지뢰를 설치했느냐” 를 추적하려면, 생성 시점에 Instigator 나 Controller 정보를 넣어줄 수도 있음

힐링 아이템 체력 회복 함수 수정
HealingItem → 플레이어를 회복
AddHealth() 함수를 직접 호출해 체력을 증가
ActorHasTag("Player") 로 플레이어인지 판별하는 단순 로직
캐릭터를 구분하는 더 안전한 방법
(예: Cast<ASpartaCharacter>(Activator)) 을 쓰거나, Collision 채널을 이용하는 식으로도 바꿀 수 있음

2. 점수 관리 시스템 구현하기
GameMode와 GameState의 연계 이해
언리얼 엔진에서의 GameMode, GameState
→ 게임의 전역 정보를 유지, 필요할 경우 멀티플레이어 환경에서 해당 정보를 서버와 클라이언트 간에 동기화하는 역할
GameMode
- 게임의 규칙을 정의하고 관리
- 어떤 캐릭터를 스폰할지, 플레이어가 사망했을 때 어떻게 처리할지를 결정
- 멀티플레이에서는 서버 전용으로 동작 (클라이언트에는 존재하지 않음)
GameState
- 게임 플레이 전반에서 공유되어야 하는 전역 상태를 저장
- GameState는 기본적으로 레벨당 1개가 존재
- 전역 데이터 관리용으로 적합 (엔진 내부에서 데이터 동기화를 고려해 설계되었음)
- 점수, 남은 시간, 현재 게임 단계(Phase), 스폰된 오브젝트의 총 개수 등을 저장
- 멀티플레이에서는 서버가 관리하고, 클라이언트는 이를 자동으로 동기화 받아볼 수 있음
싱글 플레이에서의 GameState
전역적으로 공유해야 할 정보를 한 군데서 관리하면 유지보수가 더 편함
아이템 스폰 개수, 현재 게임 진행도 등과 같은 데이터를 GameState 에서 일괄 관리할 수 있기 때문임
GameState에 점수 데이터 및 함수 추가
전역 점수를 GameState 에 저장 후, 점수를 획득할 때마다 AddScore()를 호출하여 점수가 증가하도록 구현
GameStateBase - 싱글플레이, 복잡하지 않은 게임
GameState - 멀티플레이
C++ Class → GameStateBase 선택 → 이름 설정 (SpartaGameStateBase)

- Score: 현재 누적된 점수
- AddScore(int32 Amount): 점수를 Amount만큼 증가, 최대 점수 제한, 점수 획득 사운드 재생 등을 추가할 수도 있음
- GetScore(): 현 점수 반환, 블루프린트에서 UI를 만들 때도 이 함수를 이용해 쉽게 점수를 가져올 수 있음

GameMode와 GameState 연동
기존에 만들었던 GameMode 클래스에서 GameStateClass 멤버를 SpartaGameState로 설정

SpartaGameStateBase에 대한 C++ 코드가 컴파일 → 언리얼 에디터에서 해당 클래스를 인식하게 됨
SpartaGameStateBase를 더 확장하거나 블루프린트 비주얼 스크립팅을 사용하기 위해,
C++ 클래스를 부모로 하는 블루프린트(BP_SpartaGameStateBase)를 만들어서 사용
Project Settings 적용
Edit → Project Settings → Maps & Modes → Default GameMode
SpartaGameModeBase 또는 그 블루프린트 클래스로 설정
Game State Class → BP_SpartaGameStateBase(또는 SpartaGameStateBase) 로 설정
→ 전역적으로 이 설정이 적용
World Settings에서 설정 (레벨별로 오버라이드 가능)

코인 아이템 점수 획득 함수 수정
GetWorld()->GetGameState<ASpartaGameStateBase>() 로 게임 스테이트를 가져오기
AddScore(PointValue) 함수를 호출해 점수를 올림
PointValue(int32) → 코인 아이템이 제공하는 점수량, ACoinItem의 멤버 변수로 관리
플레이어가 코인을 획득하면, 전역적으로 관리되는 GameState에서 점수가 증가
코인은 사라져서 한 번만 획득되도록 처리

'C++와 Unreal Engine으로 3D 게임 개발' 카테고리의 다른 글
| C++와 Unreal Engine으로 3D 게임 개발 4-1 (0) | 2026.06.23 |
|---|---|
| C++와 Unreal Engine으로 3D 게임 개발 3-5 (0) | 2026.06.22 |
| C++와 Unreal Engine으로 3D 게임 개발 3-3 (0) | 2026.06.20 |
| C++와 Unreal Engine으로 3D 게임 개발 3-2 (0) | 2026.06.19 |
| C++와 Unreal Engine으로 3D 게임 개발 3-1 (0) | 2026.06.18 |