UE5多人MOBA+GAS 48、制作闪现技能

文章目录


添加标签

cpp 复制代码
	CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Teleport)
	CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Cooldown)
cpp 复制代码
	UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Blink_Teleport, "Ability.Blink.Teleport", "闪烁技能")
	UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Blink_Cooldown, "Ability.Blink.Cooldown", "闪烁技能冷却")
cpp 复制代码
#pragma once

#include "CoreMinimal.h"
#include "GAS/Core/CGameplayAbility.h"
#include "GA_Blink.generated.h"

/**
 * 闪烁技能:角色选择目标位置进行传送,落地时对周围敌人造成伤害和击退
 */
UCLASS()
class CRUNCH_API UGA_Blink : public UCGameplayAbility
{
	GENERATED_BODY()
public:
	UGA_Blink();
	// 激活技能
	virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;

private:
	// 瞄准阶段动画(选择目标位置)
	UPROPERTY(EditDefaultsOnly, Category = "Anim")
	TObjectPtr<UAnimMontage> TargetingMontage;

	// 传送阶段动画
	UPROPERTY(EditDefaultsOnly, Category = "Anim")
	TObjectPtr<UAnimMontage> TeleportMontage;


	// 地面目标选择器类
	UPROPERTY(EditDefaultsOnly, Category = "Targeting")
	TSubclassOf<class ATargetActor_GroundPick> GroundPickTargetActorClass;

	// 落地伤害效果
	UPROPERTY(EditDefaultsOnly, Category = "Effect")
	FGenericDamageEffectDef DamageEffect;

	// 落地击退速度
	UPROPERTY(EditDefaultsOnly, Category = "Effect")
	float BlinkLandTargetPushSpeed = 5000.f;

	// 落地作用范围半径
	UPROPERTY(EditDefaultsOnly, Category = "Targeting")
	float TargetAreaRadius = 1000;

	// 最大闪烁距离
	UPROPERTY(EditDefaultsOnly, Category = "Targeting")
	float BlinkCastRange = 3000.f;

	// 目标选择完成回调
	UFUNCTION()
	void GroundPickTargetReceived(const FGameplayAbilityTargetDataHandle& TargetDataHandle);

	// 目标选择取消回调
	UFUNCTION()
	void GroundPickCancelled(const FGameplayAbilityTargetDataHandle& TargetDataHandle);

	// 传送事件回调(由动画事件触发)
	UFUNCTION()
	void Teleport(FGameplayEventData Payload);

	// 缓存的目标位置数据
	FGameplayAbilityTargetDataHandle BlinkTargetDataHandle;
};
cpp 复制代码
#include "GA_Blink.h"

#include "AbilitySystemBlueprintLibrary.h"
#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
#include "Abilities/Tasks/AbilityTask_WaitGameplayEvent.h"
#include "Abilities/Tasks/AbilityTask_WaitTargetData.h"
#include "GAS/TA/TargetActor_GroundPick.h"
// #include "Abilities/Tasks/AbilityTask_ApplyRootMotionMoveToForce.h"

UGA_Blink::UGA_Blink()
{
	ActivationOwnedTags.AddTag(TGameplayTags::Stats_Aim);
}

void UGA_Blink::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
	const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	// 检查网络权限和预测键
	if (!HasAuthorityOrPredictionKey(ActorInfo, &ActivationInfo))
	{
		K2_EndAbility();
		return;
	}

	// 任务1:播放瞄准动画
	UAbilityTask_PlayMontageAndWait* PlayTargetingMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
		this, 
		NAME_None, 
		TargetingMontage
	);
	PlayTargetingMontage->ReadyForActivation();

	// 任务2:创建目标选择器
	UAbilityTask_WaitTargetData* WaitBlinkLocationTargetData = UAbilityTask_WaitTargetData::WaitTargetData(
		this, 
		NAME_None, 
		EGameplayTargetingConfirmation::UserConfirmed, // 需要玩家确认
		GroundPickTargetActorClass
	);
	// 绑定目标选择完成和取消事件
	WaitBlinkLocationTargetData->ValidData.AddDynamic(this, &UGA_Blink::GroundPickTargetReceived);
	WaitBlinkLocationTargetData->Cancelled.AddDynamic(this, &UGA_Blink::GroundPickCancelled);
	WaitBlinkLocationTargetData->ReadyForActivation();

	// 生成目标选择器实例
	AGameplayAbilityTargetActor* TargetActor;
	WaitBlinkLocationTargetData->BeginSpawningActor(this, GroundPickTargetActorClass, TargetActor);
	ATargetActor_GroundPick* GroundPickTargetActor = Cast<ATargetActor_GroundPick>(TargetActor);
	if (GroundPickTargetActor)
	{
		// 配置目标选择器参数
		GroundPickTargetActor->SetShouldDrawDebug(ShouldDrawDebug()); // 是否显示调试信息
		GroundPickTargetActor->SetTargetAreaRadius(TargetAreaRadius); // 作用半径
		GroundPickTargetActor->SetTargetTraceRange(BlinkCastRange);   // 最大距离
	}

	// 完成生成
	WaitBlinkLocationTargetData->FinishSpawningActor(this, TargetActor);
}

void UGA_Blink::GroundPickTargetReceived(const FGameplayAbilityTargetDataHandle& TargetDataHandle)
{
	// 提交技能资源(如魔法值消耗)
	if (!K2_CommitAbility())
	{
		K2_EndAbility();
		return;
	}
	// 缓存目标位置数据(传送完成后造成伤害用)
	BlinkTargetDataHandle = TargetDataHandle;

	// 确保在服务端或预测有效时执行
	if (HasAuthorityOrPredictionKey(CurrentActorInfo, &CurrentActivationInfo))
	{
		// 任务3:播放传送动画
		UAbilityTask_PlayMontageAndWait* PlayTeleportMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
			this, 
			NAME_None, 
			TeleportMontage
		);
		// 绑定动画结束事件到能力结束
		PlayTeleportMontage->OnBlendOut.AddDynamic(this, &UGA_Blink::K2_EndAbility);
		PlayTeleportMontage->OnCancelled.AddDynamic(this, &UGA_Blink::K2_EndAbility);
		PlayTeleportMontage->OnInterrupted.AddDynamic(this, &UGA_Blink::K2_EndAbility);
		PlayTeleportMontage->OnCompleted.AddDynamic(this, &UGA_Blink::K2_EndAbility);
		PlayTeleportMontage->ReadyForActivation();
		
		// 任务4:在服务端监听传送事件(动画通知触发)
		if (K2_HasAuthority())
		{
			UAbilityTask_WaitGameplayEvent* WaitTeleportTimePoint = UAbilityTask_WaitGameplayEvent::WaitGameplayEvent(
				this, 
				TGameplayTags::Ability_Blink_Teleport
			);
			// 绑定传送事件回调
			WaitTeleportTimePoint->EventReceived.AddDynamic(this, &UGA_Blink::Teleport);
			WaitTeleportTimePoint->ReadyForActivation();
		}
	}
}

void UGA_Blink::GroundPickCancelled(const FGameplayAbilityTargetDataHandle& TargetDataHandle)
{
	K2_EndAbility();
}

void UGA_Blink::Teleport(FGameplayEventData Payload)
{
	if (K2_HasAuthority())
	{
		// 从目标数据获取选择的传送位置
		FHitResult PickedLocationHitResult = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(BlinkTargetDataHandle, 1);
		FVector PickedTeleportLocation = PickedLocationHitResult.ImpactPoint;

		// 将角色传送到目标位置
		GetAvatarActorFromActorInfo()->SetActorLocation(PickedTeleportLocation);

		// 对落点范围内的目标应用伤害效果
		ApplyDamageToTargetDataHandle(
			BlinkTargetDataHandle, 
			DamageEffect, 
			GetAbilityLevel(CurrentSpecHandle, CurrentActorInfo)
			);
		
		// 击退目标
		PushTargetsFromOwnerLocation(BlinkTargetDataHandle, BlinkLandTargetPushSpeed);
	}
}

位移的时候加一个动画通知



把技能添加到角色上

这样技能就齐全了

相关推荐
Zhichao_974 天前
【UE5.8】VS2026安装
ue5
DolitD5 天前
UE像素流与云渲染技术方案对比分析
3d·云原生·ue5·云计算·图形渲染
Дерек的学习记录6 天前
Unreal Engine 5:第三人称运动系统和人物动画
开发语言·学习·ue5
努力学习的小廉9 天前
UE5 入门系列(三):核心框架类全解析
ue5
平行云10 天前
建筑BIM/3D可视化轻量级实时评审与分享方案
unity·ue5·3dsmax·实时云渲染·云桌面·云游戏·建筑bim
BugPhysician15 天前
影之刃零首发UE崩溃排查:着色器缓存、虚拟内存与驱动版本
ue5·影之刃零·影之刃零报错·影之刃零进不去·ue崩溃·ue引擎崩溃·ue5引擎崩溃
电子云与长程纠缠17 天前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
fanfan_hongyun17 天前
UE5.1 蓝图调用C++方法
ue5
易知微EasyV数据可视化17 天前
UE5 中接入 GDAL:从vcpkg编译到插件打包
ue5
努力学习的小廉17 天前
UE5入门系列(一):环境搭建.md
ue5