캐릭터 데미지 적용

2025. 2. 4. 14:48·내배캠/Unreal Engine

 

 

멀티플레이 환경에서는 PlayerState를 사용해, 서버와 클라이언트 모두 플레이어 간 데이터 동기화를 시킬 수 있다.
아래는 싱글플레이 기준으로 설명할 것이고 동기화가 필요하지 않으므로, 캐릭터 클래스 자체에서 체력을 관리하도록 하였다.

 

📍 데미지 관련 메서드

✅ AActor::TakeDamage

virtual float TakeDamage
(
	float DamageAmount, 
	struct FDamageEvent const& DamageEvent,
	class AController* EventInstigator, 
	AActor* DamageCauser
)
언리얼 엔진에서 기본 데미지 시스템을 사용하는 대표적인 함수이다.
  • DamageAmount: 실제 데미지의 총량을 의미하고, 저항력 및 방어력에 따라 TakeDamage의 float 반환 값은 수정할 수 있다.
  • DamageEvent: 데미지의 구체적 유형과 추가 정보를 담고 있는 구조체이다.
          FDamageEvent는 기본 데미지 정보를 담고 있는 기본 클래스이고 이를 상속하는 다양한 구조체들이 존재한다.
          1. FPointDamageEvent: 특정 시점에서 발생하는 데미지(총알과 같은 명중하는 시점의 데미지)
          2. FRadialDamageEvent: 폭발과 같은 범위 기반의 데미지
더보기
더보기
float ACharacter::TakeDamage
(
	float DamageAmount,
	FDamageEvent const& DamageEvent,
	AController* EventInstigator,
	AActor* DamageCauser
)
{
	// 기본 데미지 적용
	float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	// 체력 감소 처리
	Health -= ActualDamage;
	if (Health <= 0.0f)
	{
		OnDeath();  // 캐릭터 사망 처리 함수
	}

	// 경우에 따라 캐릭터의 방어력, 저항력을 적용해 반환 가능
	return ActualDamage;
}
  • EventInstigator: 데미지를 유발한 플레이어나 AI를 제어하는 컨트롤러를 의미한다.
    데미지의 출처가 누구인지 파악하고, 데미지와 관련된 추가 로직(경험치 부여 등)을 적용할 때 사용된다.
  • DamageCauser: 데미지를 유발한 실제 액터(폭탄, 총알, 화살 등)이다.
    데미지를 유발한 오브젝트에 대한 특수 처리가 필요할 때 사용된다.

 

✅ UGameplayStatics::ApplyDamage

static float ApplyDamage
(
	AActor* DamagedActor,
	float BaseDamage,
	AController* EventInstigator,
	AActor* DamageCauser,
	TSubclassOf<class UDamageType> DamageTypeClass
)
액터에 데미지를 입히는 기능을 제공하는 함수이다.
이 함수를 호출하면 해당 액터의 TakeDamage 함수가 자동으로 호출된다. 따라서 데미지를 처리하는 기본 흐름을 간단하게 구성할 수 있다.
  • DamagedActor: 데미지를 받을 액터를 의미한다.
  • BaseDamage: 데미지의 기본 값을 의미한다.
    이 값은 최종 데미지로 그대로 적용되기도 하고, 추가 로직에 의해 변형될 수 있다.
  • EventInstigator: 데미지를 입힌 컨트롤러를 의미한다.
    데미지를 입힌 주체를 파악할 때 사용된다.
  • DamageCauser: 실제 데미지를 발생시킨 액터를 의미한다.
    예를 들어 플레이어가 적에게 총을 쏜 경우, 총알 액터가 이 DamageCauser가 된다.
  • DamageTypeClass: 데미지의 유형을 정의하는 클래스이다.
    기본적으로 언리얼에 UDamageType이라는 클래스가 있고, 이를 상속하여 커스텀 데미지 타입을 정의할 수 있다.
    예를 들어 폭발 데미지라면 UDamageType을 상속 받는 UExplosionDamageType 커스텀 클래스를 만드는 등.

 


 

📌 PlayerCharacter.h

UCLASS()
class APlayerCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	APlayerCharacter();

	UFUNCTION(BlueprintPure, Category = "Health")
	float GetHealth() const { return Health; }
	UFUNCTION(BlueprintCallable, Category = "Health")
	void AddHealth(float Amount);

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
	float MaxHealth;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
	float Health;

	void OnDeath();

	virtual float TakeDamage(
		float DamageAmount,
		struct FDamageEvent const& DamageEvent,
		AController* EventInstigator,
		AActor* DamageCauser) override;
};

 

📌 PlayerCharacter.cpp

APlayerCharacter::APlayerCharacter()
{
	MaxHealth = 100.0f;
	Health = MaxHealth;
}

void APlayerCharacter::AddHealth(float Amount)
{
	Health = FMath::Clamp(Health + Amount, 0.0f, MaxHealth);
}

void APlayerCharacter::OnDeath()
{
	// 게임 종료 로직
}

float APlayerCharacter::TakeDamage
(	
	float DamageAmount,
	FDamageEvent const& DamageEvent,
	AController* EventInstigator, 
    AActor* DamageCauser
)
{
	float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	Health = FMath::Clamp(Health - DamageAmount, 0.0f, MaxHealth);
	if (Health <= 0.0f)
	{
		OnDeath();
	}
	return ActualDamage;
}

 


 

📌 MineItem.cpp

void AMineItem::Explode()
{
	TArray<AActor*> OverlappingActors;
	ExplosionCollision->GetOverlappingActors(OverlappingActors);

	for (AActor* Actor : OverlappingActors)
	{
		if (Actor && Actor->ActorHasTag("Player"))
		{
			UGameplayStatics::ApplyDamage
            (
				Actor,
				ExplosionDamage,
				nullptr,
				this,
				UDamageType::StaticClass()
			);
		}
	}
	DestroyItem();
}
  • Actor: 오버랩된 대상 액터
  • ExplosionDamage: 폭발 데미지
  • nullptr: Mine액터 자체가 데미지를 입히는 것이기에 EventInstigator 컨트롤러가 없으므로 nullptr 전달
  • this: 데미지를 입히는 주체가 되는 DamageCauser는 Mine 액터이므로 this 전달
  • UDamageType::StaticClass(): 기본 데미지 타입 전달

'내배캠 > Unreal Engine' 카테고리의 다른 글

UI 위젯 설계와 실시간 데이터 연동  (0) 2025.02.06
Game State와 Game Mode  (0) 2025.02.04
가비지 컬렉션과 메모리 관리  (0) 2025.01.31
Pawn에 Possess 하기  (0) 2025.01.31
데이터 에셋과 데이터 테이블  (0) 2025.01.28
'내배캠/Unreal Engine' 카테고리의 다른 글
  • UI 위젯 설계와 실시간 데이터 연동
  • Game State와 Game Mode
  • 가비지 컬렉션과 메모리 관리
  • Pawn에 Possess 하기
동그래님
동그래님
  • 동그래님
    개발자 동그래
    동그래님
  • 전체
    오늘
    어제
    • 분류 전체보기 (210)
      • 공부 (51)
        • Code Cata (50)
      • 내배캠 (151)
        • TIL (50)
        • C++ (37)
        • Unreal Engine (48)
        • GAS(Gameplay Ability System.. (16)
      • Project (7)
        • Gunfire Paragon (5)
        • Arena Fighters (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    동그래님
    캐릭터 데미지 적용
    상단으로

    티스토리툴바