做淘宝客导购网站,建筑人才网代码,怎么能查到网站是哪家公司做的,公司网站建站软件书接 11. UE5 RPG使用GameplayEffect修改角色属性#xff08;二#xff09; 前面#xff0c;介绍了GameplayEffect的Instant和Duration的使用#xff0c;这一篇主要介绍一下无限制时间类型的infinite的使用方式。 无限时间限制模式下#xff0c;如果你的周期时间#xff…书接 11. UE5 RPG使用GameplayEffect修改角色属性二 前面介绍了GameplayEffect的Instant和Duration的使用这一篇主要介绍一下无限制时间类型的infinite的使用方式。 无限时间限制模式下如果你的周期时间Period为0那就是相当于增加了一个状态加了一个Buff效果是持续的如果周期时间你设置了值那么它将变成为每个周期执行一次Instant效果的GameplayEffect。 使用起来基本上和有时间限制的Duration一样它们的区别在于一个是有时间限制的另一个是没有时间限制。
应用场景
可以使用到地面陷阱比如地上的岩浆角色站在上面会一直掉血离开后通过清除GameplayEffect来取消效果。恢复水泉角色站在旁边可以一直恢复。无限制时间的buff比如装备提供的buff角色特有的属性bufff。
接下来我们要制作一个通用的类里面可以设置这三种属性的GameplayEffect在蓝图里面只需要设置何时触发效果即可。并且实现一下Infinite效果的添加和删除功能。
首先我们要添加两个枚举用于设置添加的类在何时应用到actor身上
//效果应用状态枚举
UENUM(BlueprintType)
enum class EEffectApplicationPolicy
{ApplyOnOverlap,ApplyOnEndOverlap,DoNotApply
};//效果移除的状态枚举
UENUM(BlueprintType)
enum class EEffectRemovalPolicy
{RemoveOnEndOverlap,DoNotRemove
};接着修改配置项的类每一种GameplayEffect的类Instant和Duration只有添加时的策略配置它们两个一个是瞬间效果另一个是有时效性的都不需要主动移除Infinite的则需要设置添加策略和移除策略。 UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect InstantGameplayEffectClass; //生成GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy InstantEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect DurationGameplayEffectClass; //生成具有一定持续时间的GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy DurationEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect InfinityGameplayEffectClass; //生成具有一定持续时间的GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy InfinityEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectRemovalPolicy InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap;接着我们需要创建两个函数可以在蓝图中调用触发overlap和endoverlap时的相关事件 //在重叠开始时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnOverlap(AActor* TargetActor);//在重叠结束时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnEndOverlap(AActor* TargetActor);在Overlap事件中如果你设置了对应的需要在Overlap时添加效果将去执行ApplyEffectToTarget()函数应用效果。
void AEffectActorBase::OnOverlap(AActor* TargetActor)
{if(InstantEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InfinityGameplayEffectClass);}
}ApplyEffectToTarget()函数之前也讲过这里有了更改就是对于Infinite类型的效果并且在重叠结束时需要销毁的效果我们需要将其的引用保存下来因为它不会自己取消需要手动去销毁。
void AEffectActorBase::ApplyEffectToTarget(AActor* TargetActor, TSubclassOfUGameplayEffect GameplayEffectClass)
{/*** 默认自己编写从actor身上获取ASC的方式* IAbilitySystemInterface* ASCInterface CastIAbilitySystemInterface(TargetActor); //判断当前actor是否有技能系统接口if(ASCInterface){UAbilitySystemComponent* TargetASC ASCInterface-GetAbilitySystemComponent(); }*///获取ASCUAbilitySystemComponent* TargetASC UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if(TargetASC nullptr) return;check(GameplayEffectClass);//创建Effect的句柄 包含了实例化Effect所需数据FGameplayEffectContextHandle EffectContextHandle TargetASC-MakeEffectContext();//设置创建Effect的对象EffectContextHandle.AddSourceObject(this);//Effect的实例化后的句柄可以通过此来寻找调用const FGameplayEffectSpecHandle EffectSpecHandle TargetASC-MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);//从句柄中获取到实例的地址并被应用。const FActiveGameplayEffectHandle ActiveGameplayEffectHandle TargetASC-ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());//从句柄中获取到定义的对象并判断设置的const bool bIsInfinite EffectSpecHandle.Data.Get()-Def.Get()-DurationPolicy EGameplayEffectDurationType::Infinite;//在是无限时间效果和需要在结束时清除掉时将效果句柄添加到mapif(bIsInfinite InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap){ActiveEffectHandles.Add(ActiveGameplayEffectHandle, TargetASC);}
}在结束重叠事件函数中首先逻辑判断是否需要在离开时添加效果。接下来就是判断Infinite类型的效果是否需要在结束重叠事件时移除如果需要则通过ASC判断相同来找到对应的效果进行移除在堆栈里面还不能直接移除所以先将引用保存了下来
void AEffectActorBase::OnEndOverlap(AActor* TargetActor)
{//添加效果if(InstantEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InfinityGameplayEffectClass);}//删除效果if(InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap){UAbilitySystemComponent* TargetASC UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if(!IsValid(TargetASC)) return;//创建存储需要移除的效果句柄存储Key用于遍历完成后移除效果TArrayFActiveGameplayEffectHandle HandlesToRemove;//循环map内存的数据for(TTupleFActiveGameplayEffectHandle, 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);}}
}接着编译打开ue看到右侧有对应的属性配置 事件图表更好设置在对应的碰撞体事件触发回调时链接即可 GameplayEffect的设置就很简单了一个持续掉血的效果 接下来就是测试运行起来点击~键然后输入showdebug abilitysystem 来查看掉血情况
下面附上上面两个文件的整个代码 EffectActorBase.h
// 版权归暮志未晚所有。#pragma once#include CoreMinimal.h
#include GameFramework/Actor.h
#include GameplayEffectTypes.h
#include EffectActorBase.generated.hstruct FActiveGameplayEffectHandle;
class UAbilitySystemComponent;
class UGameplayEffect;//效果应用状态枚举
UENUM(BlueprintType)
enum class EEffectApplicationPolicy
{ApplyOnOverlap,ApplyOnEndOverlap,DoNotApply
};//效果移除的状态枚举
UENUM(BlueprintType)
enum class EEffectRemovalPolicy
{RemoveOnEndOverlap,DoNotRemove
};/*** 在场景中可放置的影响角色属性的物件基类*/
UCLASS()
class AURA_API AEffectActorBase : public AActor
{GENERATED_BODY()public: AEffectActorBase();protected:// 游戏开始或生成对象时回调virtual void BeginPlay() override;//给与目标添加GameplayEffect效果UFUNCTION(BlueprintCallable) void ApplyEffectToTarget(AActor* TargetActor, TSubclassOfUGameplayEffect GameplayEffectClass);//在重叠开始时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnOverlap(AActor* TargetActor);//在重叠结束时处理效果的添加删除逻辑UFUNCTION(BlueprintCallable) void OnEndOverlap(AActor* TargetActor);UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect InstantGameplayEffectClass; //生成GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy InstantEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect DurationGameplayEffectClass; //生成具有一定持续时间的GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy DurationEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)TSubclassOfUGameplayEffect InfinityGameplayEffectClass; //生成具有一定持续时间的GameplayEffect的类UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectApplicationPolicy InfinityEffectApplicationPolicy EEffectApplicationPolicy::DoNotApply;UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryApply Effects)EEffectRemovalPolicy InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap;//用于存储当前已经激活的GameplayEffect的句柄的mapTMapFActiveGameplayEffectHandle, UAbilitySystemComponent* ActiveEffectHandles;
};
EffectActorBase.cpp
// 版权归暮志未晚所有。#include Actor/EffectActorBase.h
#include ActiveGameplayEffectHandle.h
#include AbilitySystemBlueprintLibrary.h
#include AbilitySystemComponent.hAEffectActorBase::AEffectActorBase()
{// 设置当前对象是否每帧调用Tick()PrimaryActorTick.bCanEverTick false;SetRootComponent(CreateDefaultSubobjectUSceneComponent(SceneRoot));
}void AEffectActorBase::BeginPlay()
{Super::BeginPlay();
}void AEffectActorBase::ApplyEffectToTarget(AActor* TargetActor, TSubclassOfUGameplayEffect GameplayEffectClass)
{/*** 默认自己编写从actor身上获取ASC的方式* IAbilitySystemInterface* ASCInterface CastIAbilitySystemInterface(TargetActor); //判断当前actor是否有技能系统接口if(ASCInterface){UAbilitySystemComponent* TargetASC ASCInterface-GetAbilitySystemComponent(); }*///获取ASCUAbilitySystemComponent* TargetASC UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if(TargetASC nullptr) return;check(GameplayEffectClass);//创建Effect的句柄 包含了实例化Effect所需数据FGameplayEffectContextHandle EffectContextHandle TargetASC-MakeEffectContext();//设置创建Effect的对象EffectContextHandle.AddSourceObject(this);//Effect的实例化后的句柄可以通过此来寻找调用const FGameplayEffectSpecHandle EffectSpecHandle TargetASC-MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);//从句柄中获取到实例的地址并被应用。const FActiveGameplayEffectHandle ActiveGameplayEffectHandle TargetASC-ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());//从句柄中获取到定义的对象并判断设置的const bool bIsInfinite EffectSpecHandle.Data.Get()-Def.Get()-DurationPolicy EGameplayEffectDurationType::Infinite;//在是无限时间效果和需要在结束时清除掉时将效果句柄添加到mapif(bIsInfinite InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap){ActiveEffectHandles.Add(ActiveGameplayEffectHandle, TargetASC);}
}void AEffectActorBase::OnOverlap(AActor* TargetActor)
{if(InstantEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnOverlap){ApplyEffectToTarget(TargetActor, InfinityGameplayEffectClass);}
}void AEffectActorBase::OnEndOverlap(AActor* TargetActor)
{//添加效果if(InstantEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InstantGameplayEffectClass);}if(DurationEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, DurationGameplayEffectClass);}if(InfinityEffectApplicationPolicy EEffectApplicationPolicy::ApplyOnEndOverlap){ApplyEffectToTarget(TargetActor, InfinityGameplayEffectClass);}//删除效果if(InfinityEffectRemovalPolicy EEffectRemovalPolicy::RemoveOnEndOverlap){UAbilitySystemComponent* TargetASC UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);if(!IsValid(TargetASC)) return;//创建存储需要移除的效果句柄存储Key用于遍历完成后移除效果TArrayFActiveGameplayEffectHandle HandlesToRemove;//循环map内存的数据for(TTupleFActiveGameplayEffectHandle, 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);}}
}