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);
	}
}

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



把技能添加到角色上

这样技能就齐全了

相关推荐
avi91114 小时前
Unreal虚幻粒子系统二三事
ue5·虚幻引擎·unreal
一梦、んんん14 小时前
UE 雷达干扰效果模拟
ue5
玉龙20251 天前
虚幻引擎|UE5制作DeepSeek插件并打包发布
ue5·游戏引擎·虚幻·虚幻引擎基础入门·=学习·虚幻引擎插件
努力的小钟1 天前
Unreal Engine GameplayTag匹配功能详解
ue5
司徒法克1 天前
ue编辑器视口鼠标消失的问题
ue5
CandyU21 天前
UE5 小知识点 —— 09 - 旋转小问题
ue5
AA陈超2 天前
虚幻引擎UE5专用服务器游戏开发-21 连招技能动画蒙太奇播放
c++·游戏·ue5·游戏引擎·虚幻
FlyingMindIndex04 天前
UE_ContrlRig
ue5·ue4
玉龙20254 天前
使用虚幻引擎(UE5)制作开箱爆金币功能
microsoft·ue5·虚幻·虚幻引擎教程·中文教程
HELLOMILI5 天前
[UnrealEngine] 虚幻引擎UE5下载及安装(UE4、UE5)
游戏·ue5·游戏引擎·ue4·虚幻·软件需求