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

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



把技能添加到角色上

这样技能就齐全了

相关推荐
幻雨様3 小时前
UE5多人MOBA+GAS 43、制作激光技能
ue5
ue星空3 天前
UE5配置MRQ编解码器输出MP4视频
ue5·音视频
吴梓穆9 天前
UE5 图片9宫格切割
ue5
Kingsdesigner10 天前
游戏开发流程革命:我用Substance插件,在UE5内实现材质的实时“创世纪”
游戏·adobe·ue5·游戏引擎·游戏开发·设计师·substance 3d
幻雨様12 天前
UE5多人MOBA+GAS 37、库存系统(四)
ue5
DoomGT12 天前
Physics Simulation - UE中Projectile相关事项
ue5·游戏引擎·虚幻·虚幻引擎·unreal engine
右弦GISer14 天前
【UE5医学影像可视化】读取本地Dicom生成VolumeTexture,实现2D显示和自动翻页
ue5·dicom·医学图像
小梦白14 天前
RPG增容3:尝试使用MVC结构搭建玩家升级UI(一)
游戏·ui·ue5·mvc
AgilityBaby14 天前
解决「CPU Virtualization Technology 未开启或被占用」弹窗问题
ue5·游戏引擎·无畏契约·cpu 虚拟化技术