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.