...
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOutOfHealthDeleget);
UCLASS()
class ARENABATTLEGAS_API UABCharacterAttributeSet : public UAttributeSet
{
...
UPROPERTY()
mutable FOutOfHealthDeleget OnOutOfHealth;
...
bool bOutOfHealth = false;
};
UABCharacterAttributeSet에 다음과 같이 Delegate를 선언하고 이미 한번 죽었는지 체크하는 bOutOfHealth를 추가한다.
여기서 mutable이 선언자가 있는데 mutable은 const 객체 안에서도 해당 변수는 수정이 가능하다는 의미이다.
이는 ASC->GetSet을 통해서 AttributeSet을 들고오면 const로 들고오게 된다.
이때 const로 되어있으면 Delegate 구독도 할 수 없기 때문에 mutable을 사용하여 구독(수정)이 가능하도록 한다.
void UABCharacterAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
//여기서 Data는 Effect로 인해서 변화된 데이터이다.
Super::PostGameplayEffectExecute(Data);
float MinimumHealth = 0.0f;
//Health에 직접 접은은 불가능
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
{
GAS_LOG(LogABGAS, Warning, TEXT("Direct Health Access : %f"), GetHealth());
SetHealth(FMath::Clamp(GetHealth(), MinimumHealth, GetMaxHealth()));
}
//데미지를 통한 접근 가능.
else if (Data.EvaluatedData.Attribute == GetDamageAttribute())
{
GAS_LOG(LogABGAS, Log, TEXT("Damage : %f"), GetDamage());
SetHealth(FMath::Clamp(GetHealth()- GetDamage(), MinimumHealth, GetMaxHealth()));
SetDamage(0.0f);
}
if ((GetHealth() <= 0.0f) && !bOutOfHealth)
{
//Character.State.IsDead라는 태그를 직접 부착하는 방식이다.
Data.Target.AddLooseGameplayTag(ABTAG_CHARACTER_ISDEAD);
OnOutOfHealth.Broadcast();
}
bOutOfHealth = (GetHealth() <= 0.0f);
}
그리고 Health를 처리하는 PostGameplayEffectExecute에서 사망했는지 확인하고
AddLooseGameplayTag를 통해 사망태그 (Character.State.IsDead)를 추가해준다.
그리고 Delegate를 Broadcast한다.
//NPC
AttributeSet->OnOutOfHealth.AddDynamic(this, &AABGASCharacterNonPlayer::OnOutOfHealth);
-----------------------------------------------------------
//Player
//PlayerState에서 ASC를 들고와서 PlayerState에 있는 ASC를 Player 캐릭터 ASC에 넣어준다.
ASC = GASPS->GetAbilitySystemComponent();
//위 단계에서 OwnerActor는 PlayerState로 AvatarActor는 Player 캐릭터로 정해졌다.
//이제 ASC 초기화를 해주면 된다.
//첫번째 인자는 OwnerActor, 두번째 인자는 AvatarActor를 넣어주면 된다.
ASC->InitAbilityActorInfo(GASPS, this);
const UABCharacterAttributeSet* CurrentAttributeSet = ASC->GetSet<UABCharacterAttributeSet>();
if (CurrentAttributeSet)
{
CurrentAttributeSet->OnOutOfHealth.AddDynamic(this, &ThisClass::OnOutOfHealth);
}
NPC는 직접 AttributeSet을 들고 있기 때문에 GetSet을 할 필요 없이 직접 Bind하면 되고
Player는 PlayerState가 ASC를 가지고 있기 때문에
PlayerState에서 ASC를 가져와 캐싱을 하고 해당 ASC에서 GetSet을 통해 AttributeSet을 가져온 후에
OnOutOfHealth와 바인딩하여 사망 처리를 한다.
'Unreal 게임 개발 > Unreal 강의 개인 정리' 카테고리의 다른 글
| 게임플레이 큐 & 공격 파티클 재생 - GAS (2) | 2025.08.27 |
|---|---|
| 기간형 게임플레이 이펙트 & 무적 구현 & 스택형 버프 - GAS (3) | 2025.08.26 |
| Attribute Set UI로 표시 - GAS (0) | 2025.08.25 |
| EffectContext & Spec Handle / 캐릭터 레벨 스탯 변화 - GAS (0) | 2025.08.25 |
| 레벨과 커브 테이블 & 연속 공격 공격력 변화 - GAS (2) | 2025.08.25 |