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

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



把技能添加到角色上

这样技能就齐全了

相关推荐
远离UE43 小时前
UE5 SF_VertexShader 如何使用
ue5
电子云与长程纠缠6 小时前
UE5 Lyra PocketWorld进行3D内容UI预览 - 上
开发语言·学习·3d·ue5·游戏引擎
电子云与长程纠缠8 小时前
UE5 Lyra PocketWorld进行3D内容UI预览 - 下
开发语言·学习·游戏·ui·ue5
远离UE41 天前
UE5 GPU内部异步
ue5
1204157137 肖哥1 天前
UE5 PCG PCGBlueprintElement简介
ue5
dong1326971 天前
UE5FPS游戏开发教程(四)
ue5
dong1326972 天前
UE5FPS游戏开发教程(三)
ue5
日月云棠2 天前
UE5源码分析之Editor——AnimationBlueprintLibrary模块全面分析
ue5
远离UE42 天前
UE5 ECS 原理
ue5
mengzhi啊4 天前
UE5 把剑绑定到骨骼-给要播放的动画及动画蒙太奇添加武器
ue5