UE5/GameplayTags

[UE5] GE 델리게이트 // 이펙트실행시 함수실행구현, 뷰포트에 디버그찍는법

Mini_96 2024. 6. 3. 02:31

1. InitAbilityInfo 를 게임캐릭Base에 두고, 자식에게 강제구현시킴

virtual void InitAbilityActorInfo();

 

1.5 델리게이트로 MyASC에서 InfoSet를 구현할거임

void UAuraAbilitySystemComponent::AbilityActorInfoSet()
{
	
}

void UAuraAbilitySystemComponent::EffectApplied(UAbilitySystemComponent* AbilitySystemComponent,
                                                const FGameplayEffectSpec& EffectSpec, FActiveGameplayEffectHandle ActiveEffectHandle)
{
	
}

 

2. 자식들(캐릭터, 적)에서 ASC를 내가만든 ASC로 캐스팅시키고,

각각 InfoSet 함수실행

void AAuraEnemy::InitAbilityActorInfo()
{
	// 능력 시스템 컴포넌트를 초기화합니다.
	//첫 번째 this는 능력의 소유자(Owner)를, 두 번째 this는 능력이 적용될 대상(Actor)
	AbilitySystemComponent->InitAbilityActorInfo(this, this);
	Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();
}
// 능력 시스템 액터 정보를 초기화하는 함수
void AAuraCharacter::InitAbilityActorInfo()
{
	...

	Cast<UAuraAbilitySystemComponent>(AuraPlayerState->GetAbilitySystemComponent())->AbilityActorInfoSet();
	
	...
}

※ 이때, ASC는 캐릭터들을 전혀 모름에 주의! // 캐릭터만 ASC에 의존성이 있음.

 

3. AbilitySystemComponent.h에 있는 델리게이트 사용

=> (이미 내부에 선언됨, 변수부에 추가됨, 방송함수 있음)

이펙트가 스스로에게 적용될때, 방송한다고 쓰여있다.

/** Delegate for when an effect is applied */
	DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnGameplayEffectAppliedDelegate, UAbilitySystemComponent*, const FGameplayEffectSpec&, FActiveGameplayEffectHandle);

구독만 해주면됨

void UAuraAbilitySystemComponent::AbilityActorInfoSet()
{
	OnGameplayEffectAppliedDelegateToSelf.AddUObject(this,&UAuraAbilitySystemComponent::EffectApplied);
}

void UAuraAbilitySystemComponent::EffectApplied(UAbilitySystemComponent* AbilitySystemComponent,
                                                const FGameplayEffectSpec& EffectSpec, FActiveGameplayEffectHandle ActiveEffectHandle)
{
	GEngine->AddOnScreenDebugMessage(1,8.f,FColor::Blue,FString("Effect Applied!"));
}

 

※뷰포트에 디버그찍는법

GEngine->AddOnScreenDebugMessage(1,8.f,FColor::Blue,FString("Effect Applied!"));

 

4. 결과

포션등을 먹으면 구독함수가 실행된다.

 

* 델리게이트 공부

1. uclass 클래스 위에서 선언 DECLARE_DELEGATE_파라미터개수(함수이름, 파라미터들) //1개만 바인드가능

DECLARE_MULTICAST_DELEGATE // 여러개 바인드 가능

DECLARE_DYNAMIC_DELEGATE // 블루프린트에서 바인드 가능

ex) DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam : 여러개바인드가능, BP에서 바인드가능, 파라미터1개 // 얘가 만능이긴함

DECLARE_MULTICAST_DELEGATE_TwoParams(FCourseInfoOnChangedSignature, 
const FString&, const FString&);

 

학사정보, 학생은 서로 의존성이 없어야함!

2. 학사정보 변수부에 추가

FCourseInfoOnChangedSignature OnChanged;

3. 학사정보 내부에 델리게이트 넣기, 방송하기

void UCourseInfo::ChangeCourseInfo(const FString& InSchoolName, const FString& InNewContents)
{
	Contents = InNewContents;
	UE_LOG(LogTemp, Log, TEXT("[CourseInfo] 학사 정보가 변경되어 알림을 발송합니다."));
	OnChanged.Broadcast(InSchoolName, Contents);
}

 

4. 구독자(학생)에서 델리게이트의 인자에 맞는 함수선언 // 정보변경시, 아래함수가 실행됨

void UStudent::GetNotification(const FString& School, const FString& NewCourseInfo)
{
	UE_LOG(LogTemp, Log, TEXT("[Student] %s님이 %s로부터 받은 메시지 : %s"), *Name, *School, *NewCourseInfo);
}

5. 중재자(컨트롤러) 는 학사정보, 학생를 참조해야함 (ptr을 가짐)

UCLASS()
class UNREALCOMPOSITION_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
public :
	UMyGameInstance();

	virtual void Init() override;
private :
	UPROPERTY()
	TObjectPtr<class UCourseInfo> CourseInfo;

6. 중재자 내부에서 함수추가, 구독

CourseInfo->OnChanged.AddUObject(Student1, &UStudent::GetNotification);
토탈 코드.
void UMyGameInstance::Init() {
	Super::Init();

	CourseInfo = NewObject<UCourseInfo>(this);
	
	UE_LOG(LogTemp, Log, TEXT("============================="));

	UStudent* Student1 = NewObject<UStudent>();
	Student1->SetName(TEXT("학생1"));
	UStudent* Student2 = NewObject<UStudent>();
	Student2->SetName(TEXT("학생2"));
	UStudent* Student3 = NewObject<UStudent>();
	Student2->SetName(TEXT("학생3"));

	CourseInfo->OnChanged.AddUObject(Student1, &UStudent::GetNotification);
	CourseInfo->OnChanged.AddUObject(Student2, &UStudent::GetNotification);
	CourseInfo->OnChanged.AddUObject(Student3, &UStudent::GetNotification);

	CourseInfo->ChangeCourseInfo(SchoolName, TEXT("변경된 학사 정보"));

	UE_LOG(LogTemp, Log, TEXT("============================="));
}

 

* 예시2)

보스몹 컨트롤러 캐릭터 에서, 보스몹<-> 캐릭터에는 의존성이 없어야함!

보스몹이 데미지를 받는상황

1. 선언

DECLARE_MULTICAST_DELEGATE_OneParams(FBossMonsterDamagedSignature, int32, Damage)
UCLASS()
class RPGSAMPLE_API UBossMonster : public UObject
{
	GENERATED_BODY()
public :
	UBossMonster();

	FBossMonsterDamagedSignature OnDamaged;

2. 보스몹 내부구현, 방송 //파라미터 똑같이

void UBossMonster::GetDamage(int32 Damage) {
	TotalHp -= Damage;
	UE_LOG(LogTemp, Log, TEXT("[BossMonster] 광란의 개발자 김재윤이 화가 나기 시작했습니다!"));
	OnDamaged.BroadCast(Damage);
}

3. 캐릭터에서도 파라미터 똑같이 구현

void URPGCharacter::OnAttack(int32 Damages) {
	UE_LOG(LogTemp, Log, TEXT("[Player] %s에게의 메세지 :  광란의 김재윤이 %d의 데미지를 받았습니다."), *Name, Damages);

4. 컨트롤러에서 보스몹 사용

UCLASS()
class RPGSAMPLE_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
	
public :
	UMyGameInstance();
	virtual void Init() override;
	
private :
	UPROPERTY()
	TObjectPtr<class UBossMonster> BossMonster;

5. 컨트롤러에서 이벤트할당(구독)

	//델리게이트에 이벤트를 할당해주고
	BossMonster->OnDamaged.AddUObject(Archer, &URPGCharacter::OnAttack);
	BossMonster->OnDamaged.AddUObject(Mage, &URPGCharacter::OnAttack);
	BossMonster->OnDamaged.AddUObject(Warrior, &URPGCharacter::OnAttack);

6. 속성변경 시킴

//각 클래스의 캐릭터가 데미지를 주게 될 것이다.
	for (auto Character : Characters) {
		UE_LOG(LogTemp, Log, TEXT("================================"));
		BossMonster->GetDamage(Character->GetDamage());
	}

7. 결과

 

https://github.com/DongHoonYu96/GameplayAbilitySystem_Aura/commit/15d268a5963e07aceb6e313e4d5e26e300fd2983

 

feat : 이펙트실행시 함수실행구현 · DongHoonYu96/GameplayAbilitySystem_Aura@15d268a

Bisu96 committed Jun 2, 2024

github.com