当前位置: 首页 > news >正文

虚幻引擎5 GAS开发俯视角RPG游戏 #06-7:无限游戏效果

一. 无限游戏效果策略:

1.添加枚举

Source/CC_Aura/Public/Actor/CC_EffectActor.h:

//效果应用策略枚举
UENUM(BlueprintType) 
enum class EEffectApplicationPolicy :uint8		//使用BlueprintType标记的枚举类型目前仅支持uint8作为基础类型。
{ApplyOnOverlap,			//重叠时应用ApplyOnEndOverlap,		//结束重叠时应用DoNotApply				
};//效果移除策略枚举
UENUM(BlueprintType) 
enum class EEffectRemovalPolicy :uint8
{RemoveOnEndOverlap,		//在结束重叠时移除DoNotRemove
};

赋值:

	//给对象添加效果UFUNCTION(BlueprintCallable)void ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass);//即时游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> InstantGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy InstantEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;//持续游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> DurationGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy DurationEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;//无限游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> InfiniteGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy InfinityEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectRemovalPolicy InfinityEffectRemovalPolicy = EEffectRemovalPolicy::RemoveOnEndOverlap;

2.添加函数:

	//在重叠开始时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnOverlap(AActor* TargetActor);//在重叠结束时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnEndOverlap(AActor* TargetActor);

在Source/CC_Aura/Private/Actor/CC_EffectActor.cpp:

void ACC_EffectActor::OnOverlap(AActor* TargetActor)
{//即时效果if (InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}//持续效果if (DurationEffectApplicationPolicy ==  EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}//无限效果if (InfinityEffectApplicationPolicy ==  EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);}
}

3.修改ApplyEffectToTarget函数,当无限效果时,保存效果规格句柄:


void ACC_EffectActor::ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass)
{checkf(GameplayEffectClass, TEXT("%s中:GameplayEffectClass没有设置!!!"), *GetName());//1.获取目标Actor的AbilitySystemComponent组件UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if (TargetASC == nullptr) return;//2.创建效果上下文句柄FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();EffectContextHandle.AddSourceObject(this);		//设置效果来源对象为当前EffectActor//3.创建效果规格句柄(Spec)const FGameplayEffectSpecHandle EffectSpecHandle = TargetASC->MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);//4.应用效果const FActiveGameplayEffectHandle ActiveGameplayEffectHandle = TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());//5.如果是无限效果,存储权柄信息const bool bIsInfinite = EffectSpecHandle.Data.Get()->Def.Get()->DurationPolicy == EGameplayEffectDurationType::Infinite;//无限效果 && 结束覆盖时移除if (bIsInfinite && InfinityEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap){//存储信息ActiveEffectHandles.Add(ActiveGameplayEffectHandle, TargetASC);}
}

4.结束重叠时,触发事件函数:


void ACC_EffectActor::OnEndOverlap(AActor* TargetActor)
{//添加效果if(InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);}//手动结束无限效果if (InfinityEffectRemovalPolicy ==  EEffectRemovalPolicy::RemoveOnEndOverlap){//1.获取目标Actor的AbilitySystemComponent组件UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if (!IsValid(TargetASC)) return;//创建存储需要移除的效果句柄存储Key,用于遍历完成后移除效果TArray<FActiveGameplayEffectHandle> HandlesToRemove;//循环map内存的数据for(TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*> HandlePair : ActiveEffectHandles){//判断是否ASC相同if(TargetASC == HandlePair.Value){//通过句柄将效果移除,注意,有可能有多层效果,不能将其它层的效果也移除掉,所以只移除一层TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);//添加到移除列表HandlesToRemove.Add(HandlePair.Key);}}//遍历完成后,在Map中将移除效果的KeyValue删除for(auto& Handle : HandlesToRemove){ActiveEffectHandles.FindAndRemoveChecked(Handle);}}
}

5.在BP_FireArea: 

6.火焰效果:

源代码:

Source/CC_Aura/Public/Actor/CC_EffectActor.h:

// 版权归陈超所有#pragma once#include "CoreMinimal.h"
#include "ActiveGameplayEffectHandle.h"
#include "GameFramework/Actor.h"
#include "CC_EffectActor.generated.h"//struct FActiveGameplayEffectHandle;
class UAbilitySystemComponent;
class UGameplayEffect;
class USphereComponent;
class UStaticMeshComponent;//效果应用策略枚举
UENUM(BlueprintType) 
enum class EEffectApplicationPolicy :uint8		//使用BlueprintType标记的枚举类型目前仅支持uint8作为基础类型。
{ApplyOnOverlap,			//重叠时应用ApplyOnEndOverlap,		//结束重叠时应用DoNotApply				
};//效果移除策略枚举
UENUM(BlueprintType) 
enum class EEffectRemovalPolicy :uint8
{RemoveOnEndOverlap,		//在结束重叠时移除DoNotRemove
};UCLASS()
class CC_AURA_API ACC_EffectActor : public AActor
{GENERATED_BODY()public:	ACC_EffectActor();protected:virtual void BeginPlay() override;//给对象添加效果UFUNCTION(BlueprintCallable)void ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass);//在重叠开始时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnOverlap(AActor* TargetActor);//在重叠结束时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnEndOverlap(AActor* TargetActor);//即时游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> InstantGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy InstantEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;//持续游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> DurationGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy DurationEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;//无限游戏效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effects")TSubclassOf<UGameplayEffect> InfiniteGameplayEffectClass;UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectApplicationPolicy InfinityEffectApplicationPolicy = EEffectApplicationPolicy::DoNotApply;	//无限效果应用效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")EEffectRemovalPolicy InfinityEffectRemovalPolicy = EEffectRemovalPolicy::RemoveOnEndOverlap;	//无限效果移除策略//用于存储当前已经激活的GameplayEffect的句柄的mapTMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectHandles;
};

Source/CC_Aura/Private/Actor/CC_EffectActor.cpp:

// 版权归陈超所有#include "Actor/CC_EffectActor.h"#include "AbilitySystemComponent.h"
#include "AbilitySystemBlueprintLibrary.h"ACC_EffectActor::ACC_EffectActor()
{// 将此参与者设置为每帧调用Tick()。如果你不需要它,你可以关闭它来提高性能。PrimaryActorTick.bCanEverTick = false;SetRootComponent(CreateDefaultSubobject<USceneComponent>("SceneRoot"));
}// 在游戏开始或生成时调用
void ACC_EffectActor::BeginPlay()
{Super::BeginPlay();
}void ACC_EffectActor::ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass)
{checkf(GameplayEffectClass, TEXT("%s中:GameplayEffectClass没有设置!!!"), *GetName());//1.获取目标Actor的AbilitySystemComponent组件UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if (TargetASC == nullptr) return;//2.创建效果上下文句柄FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();EffectContextHandle.AddSourceObject(this);		//设置效果来源对象为当前EffectActor//3.创建效果规格句柄(Spec)const FGameplayEffectSpecHandle EffectSpecHandle = TargetASC->MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);//4.应用效果const FActiveGameplayEffectHandle ActiveGameplayEffectHandle = TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());//5.如果是无限效果,存储权柄信息const bool bIsInfinite = EffectSpecHandle.Data.Get()->Def.Get()->DurationPolicy == EGameplayEffectDurationType::Infinite;//无限效果 && 结束覆盖时移除if (bIsInfinite && InfinityEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap){//存储信息ActiveEffectHandles.Add(ActiveGameplayEffectHandle, TargetASC);}
}void ACC_EffectActor::OnOverlap(AActor* TargetActor)
{//即时效果if (InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}//持续效果if (DurationEffectApplicationPolicy ==  EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}//无限效果if (InfinityEffectApplicationPolicy ==  EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);}
}void ACC_EffectActor::OnEndOverlap(AActor* TargetActor)
{//添加效果if(InstantEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy == EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InfiniteGameplayEffectClass);}//手动结束无限效果if (InfinityEffectRemovalPolicy ==  EEffectRemovalPolicy::RemoveOnEndOverlap){//1.获取目标Actor的AbilitySystemComponent组件UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if (!IsValid(TargetASC)) return;//创建存储需要移除的效果句柄存储Key,用于遍历完成后移除效果TArray<FActiveGameplayEffectHandle> HandlesToRemove;//循环map内存的数据for(TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*> HandlePair : ActiveEffectHandles){//判断是否ASC相同if(TargetASC == HandlePair.Value){//通过句柄将效果移除,注意,有可能有多层效果,不能将其它层的效果也移除掉,所以只移除一层TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);//添加到移除列表HandlesToRemove.Add(HandlePair.Key);}}//遍历完成后,在Map中将移除效果的KeyValue删除for(auto& Handle : HandlesToRemove){ActiveEffectHandles.FindAndRemoveChecked(Handle);}}
}

http://www.lryc.cn/news/589819.html

相关文章:

  • 使用EF Core修改数据:Update方法与SaveChanges的深度解析
  • 前端性能追踪工具:用户体验的毫秒战争
  • Kiro:亚马逊云发布,革命性AI编程工具!以“规范驱动开发“重塑软件构建范式!
  • es启动问题解决
  • Java数据结构第二十五期:红黑树传奇,当二叉树穿上 “红黑铠甲” 应对失衡挑战
  • 树莓派系统安装
  • GENERALIST REWARD MODELS: FOUND INSIDE LARGELANGUAGE MODELS
  • Java对象的比较
  • 【ArcGISPro】修改conda虚拟安装包路径
  • C++ 计数排序、归并排序、快速排序
  • 图机器学习(10)——监督学习中的图神经网络
  • 【AI智能体】Dify 基于知识库搭建智能客服问答应用详解
  • AdsPower 功能详解 | 应用中心使用指南:插件统一管理更高效、更安全!
  • 医疗AI“全栈原生态“系统设计路径分析
  • Win11专业工作站版安装配置要求
  • 力扣每日一题--2025.7.16
  • MAC 苹果版Adobe Photoshop 2019下载及保姆级安装教程!!
  • 第六章 OBProxy 路由与使用运维
  • 【基于PaddlePaddle训练的车牌识别系统】
  • http协议学习-1
  • vue的provide和inject
  • 基于 Docker 环境的 JupyterHub 详细部署手册
  • 论文导读--PQ3D:通过分段级分组实现多模态特征融合和 MTU3D:在线查询表示学习与动态空间记忆
  • cell2location复现
  • xss-labs练习
  • Android-EDLA【CTS】CtsTetheringTest存在fail
  • 探究Netty 4.2.x版本
  • 动态规划题解——分割等和子集【LeetCode】
  • Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
  • docker的搭建