0. 개요

몬스터가 데미지를 입었을 때 그에 대한 몽타주를 재생하도록 한다.

피격 몽타주 출력 중에는 몬스터의 모든 행동이 중단된다.

 

 

1. 피격에 대한 반응 설계

몬스터의 피격 태그를 생성해 해당 태그 상태에서는 몬스터의 어빌리티가 중단되거나 취소되도록 설정할 것이다.

 

 

(1) 게임플레이 이펙트 생성 - GE_HitReact

피격 반응 태그를 부여하는 게임플레이 이펙트를 생성한다.

지속 정책(Duration Policy)는 Infinite이다.

 

 

(2) Native 게임플레이 태그 생성 - AuraGameplayTags

	// 피격
	FGameplayTag Effects_HitReact;
	// 피격
	GameplayTags.Effects_HitReact = UGameplayTagsManager::Get().AddNativeGameplayTag(
		FName("Effects.HitReact"),
		FString("HitReact")
	);
}

 

 

(3) 게임플레이 이펙트 수정 - GE_HitReact

게임플레이 이펙트가 태그를 부여하도록 수정한다.

 

 

2. 몬스터가 태그 변화를 감지하기 - AuraEnemy

델리게이트를 이용하여 몬스터 클래스에서 태그가 변화하는 것을 기다린다.

 

(1) 콜백 함수, 멤버 변수

	void HitReactTagChanged(const FGameplayTag CallbackTag, int32 NewCount);

	UPROPERTY(BlueprintReadOnly, category="Combat")
	bool bHitReacting = false;

	UPROPERTY(BlueprintReadOnly, category = "Combat")
	float BaseWalkSpeed = 250.f;

태그 변화 시 호출할 콜백 함수와 피격 반응을 위한 bHitReacting, 그로 인한 정지를 구현하기 위해 기본 걷기 속도를 정의한다.

 

(2) BeginPlay

void AAuraEnemy::BeginPlay()
{
    Super::BeginPlay();
    GetCharacterMovement()->MaxWalkSpeed = bHitReacting ? 0.f : BaseWalkSpeed;
    InitAbilityActorInfo();
    
    if (UAuraUserWidget* AuraUserWidget = Cast<UAuraUserWidget>(HealthBar->GetUserWidgetObject()))
    {
        AuraUserWidget->SetWidgetController(this);
    }

    if (UAuraAttributeSet* AuraAS = CastChecked<UAuraAttributeSet>(AttributeSet))
    {
        AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AuraAS->GetHealthAttribute()).AddLambda(
            [this](const FOnAttributeChangeData& Data) 
            {
                OnHealthChanged.Broadcast(Data.NewValue);
            }
        );

        AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AuraAS->GetMaxHealthAttribute()).AddLambda(
            [this](const FOnAttributeChangeData& Data)
            {
                OnMaxHealthChanged.Broadcast(Data.NewValue);
            }
        );
        // 델리게이트 - 태그, 태그 갯수
        AbilitySystemComponent->RegisterGameplayTagEvent(FAuraGameplayTags::Get().Effects_HitReact, EGameplayTagEventType::NewOrRemoved).AddUObject(
            this,
            &AAuraEnemy::HitReactTagChanged
        );

        OnHealthChanged.Broadcast(AuraAS->GetHealth());
        OnMaxHealthChanged.Broadcast(AuraAS->GetMaxHealth());
    }
}

캐릭터의 움직임 속도를 처음에 초기화 한다.

RegisterGameplayTagEvent 함수는 특정 태그에 대한 변화를 감지하는 델리게이트를 반환한다.

이 델리게이트는 2개의 파라미터를 반환하며, 한 개는 태그이고 다른 하나는 태그의 갯수이다.

 

해당 함수의 매개 변수는 다음과 같다.

- 감지할 태그

- 태그 이벤트 타입(EGameplayTagEventType)

New Or Removed는 태그가 새롭게 생성되거나 제거되는 순간에 콜백 함수를 호출한다.

다른 옵션으로는 태그가 추가되어 카운트가 올라가거나 내려가는 순간에 콜백 함수를 호출할 수 있다.

 

 

(3) 콜백 함수

void AAuraEnemy::HitReactTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{
    // 태그가 있을 때만 작동
    bHitReacting = NewCount > 0;
    GetCharacterMovement()->MaxWalkSpeed = bHitReacting ? 0.f : BaseWalkSpeed;

}

델리게이트가 반환한 태그와 갯수를 사용하여 태그가 존재할 때 bHitReacting을 True로 만든다.

해당 불리언을 사용하여 잠시 움직이지 못하게하는 코드이다.

 

 

3. HitReact 이펙트를 부여하는 게임플레이 어빌리티

이제 Tag와 결합된 HitReact 이펙트를 부여하는 게임플레이 어빌리티가 필요하다.

 

(1) 게임플레이 어빌리티 생성

 

 

(2) 전투 인터페이스

액터에 따라 몽타주를 출력하기 위해 각 액터가 HitReact 몽타주를 가지고 있게 한다.

이 때 적합한 것은 인터페이스를 활용하는 것이다.

	// 피격 몽타주, C++에서 오버라이드 가능, 블루프린트에서 호출 가능
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	UAnimMontage* GetHitReactMontage();
};

 

 

(3) GetHitReactMontage 함수 오버라이드 - AuraCharacterBase

이제 이 함수를 모든 액터에게서 불러올 수 있도록 Character Base에 구현한다.

public:
	AAuraCharacterBase();

	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const { return AbilitySystemComponent; }
	UAttributeSet* GetAttributeSet() const { return AttributeSet; }

	virtual UAnimMontage* GetHitReactMontage_Implementation() override;
private:
	// 시작 시 활성화되는 어빌리티
	UPROPERTY(EditAnywhere, Category="Abilities")
	TArray<TSubclassOf<UGameplayAbility>> StartupAbilities;

	UPROPERTY(EditAnywhere, Category = "Combat")
	TObjectPtr<UAnimMontage> HitReactMontage;
};
UAnimMontage* AAuraCharacterBase::GetHitReactMontage_Implementation()
{
	return HitReactMontage;
}

 

 

(4) 몬스터 블루프린트에 HitReact 몽타주 할당