添加寒冰技能
GA_Freeze
// 幻雨喜欢小猫咪
#pragma once
#include "CoreMinimal.h"
#include "GAS/Core/CGameplayAbility.h"
#include "GA_Freeze.generated.h"
/**
* 冰冻技能:角色瞄准地面位置释放冰冻效果,对区域内敌人造成伤害
*/
UCLASS()
class UGA_Freeze : public UCGameplayAbility
{
GENERATED_BODY()
public:
UGA_Freeze();
// 激活技能
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
private:
// 目标选择半径(效果作用范围)
UPROPERTY(EditDefaultsOnly, Category = "Targeting")
float TargetingRadius = 1000.f;
// 目标选择距离(最大施法距离)
UPROPERTY(EditDefaultsOnly, Category = "Targeting")
float TargetRange = 2000.f;
// 地面目标选择器类
UPROPERTY(EditDefaultsOnly, Category = "Targeting")
TSubclassOf<class ATargetActor_GroundPick> TargetActorClass;
// 瞄准阶段动画
UPROPERTY(EditDefaultsOnly, Category = "Animation")
TObjectPtr<UAnimMontage> FreezeTargetingMontage;
// 施法阶段动画
UPROPERTY(EditDefaultsOnly, Category = "Animation")
TObjectPtr<UAnimMontage> FreezeCastMontage;
// 伤害效果(冰冻伤害)
UPROPERTY(EditDefaultsOnly, Category = "Effect")
FGenericDamageEffectDef DamageEffect;
// 目标位置视觉提示标签
UPROPERTY(EditDefaultsOnly, Category = "GameplayCue")
FGameplayTag FreezingTargetGameplayCueTag;
// 冰冻效果视觉标签
UPROPERTY(EditDefaultsOnly, Category = "GameplayCue")
FGameplayTag FreezingGameplayCueTag;
// 目标选择完成回调
UFUNCTION()
void TargetReceived(const FGameplayAbilityTargetDataHandle& TargetDataHandle);
// 目标选择取消回调
UFUNCTION()
void TargetingCancelled(const FGameplayAbilityTargetDataHandle& TargetDataHandle);
};
#include "GA_Freeze.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemComponent.h"
#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
#include "Abilities/Tasks/AbilityTask_WaitTargetData.h"
#include "GAS/TA/TargetActor_GroundPick.h"
UGA_Freeze::UGA_Freeze()
{
// 添加瞄准状态标签
ActivationOwnedTags.AddTag(TGameplayTags::Stats_Aim);
}
void UGA_Freeze::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
// 检查网络权限和预测键
if (!HasAuthorityOrPredictionKey(CurrentActorInfo, &CurrentActivationInfo))
{
return;
}
// 任务1:播放瞄准动画(选择目标位置阶段)
UAbilityTask_PlayMontageAndWait* PlayTargetingMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
this,
NAME_None,
FreezeTargetingMontage // 使用瞄准动画
);
// 绑定动画结束事件到能力结束
PlayTargetingMontage->OnBlendOut.AddDynamic(this, &UGA_Freeze::K2_EndAbility);
PlayTargetingMontage->OnCancelled.AddDynamic(this, &UGA_Freeze::K2_EndAbility);
PlayTargetingMontage->OnCompleted.AddDynamic(this, &UGA_Freeze::K2_EndAbility);
PlayTargetingMontage->OnInterrupted.AddDynamic(this, &UGA_Freeze::K2_EndAbility);
PlayTargetingMontage->ReadyForActivation(); // 启动任务
// 任务2:创建目标选择器
UAbilityTask_WaitTargetData* WaitTargetData = UAbilityTask_WaitTargetData::WaitTargetData(
this,
NAME_None,
EGameplayTargetingConfirmation::UserConfirmed, // 需要玩家确认
TargetActorClass
);
// 绑定目标选择完成和取消事件
WaitTargetData->ValidData.AddDynamic(this, &UGA_Freeze::TargetReceived);
WaitTargetData->Cancelled.AddDynamic(this, &UGA_Freeze::TargetingCancelled);
WaitTargetData->ReadyForActivation();
// 生成目标选择器实例
AGameplayAbilityTargetActor* TargetActor;
WaitTargetData->BeginSpawningActor(this, TargetActorClass, TargetActor);
ATargetActor_GroundPick* GroundPickActor = Cast<ATargetActor_GroundPick>(TargetActor);
if (GroundPickActor)
{
// 配置目标选择器参数
GroundPickActor->SetShouldDrawDebug(ShouldDrawDebug()); // 是否显示调试信息
GroundPickActor->SetTargetAreaRadius(TargetingRadius); // 作用半径
GroundPickActor->SetTargetTraceRange(TargetRange); // 最大距离
}
// 完成生成
WaitTargetData->FinishSpawningActor(this, TargetActor);
}
void UGA_Freeze::TargetReceived(const FGameplayAbilityTargetDataHandle& TargetDataHandle)
{
// 提交技能资源(如魔法值消耗)
if (!K2_CommitAbility())
{
K2_EndAbility();
return;
}
// 服务端:应用伤害效果
if (K2_HasAuthority())
{
ApplyDamageToTargetDataHandle(TargetDataHandle, DamageEffect, GetAbilityLevel(CurrentSpecHandle, CurrentActorInfo));
}
// 创建冰冻特效参数
FGameplayCueParameters FreezeCueParameters;
// 从目标数据中获取命中位置作为特效的生成点
FreezeCueParameters.Location = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(TargetDataHandle, 1).ImpactPoint;
// 设置特效规模(使用目标半径)
FreezeCueParameters.RawMagnitude = TargetingRadius;
// 在目标位置播放冰冻特效(所有客户端可见)
GetAbilitySystemComponentFromActorInfo()->ExecuteGameplayCue(FreezingGameplayCueTag, FreezeCueParameters);
// 本地播放施法动画
PlayMontageLocally(FreezeCastMontage);
// 结束技能
K2_EndAbility();
}
void UGA_Freeze::TargetingCancelled(const FGameplayAbilityTargetDataHandle& TargetDataHandle)
{
// 取消目标选择时直接结束技能
K2_EndAbility();
}
添加冷却标签
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Freeze_Cooldown)
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Freeze_Cooldown, "Ability.Freeze.Cooldown", "冻结技能冷却")
添加GC
添加GE
添加到GA中
添加到数据表
添加到角色中