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. 결과
'UE5 > GameplayTags' 카테고리의 다른 글
[UE5] GE태그 방송하기 , 람다함수 (0) | 2024.06.03 |
---|---|
[UE5] 이펙트실행되면, 모든태그가져오기 (0) | 2024.06.03 |
[UE5] GETag 적용 실험 (0) | 2024.06.03 |
[UE5] 게임플레이태그 추가방법들 // 5.3이후 issued (0) | 2024.06.03 |
[UE5] GameplayTags 개념 (0) | 2024.06.02 |