UE5多人MOBA+GAS 19、创建升龙技能,以及带力的被动,为升龙技能添加冷却和消耗

文章目录


创建升龙拳的Tag以及受力被动的Tag

给这个技能添加标签

cpp 复制代码
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Uppercut_Launch)
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Passive_Launch_Activate)
cpp 复制代码
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Uppercut_Launch, "Ability.Uppercut.Launch", "升龙拳攻击")
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Passive_Launch_Activate, "Ability.Passive.Launch.Activate", "击飞被动技能激活")

CGameplayAbility中添加绘制Debug的布尔变量(暂时对我没的没什么用)

cpp 复制代码
	UFUNCTION()
	FORCEINLINE bool ShouldDrawDebug() const { return bShouldDrawDebug; }
private:
	UPROPERTY(EditDefaultsOnly, Category = "Debug")
	bool bShouldDrawDebug = false;

创建升龙技能

添加上勾拳(升龙拳)技能,命名为UpperCut

cpp 复制代码
// 幻雨喜欢小猫咪

#pragma once

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

/**
 * 
 */
UCLASS()
class CRUNCH_API UUpperCut : public UCGameplayAbility
{
	GENERATED_BODY()
public:	
	// 激活技能时调用
	virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
private:
	// 上勾拳动画Montage
	UPROPERTY(EditDefaultsOnly, Category = "Animation")
	TObjectPtr<UAnimMontage> UpperCutMontage;
	
	// 启动击飞效果
	UFUNCTION()
	void StartLaunching(FGameplayEventData EventData);
};
cpp 复制代码
// 幻雨喜欢小猫咪


#include "UpperCut.h"

#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"

void UUpperCut::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
                                const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	if (!K2_CommitAbility())
	{
		K2_EndAbility();
		return;
	}
	// 服务器执行
	if (HasAuthorityOrPredictionKey(ActorInfo, &ActivationInfo))
	{
		UAbilityTask_PlayMontageAndWait* PlayUpperCutMontageTask = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, NAME_None, UpperCutMontage);
		PlayUpperCutMontageTask->OnBlendOut.AddDynamic(this, &UUpperCut::K2_EndAbility);
		PlayUpperCutMontageTask->OnCancelled.AddDynamic(this, &UUpperCut::K2_EndAbility);
		PlayUpperCutMontageTask->OnCompleted.AddDynamic(this, &UUpperCut::K2_EndAbility);
		PlayUpperCutMontageTask->OnInterrupted.AddDynamic(this, &UUpperCut::K2_EndAbility);
		PlayUpperCutMontageTask->ReadyForActivation();
		
		UAbilityTask_WaitGameplayEvent* WaitLaunchEventTask = UAbilityTask_WaitGameplayEvent::WaitGameplayEvent(this, TGameplayTags::Ability_Uppercut_Launch);
		WaitLaunchEventTask->EventReceived.AddDynamic(this, &UUpperCut::StartLaunching);
		WaitLaunchEventTask->ReadyForActivation();
	}
}

void UUpperCut::StartLaunching(FGameplayEventData EventData)
{
	if (K2_HasAuthority())
	{
		// 获取命中目标的数量
		int32 HitResultCount = UAbilitySystemBlueprintLibrary::GetDataCountFromTargetData(EventData.TargetData);
	
		for (int32 i = 0; i < HitResultCount; ++i)
		{
			// 获取每个命中的HitResult
			FHitResult HitResult = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(EventData.TargetData, i);
			UE_LOG(LogTemp, Warning, TEXT("HitActorName:  %s"), *HitResult.GetActor()->GetName())
		}
	}
}

将升龙技能添加到角色中

蓝图继承并创建

直接复制基础攻击增加一个技能一

添加到映射中

将技能添加到角色中

创建一个击飞被动,供升龙激活技能

添加一个新的类GAP_Launched,作为击飞的被动技能

cpp 复制代码
// 幻雨喜欢小猫咪

#pragma once

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

/**
 * 被击飞能力类
 * 用于处理角色被击飞时的特殊能力逻辑
 */
UCLASS()
class UGAP_Launched : public UCGameplayAbility
{
	GENERATED_BODY()
public:
	// 构造函数
	UGAP_Launched();

	// 激活能力时调用
	virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
	
	// 获取击飞激活事件Tag
	static FGameplayTag GetLaunchedAbilityActivationTag();
};
cpp 复制代码
// 幻雨喜欢小猫咪


#include "GAP_Launched.h"

#include "GAS/Core/TGameplayTags.h"

UGAP_Launched::UGAP_Launched()
{
	// 设置网络执行策略为仅在服务器端执行
	NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::ServerOnly;

	// 创建一个新的触发数据对象
	FAbilityTriggerData TriggerData;

	// 设置触发数据的触发源为游戏事件
	TriggerData.TriggerSource = EGameplayAbilityTriggerSource::GameplayEvent;

	// 设置触发数据的触发标签为击飞被动技能激活标签
	TriggerData.TriggerTag = TGameplayTags::Ability_Passive_Launch_Activate;

	// 将创建好的触发数据添加到能力触发器列表中
	AbilityTriggers.Add(TriggerData);
}

void UGAP_Launched::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
	const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	if (!K2_CommitAbility())
	{
		K2_EndAbility();
		return;
	}

	if (K2_HasAuthority())
	{
		// 推自己
		PushSelf(TriggerEventData->TargetData.Get(0)->GetHitResult()->ImpactNormal);
		K2_EndAbility();
	}
}

FGameplayTag UGAP_Launched::GetLaunchedAbilityActivationTag()
{
	return TGameplayTags::Ability_Passive_Launch_Activate;
}

CGameplayAbility中添加推动自身的力

cpp 复制代码
	// 推动自己(如击退/击飞)
	void PushSelf(const FVector& PushVel);
	void PushTarget(AActor* Target, const FVector& PushVel);
	
	// 获取拥有者角色指针
	ACharacter* GetOwningAvatarCharacter();
private:
	// 缓存的拥有者角色指针
	UPROPERTY()
	TObjectPtr<ACharacter> AvatarCharacter;
cpp 复制代码
void UCGameplayAbility::PushSelf(const FVector& PushVel)
{
	ACharacter* OwningAvatarCharacter = GetOwningAvatarCharacter();
	if (OwningAvatarCharacter)
	{
		OwningAvatarCharacter->LaunchCharacter(PushVel, true, true);
	}
}

void UCGameplayAbility::PushTarget(AActor* Target, const FVector& PushVel)
{
	// 目标为空则返回
	if (!Target) return;

	FGameplayEventData EventData;

	// 创建单目标命中数据对象
	FGameplayAbilityTargetData_SingleTargetHit* HitData = new FGameplayAbilityTargetData_SingleTargetHit;
	// 配置命中结果参数
	FHitResult HitResult;
	HitResult.ImpactNormal = PushVel; // 设置冲击方向为力的方向
	HitData->HitResult = HitResult;
	EventData.TargetData.Add(HitData);
	// 用标签激活技能
	UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(Target, UGAP_Launched::GetLaunchedAbilityActivationTag(), EventData);
}

ACharacter* UCGameplayAbility::GetOwningAvatarCharacter()
{
	if (!AvatarCharacter)
	{
		AvatarCharacter = Cast<ACharacter>(GetAvatarActorFromActorInfo());
	}
	return AvatarCharacter;
}

回到升龙技能中,实现力技能的添加,再添加一个伤害效果

cpp 复制代码
    // 上勾拳击飞阶段的伤害效果
    UPROPERTY(EditDefaultsOnly, Category = "Launch")
    TSubclassOf<UGameplayEffect> LaunchDamageEffect;
	
	// 上勾拳击飞速度
	UPROPERTY(EditDefaultsOnly, Category = "Launch", meta = (DisplayName = "击飞力的大小"))
	float UpperCutLaunchSpeed = 1000.f;
cpp 复制代码
void UUpperCut::StartLaunching(FGameplayEventData EventData)
{
	if (K2_HasAuthority())
	{
		// 获取命中目标的数量
		int32 HitResultCount = UAbilitySystemBlueprintLibrary::GetDataCountFromTargetData(EventData.TargetData);
		// 推动自己向上
		PushTarget(GetAvatarActorFromActorInfo(), FVector::UpVector * UpperCutLaunchSpeed);

		for (int32 i = 0; i < HitResultCount; ++i)
		{
			// 获取每个命中的HitResult
			FHitResult HitResult = UAbilitySystemBlueprintLibrary::GetHitResultFromTargetData(EventData.TargetData, i);

			PushTarget(HitResult.GetActor(), FVector::UpVector * UpperCutLaunchSpeed);
			ApplyGameplayEffectToHitResultActor(HitResult, LaunchDamageEffect, GetAbilityLevel(CurrentSpecHandle, CurrentActorInfo));
  
		}
	}
}

为角色添加基础技能,因为是通过tag触发的,所以不用管输入

创建一个GE

然后一个升龙拳双方都起飞了

为技能添加冷却以及消耗

创建一个tag表示升龙的冷却,在冷却标签存在的时间内是无法再次使用此技能。

cpp 复制代码
CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Uppercut_Cooldown)
cpp 复制代码
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Uppercut_Cooldown, "Ability.Uppercut.Cooldown", "升龙拳技能冷却")

创建一个GE来设置拥有持续时间,在GA的冷却中添加该GE

将CD添加到GA中

创建一个GE作为开销

用技能就会耗蓝了

相关推荐
上海云盾第一敬业销售10 小时前
深入了解游戏盾:安全架构解析
安全·游戏·安全架构
曼巴UE510 小时前
UE5 C++ TSet 创建初始和迭代
java·c++·ue5
AA陈超11 小时前
Lyra学习5:GameFeatureAction分析
c++·笔记·学习·ue5·lyra
da_vinci_x11 小时前
PS 3D Viewer + AI 生成:灰盒(Greybox)一键变“3A”概念图
人工智能·游戏·数学建模·3d·prompt·aigc·游戏美术
国服第二切图仔11 小时前
Electron for 鸿蒙PC项目实战案例之记忆卡片游戏
游戏·electron·harmonyos·鸿蒙pc
技术小甜甜11 小时前
[Godot游戏开发] 安卓平台游戏如何设置窗口与分辨率:Viewport、Window Override与自适应窗口解析
android·游戏·godot
PA_1 天前
unity Component-Based Architecture游戏框架
游戏·unity·游戏引擎
Stark-C1 天前
『真·扩容』将游戏和软件安装到NAS,极空间iSCSI功能初体验
游戏
Minecraft红客1 天前
复原大唐3d更新版本
c++·游戏·3d·娱乐
zhangzhangkeji1 天前
UMG - 18:尺寸框里的按钮属性,按钮包含文本框,以此来了解按钮的尺寸属性与颜色属性
ue5