当前位置: 首页 > 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.dtcms.com/a/282408.html

相关文章:

  • 【28】MFC入门到精通——MFC串口 Combobox 控件实现串口号
  • 技术演进中的开发沉思-36 MFC系列: 对话框
  • Java并发编程(一)
  • LeetCode Hot 100 二叉树的最大深度
  • .NET 10 Preview 4 已发布
  • 【C# in .NET】9. 探秘委托:函数抽象的底层机制
  • 设置第三方窗口置顶(SetWindowPos方法,vb.net)
  • WMS仓储管理系统智能调控提升电子企业库存周转率
  • 系统启动流程分析
  • Linux-RAID
  • QML 五大对话框组件
  • 端口被占用时的解决问题
  • Egg.js × NestJS 2025 Nodejs后端框架选型指南
  • 代码随想录算法训练营十七天|二叉树part07
  • 【android bluetooth 协议分析 03】【蓝牙扫描详解 2】【app触发蓝牙扫描后,协议栈都做了那些事情】
  • 跨平台 App 如何无痛迁移到鸿蒙系统?全流程实战+Demo 教程
  • 八股文——包装类
  • Android 升级targetSdk无法启动服务
  • 动态规划题解——分割等和子集【LeetCode】
  • 面向向量检索的教育QA建模:九段日本文化研究所日本语学院的Prompt策略分析(6 / 500)
  • 知识点3:python-sdk 核心概念(prompt、image、context)
  • 有哪些好用的原型设计软件?墨刀、Axure等测评对比
  • MAC 苹果版Adobe Photoshop 2019下载及保姆级安装教程!!
  • Prompt Engineering 快速入门+实战案例
  • C#.NET BackgroundService 详解
  • 增程式汽车底盘设计cad【9张】三维图+设计说明书
  • 机器学习sklearn入门:归一化和标准化
  • 深入解析 AWS RDS Proxy
  • VirtualBox 中 CentOS 7 双网卡配置静态 IP
  • 用 Ray 跨节点调用 GPU 部署 DeepSeek 大模型,实现分布式高效推理