[Unreal_C++_DarkSoul]#9_Status Effect
Weapon의 Skill 공격 시 고유의 Attribute와 매치되는 상태 이상 효과를 구현합니다
Unreal 포트폴리오 작업 과정을 기록합니다.
Overview
- 개요
- 설계
- 상세 내용
- 게임 플레이 화면
개요
1. 상태 이상 효과
- 각 Weapon은 고유의 Attribute(속성)을 갖도록 합니다.
- 그리고, 각 Attribute는 Weapon의 스킬 공격 시 피격 대상에게 물리 대미지뿐만 아니라, 특별한 상태 이상 효과를 유발합니다.
- 예를 들면, 불 속성의 무기는 특정 스킬 공격 시 피격 대상에게 물리 데미지 뿐만 아니라, DoT 데미지를 전달하는 "화상" 효과를 유발합니다.
- 총 5가지 상태 이상 효과를 구현합니다.
- "Burn(화상)", "Frozen(스턴)", "Threat(공포)", "Electric Shock(스턴)", 그리고 "Debuff(방어력 감소)"
설계
1. 설계
- Damage Type 클래스 선언 및 정의
- Status Effect 클래스 선언 및 정의
- Heatlh Component와 Damage Type 클래스가 공통으로 활용할 인터페이스 클래스 구현
Details
- Damage Type 클래스는 Weapon이 피격 대상에게 전달하는 대미지에 대한 정보를 담고 있습니다.
- 각 Damage Type 클래스는 고유의 상태 이상 효과(Status Effect)를 유발합니다.
- 그리고, 각 "상태 이상 효과"는 활성화 시 주어진 고정 시간 동안 피격 대상에게 특별한 대미지를 전달합니다.
- 피격 대상의 Health Component는 전달 받은 Damage Type 클래스를 통해 상태 이상 효과 유발 여부를 확인.
상세 코드
1. Custom_Enums.h
//...
UENUM(BlueprintType)
enum class EAttributeType : uint8
{
E_Fire = 0 UMETA(DisplayName = "Fire"),
E_Ice UMETA(DisplayName = "Ice"),
E_Electric UMETA(DisplayName = "Electric"),
E_Dark UMETA(DisplayName = "Dark"),
E_Steel UMETA(DisplayName = "Steel"),
E_Max UMETA(DisplayName = "Max"),
};
//...
Details
- 앞으로 구현할 상태 이상 효과 클래스마다 갖는 고유의 속성 값을 정의하기 위해 속성 열거형을 정의합니다.
- Damage Type 클래스와 Status Effect 클래스를 연결할 매개체로 활용됩니다.
2. DamageTypeHealthInterface.cpp
/* ********************************************************************************************************
[Remark]: Add UFUNCTION() Reflection On Unreal Editor Makes Error
목적:
"C_HealthComponent" 객체의 포인터를 "참조형"으로 인자를 넘겨 받아 "Out Parameter"로 활용하고자 합니다.
설명:
1. UFUNCTION()을 작성하면, Out Parameter로 받을 시 Log(Missing '*' in Expected a pointer type)가 발생합니다.
2. UFUNCTION()을 지우니까, 에러가 발생하지 않는 특이한 점을 발견합니다.
*********************************************************************************************************/
public:
virtual void TriggerStatusEffect(class UC_HealthComponent* OutComp) = 0;
Details
- Health Component와 Damage Type이 공통으로 상속하는 인터페이스 클래스를 생성합니다.
- "TriggerStatusEffect()" 순수 가상 함수를 선언합니다.
- 이후, Damage Type 클래스에서 "TriggerStatusEffect()" 가상 함수를 오버 라이딩합니다.
3. DT_Burn.cpp
void UDT_Burn::TriggerStatusEffect(UC_HealthComponent* OutComp)
{
OutComp->TriggerStatusEffect(EAttributeType::E_Fire);
}
4. DT_Frozen.cpp
void UDT_Frozen::TriggerStatusEffect(UC_HealthComponent* OutComp)
{
OutComp->TriggerStatusEffect(EAttributeType::E_Ice);
}
Details
- Weapon이 전달한 Damage Type 클래스는 피격 대상의 Health Component를 인자로 받아 하여금 알맞은 상태 이상 효과를 유발합니다.
- 눈여겨볼 점은 각 대미지 타입 클래스는 각각 다른 EAttributeType을 HealthComponent의 "TriggetStatusEffect()" 함수에 전달하고 있습니다!
- 따라서, Damage 관련 이벤트가 발생하면, 피격 대상의 Health Component에게 전달된 각기 다른 Damage Type 클래스로 하여금 각기 다른 상태 이상 효과를 유발하도록 합니다.
5. SE_Burn::StartActivation()
void ASE_Burn::StartActivation()
{
Super::StartActivation();
AActor* AttachActor = GetOwner();
CheckNull(AttachActor);
// Timer
FTimerDelegate TimerDelegate = FTimerDelegate::CreateUObject(this, &ASE_Burn::SendDamage, AttachActor );
GetWorldTimerManager().SetTimer(TimerHandler, TimerDelegate, DamageRate, true);
}
6. SE_Frozen::StartActivation()
void ASE_Frozen::StartActivation()
{
Super::StartActivation();
AActor* AttachActor = GetOwner();
CheckNull(AttachActor);
ACharacter* AttachCharacter = Cast<ACharacter>(AttachActor);
CheckNull(AttachCharacter);
// 1. Change Material
ChangeMaterialFrozen(&AttachCharacter);
// 2. Stop Movement
StopCharacterMovement(&AttachActor);
// 3. Timer For End Activation
GetWorld()->GetTimerManager().SetTimer(TimerHandler, this, &ASE_Frozen::EndActivation, DamageRate, false);
}
Details
- 상태 이상 효과는 크게 두 가지 카테고리를 가집니다 - DoT, 스턴, 그리고 Debuff
- 각 상태 이상 효과 클래스는 기본적으로 3가지 패턴을 통해 피격 대상에게 상태 이상 효과를 유발하고, 세부적으로 특별한 Particle을 화면에 렌더링 합니다.
7. HealthComponent::TriggerStatusEffect()
void UC_HealthComponent::TriggerStatusEffect(EAttributeType InAttributeType)
{
CheckFalse(StatusEffectClasses.IsValidIndex((int32)InAttributeType));
AActor* OwnerActor = GetOwner();
CheckNull(OwnerActor);
AGameObject* OwnerObject = Cast<AGameObject>(OwnerActor);
CheckNull(OwnerObject);
StatusEffect = GetWorld()->SpawnActor<AStatusEffect>(StatusEffectClasses[((int32)InAttributeType)]);
StatusEffect->SetOwner(OwnerObject);
StatusEffect->AttachComponentToOwnerComponent(OwnerObject->GetMesh());
StatusEffect->StartActivation();
}
Details
- Health Component는 인자로 전달받은 속성 값을 통해 미리 갖고 있는 상태 이상 효과 클래스들의 목록을 탐색하여 알맞은 상태 이상 효과를 활성화시킵니다.
게임 플레이 화면
'개인프로젝트' 카테고리의 다른 글
[Unreal_C++_DarkSoul]#11_기능 구현, Parkour(Vaulting) (0) | 2022.12.25 |
---|---|
[Unreal_C++_DarkSoul]#10_문제 해결, AIController (0) | 2022.12.25 |
[Unreal_C++_DarkSoul]#8_문제 해결, Send Damage 방식 수정 (0) | 2022.12.18 |
[Unreal_C++_DarkSoul]#7_문제 해결, Magic Projectile (0) | 2022.12.17 |
[Unreal_C++_DarkSoul]#6_기능 구현, Targeting 기능 (0) | 2022.12.10 |