[Unreal_C++_DarkSoul]#8_문제 해결, Send Damage 방식 수정
Weapon 클래스가 Power Component를 통해 피격 대상에게 데미지 전달하는 방식을 수정합니다.
포트폴리오 진행 사항을 기록하기 위한 포스팅입니다.
Overview
- 문제점 고찰 및 해결책 제시
- 결과 코드
문제점
1. Sword.cpp
void ASword::OnCapsuleBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
CheckNull(OtherActor);
AActor* OwnerActor = GetOwner();
CheckNull(OwnerActor);
CheckTrue(OtherActor == OwnerActor);
if (AttackHitActors.Contains(OtherActor) != true)
{
GetPowerComponent()->SendDamge(OwnerActor, OtherActor, IsSkillAttack, SkillBasePower);
AttackHitActors.Add(OtherActor);
}
}
Problems
- 커플링: 각 무기별 충돌 과정에서 피격 대상에게 Damgae를 전달하기 위해 Power Component를 경유합니다.
- Type-Safe: Weapon 클래스는 데미지 전달 동작을 위해 "Power Component" 데이터 타입을 꼭 알아야 합니다.
- 코드 중복: 각 하위 클래스들은 데미지 전달 동작을 위해 #include "PowerComponent.h" 등의 코드가 필수적입니다.
- 유지 보수: Power Component 개발 중 문제가 발생하면, 모든 무기 하위 클래스들에게 영향을 끼칩니다.
Solutions
- Custom Delegate를 활용하여 Weapon 클래스의 데미지 전달 동작을 캡슐화합니다.
- Custom Delegate를 활용하여 보다 범용성이 높은 일반화 프로그래밍이 가능해집니다.
- Custom Delegate를 활용하여 Type-Safety를 보장합니다.
해결
1. Weapon.h
/*****************************************************************************************************************
[Remark]: FourParms -> FiveParams
목적:
Weapon의 피격 과정에서 "Staus Effect", 즉 상태 이상 공격을 추가 구현하기 위해 EAttributeType을 인자로 추가합니다.
설명:
1. FourParms -> FiveParams 로 교체
2. C_PowerComponent 에서 Load하는 Weapon의 Power Information 중 "Attribute(속성)" 또한 Damage 전달 구현에 포함합니다.
*****************************************************************************************************************/
DECLARE_DELEGATE_RetVal_FourParams(bool, FWeaponCollisionBeginOverlap, AActor*, AActor*, bool, float);
class Weapon
{
//...
public:
FWeaponCollisionBeginOverlap OnWeaponCollisionBeginOverlap;
//...
};
Details
- Weapon 클래스 외부에 Custom Delegate를 선언합니다.
- Weapon 클래스 내부에 미리 정의한 Custom Delegate 유형의 멤버를 선언합니다.
2. Sword::OnCapsuleBeginOverlap()
void ASword::OnCapsuleBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
CheckNull(OtherActor);
AActor* OwnerActor = GetOwner();
CheckNull(OwnerActor);
CheckTrue(OtherActor == OwnerActor);
if (AttackHitActors.Contains(OtherActor) != true)
{
if (OnWeaponCollisionBeginOverlap.IsBound())
{
OnWeaponCollisionBeginOverlap.Execute(OwnerActor, OtherActor, IsSkillAttack, SkillBasePower);
AttackHitActors.Add(OtherActor);
}
}
}
Details
- Sword 클래스, Weapon 클래스를 상속하는 하위 클래스들 중 하나를 살펴보겠습니다.
- Power Component를 가져와 노출시키는 것이 아니라, 단순히 커스텀 델리게이트와 바인딩된 함수들을 실행시킵니다.
- 바인딩된 위치가 캡슐화되어 유지보수성 향상을 기대할 수 있겠습니다.
- 다만, 팀 프로젝트에서 다른 팀원들에게 혼란을 줄 수도...?
3. PowerComponent::BeginPlay()
void UC_PowerComponent::BeginPlay()
{
//...
AActor* OwnerActor = GetOwner();
CheckNull(OwnerActor);
Cast<AWeapon>(OwnerActor)->OnWeaponCollisionBeginOverlap.BindUFunction(this, TEXT("SendDamage"));
}
Details
- Weapon 클래스에서 제공하는 델리게이트 함수를 "SendDamage()" 함수와 바인딩을 수행합니다.
'개인프로젝트' 카테고리의 다른 글
[Unreal_C++_DarkSoul]#10_문제 해결, AIController (0) | 2022.12.25 |
---|---|
[Unreal_C++_DarkSoul]#9_기능 구현, Status Effect 기능 (0) | 2022.12.18 |
[Unreal_C++_DarkSoul]#7_문제 해결, Magic Projectile (0) | 2022.12.17 |
[Unreal_C++_DarkSoul]#6_기능 구현, Targeting 기능 (0) | 2022.12.10 |
[Unreal_C++_DarkSoul]#5_기능 구현, Target Point, Enemy Spawn 위치 (0) | 2022.12.10 |