Configuração de Habilidade de Vórtice no Sistema de Habilidade de Gameplay (GAS)

Definição de Identificadores de Tag

Para gerenciar o estado e os efeitos da mecânica de tempestade, é necessário registrar identificadores lógicos específicos dentro do sistema de tags do jogo. Estes servem para controle de tempo de recarga e identificação do tipo de impacto.

// Definição Externa
// Controle de resfriamento para a tempestade
GAMEPLAY_TAG_EXTERN(Ability_Vortex_Recovery)
// Dano aplicado por habilidades padrão
GAMEPLAY_TAG_EXTERN(Damage_Generic_Impact)
// Trigger genérico para seleção de alvo
GAMEPLAY_TAG_EXTERN(Targeting_General_Activation)

A implementação destes marcadores deve ser feita em um arquivo de definição comum, associando descrições legíveis:

GAMEPLAY_TAG_DEFINE_COMMENT(Ability_Vortex_Recovery, "Habilidade.Vortex.Recuperacao")
GAMEPLAY_TAG_DEFINE_COMMENT(Damage_Generic_Impact, "Dano.Generico.Impacto")
GAMEPLAY_TAG_DEFINE_COMMENT(Targeting_General_Activation, "Alvo.Geral.Ativacao")

Estrutura da Classe de Capacidade

A seguir, apresentamos a declaração da classe derivada que controlará o comportamento da invocação do fenômeno meteorológico. Ela herda da capacidade base personalizada e contém parâmetros exponenciáveis no editor.

#pragma once

#include "CoreMinimal.h"
#include "GAS/Core/BaseGameplayAbility.h"
#include "CustomVortexAbility.generated.h"

/**
 * Capacidade de Tempestade Ciclônica: Invoca uma área de efeito que causa 
 * dano contínuo e força de repulsão aos alvos próximos
 */
UCLASS()
class UC_CustomAbility_Vortex : public UBaseGameplayAbility
{
	GENERATED_BODY()

public:
	// Execução principal da habilidade
	virtual void ActivateAbility(const FGameplayAbilitySpecHandle SpecHandle, const FGameplayAbilityActorInfo* OwnerInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerData) override;

private:
	// Parâmetro de Dano Aplicado ao Impacto
	UPROPERTY(EditDefaultsOnly, Category = "Efeito")
	FGenericDamageSetDefinition DamageImpactSet;

	// Força inicial do Empurrão
	UPROPERTY(EditDefaultsOnly, Category = "Fisica")
	float KnockbackForceStrength = 2500.f;

	// Sequência de Animação Associada
	UPROPERTY(EditDefaultsOnly, Category = "Visual")
	TObjectPtr<uanimmontage> StormAnimationSequence;

	// Tempo total de persistência (segundos)
	UPROPERTY(EditDefaultsOnly, Category = "Lógica")
	float DurationTime = 5.0f;

	// Callback para processar eventos de dano detectados
	UFUNCTION()
	void OnImpactEventDetected(FGameplayEventData NotificationPayload);
};
</uanimmontage>

Lógica de Implementação C++

A função de ativação gerencia o ciclo de vida da habilidade, garantindo que recursos sejam comprometidos antes da execução. No lado do servidor, estabelecemos ouvintes para detectar quando o evento de dano ocorre e aplicamos as consequências físicas e numéricas.

#include "CustomVortexAbility.h"
#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
#include "Abilities/Tasks/AbilityTask_WaitCancel.h"
#include "Abilities/Tasks/AbilityTask_WaitGameplayEvent.h"
#include "Abilities/Tasks/AbilityTask_WaitDelay.h"

void UC_CustomAbility_Vortex::ActivateAbility(const FGameplayAbilitySpecHandle SpecHandle, const FGameplayAbilityActorInfo* OwnerInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerData)
{
	// Verifica se é possível comprometer custos e cooldowns
	if (!K2_CommitAbility())
	{
		K2_EndAbility();
		return;
	}

	if (HasAuthorityOrPredictionKey(OwnerInfo, &ActivationInfo))
	{
		// Passo 1: Inicializar Reprodução de Animacão
		UAbilityTask_PlayMontageAndWait* MontageTask = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
			this, 
			NAME_None, 
			StormAnimationSequence
		);
		
		// Subscrição aos estados finais da animação para limpeza segura
		MontageTask->OnBlendOut.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		MontageTask->OnCancelled.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		MontageTask->OnInterrupted.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		MontageTask->OnCompleted.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		MontageTask->ReadyForActivation();

		// Passo 2: Escuta de Eventos de Gameplay (Apenas Autoridade)
		if (K2_HasAuthority())
		{
			UAbilityTask_WaitGameplayEvent* Listener = UAbilityTask_WaitGameplayEvent::WaitGameplayEvent(
				this, 
				TGameplayTags::Damage_Generic_Impact,
				nullptr, 
				false
			);
			Listener->EventReceived.AddDynamic(this, &UC_CustomAbility_Vortex::OnImpactEventDetected);
			Listener->ReadyForActivation();
		}

		// Passo 3: Gestão de Cancelamento Manual
		UAbilityTask_WaitCancel* CancelHandler = UAbilityTask_WaitCancel::WaitCancel(this);
		CancelHandler->OnCancel.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		CancelHandler->ReadyForActivation();

		// Passo 4: Temporizador de Encerramento Automático
		UAbilityTask_WaitDelay* TimerTask = UAbilityTask_WaitDelay::WaitDelay(this, DurationTime);
		TimerTask->OnFinish.AddDynamic(this, &UC_CustomAbility_Vortex::K2_EndAbility);
		TimerTask->ReadyForActivation();
	}
}

void UC_CustomAbility_Vortex::OnImpactEventDetected(FGameplayEventData NotificationPayload)
{
	// Garante execução exclusiva no servidor para dados críticos
	if (K2_HasAuthority())
	{
		const FGameplayAbilityTargetDataHandle& Targets = NotificationPayload.TargetData;
		
		// Aplica a penalização de vida configurada
		ExecuteDamageApplication(Targets, DamageImpactSet, GetAbilityLevel(CurrentSpecHandle, CurrentActorInfo));

		// Executa vetor de empurrão baseado na posição do dono
		ApplyKnockbackToTargets(Targets, KnockbackForceStrength);
	}
}

Integração de Ativos e Dados

Para que a lógica funcione corretamente, a sequência de animações (Montage) deve possuir pelo menos dois slots configurados para suporte a blends espaciais durante o efeito. Além disso, é necessário configurar uma série de Gameplay Effects (GE) responsáveis pela aplicação real dos números de dano e status no estado da personagem.

Os valores de dano e temporização devem ser centralizados em uma Tabela de Dados, permitindo ajustes rápidos sem recompilação. Por fim, a classe criada deve ser instanciada e vinculada à lista de capacidades disponíveis na classe do personagem base.

Tags: UnrealEngine5 GameplayAbilitySystem C++ GAS MOBA

Publicado em 8-19 20:58