UGamePlayStatics::ApplyDamage()
(데미지 입히기)와 AActor:TakeDamage()
(데미지 처리) 함수가 제공됨ApplyDamage() -> TakeDamage()
UGamePlayStatics::ApplyDamage()
TakeDamage()
함수를 호출하려 시도AActor::TakeDamage()
ApplyDamage()
함수를 호출해서 TakeDamage()
가 실행되도록 하면 됨.// MineItem.cpp
// 지뢰 아이템 폭발 함수
void AMineItem::Explode()
{
TArray<AActor*> OverlappingActors;
ExplosionCollision->GetOverlappingActors(OverlappingActors);
for (AActor* Actor : OverlappingActors)
{
if (Actor && Actor->ActorHasTag("Player"))
{
// 데미지를 발생시켜 Actor->TakeDamage()가 실행되도록 함
UGameplayStatics::ApplyDamage(
Actor, // 데미지를 맞을 주체
ExplosionDamage, // 데미지 양
nullptr, // 데미지 유발 주체 - TakeDamge와 동일
this, // 데미지를 준 객체
UDamageType::StaticClass() // 기본 데미지
);
}
}
DestroyItem();
}
AActor* DamagedActor
: 데미지를 받을 대상 액터float BaseDamage
: 데미지 양AController* EventInstigator
: 데미지를 유발한 주체Controller
가 없어서 nullptr
을 넣어줌.AActor* DamageCauser
: 데미지를 유발한 오브젝트/액터 (지뢰)TSubclassOf<UDamageType> DamageTypeClass
: 기본 데미지 유형TakeDamage()
함수를 호출DamageType
은 여러가지 파생 클래스를 만들어 물리/화염/독 등 다양한 데미지 유형을 정의할 수 있음.// Cp2Character.cpp
// 데미지 처리 함수
float Cp2Character::TakeDamage(
float DamageAmount,
FDamageEvent const& DamageEvent,
AController* EventInstigator,
AActor* DamageCauser)
{
// 기본 데미지 처리 로직 호출 (필수는 아님)
float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
// 체력을 데미지만큼 감소시키고, 0 이하로 떨어지지 않도록 Clamp
Health = FMath::Clamp(Health - DamageAmount, 0.0f, MaxHealth);
// 체력이 0 이하가 되면 사망 처리
if (Health <= 0.0f)
{
OnDeath();
}
return ActualDamage; // 실제 적용된 데미지를 반환
}
float DamageAmount
: 데미지 값FDamageEvent const& DamageEvent
: 데미지를 받은 유형. AController* EventInstigator
: 데미지를 유발한 주체(Controller)AActor* DamageCauser
: 데미지를 직접적으로 발생시킨 오브젝트/액터 (무기, 폭발물 등등)return float
: 실제 적용된 데미지DamageAmount
와 동일한 경우가 많으나, 실제 게임 상황에 따라GameMode
와 GameState
는 게임의 전역 정보를 유지.GameState
가 존재.GameState
가 굳이 필요없을 것 같지만,GameState
에 스폰된 아이템 갯수 변수를 관리GameMode
또는 스폰 시스템에서 더 이상 스폰하지 않도록 로직 적용.이처럼 전역적으로 공유되어야 하는 데이터는
GameState
에 넣고
게임 규칙이나 흐름을 제어하는 로직은GameMode
또는 별도의 매니저 클래스로 분리하는 것이 일반적.