44. Infinite Effect Application and Removal
This commit is contained in:
parent
caae7fd758
commit
a218d86c23
BIN
Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
(Stored with Git LFS)
BIN
Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
(Stored with Git LFS)
Binary file not shown.
@ -1,6 +1,7 @@
|
|||||||
#include "GasaEffectActor.h"
|
#include "GasaEffectActor.h"
|
||||||
|
|
||||||
#include "GasaAbilitySystemComponent_Inlines.h"
|
#include "GasaAbilitySystemComponent_Inlines.h"
|
||||||
|
#include "GasaContainers.h"
|
||||||
using namespace Gasa;
|
using namespace Gasa;
|
||||||
|
|
||||||
AGasaEffectActor::AGasaEffectActor()
|
AGasaEffectActor::AGasaEffectActor()
|
||||||
@ -9,21 +10,24 @@ AGasaEffectActor::AGasaEffectActor()
|
|||||||
|
|
||||||
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
|
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
|
||||||
|
|
||||||
InstantEffectUsage = DefaultEffectUsagePolicy;
|
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
|
||||||
DurationEffectUsage = DefaultEffectUsagePolicy;
|
DurationEffectUsage = DefaultEffectUsagePolicy;
|
||||||
InfiniteEffectUsage = DefaultEffectUsagePolicy;
|
InfiniteEffectUsage = DefaultEffectUsagePolicy;
|
||||||
|
|
||||||
|
bDestroyOnEffectRemoval = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass)
|
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap)
|
||||||
{
|
{
|
||||||
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
||||||
|
|
||||||
FGameplayEffectContextHandle
|
FGameplayEffectContextHandle
|
||||||
Context = AS->MakeEffectContext();
|
Context = AS->MakeEffectContext();
|
||||||
Context.AddSourceObject(Actor);
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context );
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context );
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (bRemoveOnEndOverlap)
|
||||||
|
ActiveEffectsToRemove.Add(ActiveEffect, AS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AGasaEffectActor::OnOverlap(AActor* Actor)
|
void AGasaEffectActor::OnOverlap(AActor* Actor)
|
||||||
@ -33,40 +37,37 @@ void AGasaEffectActor::OnOverlap(AActor* Actor)
|
|||||||
Context = AS->MakeEffectContext();
|
Context = AS->MakeEffectContext();
|
||||||
Context.AddSourceObject(Actor);
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
if (InstantEffectClass.Get())
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
|
||||||
{
|
{
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap))
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
||||||
{
|
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
}
|
}
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap))
|
if (DurationEffectClass)
|
||||||
{
|
{
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( InstantEffectClass, AS );
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
|
||||||
|
{
|
||||||
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
ActiveDuration = ActiveEffect;
|
||||||
}
|
}
|
||||||
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
||||||
}
|
}
|
||||||
if (DurationEffectClass.Get())
|
if (InfiniteEffectClass)
|
||||||
{
|
{
|
||||||
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap))
|
bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap);
|
||||||
|
if (bApplyOnOverlap)
|
||||||
{
|
{
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context );
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
ActiveInfinite = ActiveEffect;
|
||||||
}
|
}
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap))
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
{
|
{
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( DurationEffectClass, AS );
|
if (ActiveInfinite.IsValid())
|
||||||
}
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
||||||
}
|
|
||||||
if (InfiniteEffectClass.Get())
|
|
||||||
{
|
|
||||||
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap))
|
|
||||||
{
|
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
||||||
}
|
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap))
|
|
||||||
{
|
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( InfiniteEffectClass, AS );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,40 +79,46 @@ void AGasaEffectActor::OnEndOverlap(AActor* Actor)
|
|||||||
Context = AS->MakeEffectContext();
|
Context = AS->MakeEffectContext();
|
||||||
Context.AddSourceObject(Actor);
|
Context.AddSourceObject(Actor);
|
||||||
|
|
||||||
if (InstantEffectClass.Get())
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap)
|
||||||
{
|
{
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap))
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
||||||
{
|
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
}
|
}
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
if (DurationEffectClass)
|
||||||
{
|
{
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( InstantEffectClass, AS );
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
||||||
}
|
|
||||||
}
|
|
||||||
if (DurationEffectClass.Get())
|
|
||||||
{
|
{
|
||||||
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap))
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
ActiveDuration = ActiveEffect;
|
||||||
|
}
|
||||||
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
||||||
|
}
|
||||||
|
if (InfiniteEffectClass)
|
||||||
{
|
{
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
||||||
}
|
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
|
||||||
{
|
{
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( DurationEffectClass, AS );
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context );
|
||||||
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
||||||
|
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap))
|
||||||
|
ActiveInfinite = ActiveEffect;
|
||||||
}
|
}
|
||||||
}
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
||||||
if (InfiniteEffectClass.Get())
|
|
||||||
{
|
{
|
||||||
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap))
|
if (ActiveInfinite.IsValid())
|
||||||
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FActiveGameplayEffectHandle> EffectsRemoved;
|
||||||
|
for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove)
|
||||||
{
|
{
|
||||||
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context );
|
if (ActiveEffect.Value != AS)
|
||||||
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
continue;
|
||||||
}
|
AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1);
|
||||||
if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap))
|
EffectsRemoved.Add(ActiveEffect.Key);
|
||||||
{
|
|
||||||
AS->RemoveActiveGameplayEffectBySourceEffect( InfiniteEffectClass, AS );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
RemoveKeys(ActiveEffectsToRemove, EffectsRemoved);
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,29 @@
|
|||||||
|
|
||||||
#include "GasaCommon.h"
|
#include "GasaCommon.h"
|
||||||
#include "Actors/GasaActor.h"
|
#include "Actors/GasaActor.h"
|
||||||
|
#include "ActiveGameplayEffectHandle.h"
|
||||||
#include "GameFramework/Actor.h"
|
#include "GameFramework/Actor.h"
|
||||||
|
|
||||||
#include "GasaEffectActor.generated.h"
|
#include "GasaEffectActor.generated.h"
|
||||||
|
|
||||||
|
struct FActiveGameplayEffectHandle;
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
UENUM(BlueprintType)
|
||||||
|
enum class EInstantEffectUsagePolicy : uint8
|
||||||
|
{
|
||||||
|
DoNotApply,
|
||||||
|
ApplyOnOverlap,
|
||||||
|
ApplyOnEndOverlap,
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
|
||||||
enum class EEffectUsagePolicy : uint8
|
enum class EEffectUsagePolicy : uint8
|
||||||
{
|
{
|
||||||
None = 0 UMETA(Hidden),
|
None = 0 UMETA(Hidden),
|
||||||
ApplyOnOverlap = bit(0),
|
ApplyOnOverlap = bit(0),
|
||||||
ApplyOnEndOverlap = bit(1),
|
ApplyOnEndOverlap = bit(1),
|
||||||
RemoveOnOverlap = bit(3),
|
RemoveOnOverlap = bit(2),
|
||||||
RemoveOnEndOverlap = bit(4),
|
RemoveOnEndOverlap = bit(3),
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap));
|
constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap));
|
||||||
@ -27,28 +38,34 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
TSubclassOf<UGameplayEffect> InstantEffectClass;
|
TSubclassOf<UGameplayEffect> InstantEffectClass;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
int32 InstantEffectUsage;
|
EInstantEffectUsagePolicy InstantEffectUsage;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
TSubclassOf<UGameplayEffect> DurationEffectClass;
|
TSubclassOf<UGameplayEffect> DurationEffectClass;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
|
||||||
int32 DurationEffectUsage;
|
int32 DurationEffectUsage;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
TSubclassOf<UGameplayEffect> InfiniteEffectClass;
|
TSubclassOf<UGameplayEffect> InfiniteEffectClass;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
|
||||||
int32 InfiniteEffectUsage;
|
int32 InfiniteEffectUsage;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
|
||||||
bool bDestroyOnEffectRemoval = false;
|
bool bDestroyOnEffectRemoval;
|
||||||
|
|
||||||
|
TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectsToRemove;
|
||||||
|
using ActiveEffectEntry = TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*>;
|
||||||
|
|
||||||
|
FActiveGameplayEffectHandle ActiveDuration;
|
||||||
|
FActiveGameplayEffectHandle ActiveInfinite;
|
||||||
|
|
||||||
AGasaEffectActor();
|
AGasaEffectActor();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Gameplay Effects")
|
UFUNCTION(BlueprintCallable, Category = "Gameplay Effects")
|
||||||
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass );
|
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void OnOverlap(AActor* Actor);
|
void OnOverlap(AActor* Actor);
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework")
|
||||||
EGameFrameworkState GameFrameworkState;
|
EGameFrameworkState GameFrameworkState;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = EGameFrameworkClassFlag))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EGameFrameworkClassFlag"))
|
||||||
int32 GameFrameworkClassesState;
|
int32 GameFrameworkClassesState;
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category="GameFramework")
|
UFUNCTION(BlueprintCallable, Category="GameFramework")
|
||||||
|
@ -80,13 +80,30 @@ namespace Gasa
|
|||||||
{
|
{
|
||||||
inline
|
inline
|
||||||
bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) {
|
bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) {
|
||||||
int32 Result = Bitmask == (Bitfield & Bitmask);
|
bool Result = Bitmask == (Bitfield & Bitmask);
|
||||||
return scast(bool, Result);
|
return Result;
|
||||||
|
}
|
||||||
|
inline
|
||||||
|
bool Bitfield_IsSetExactly(int32 Bitfield, int32 Bitmask)
|
||||||
|
{
|
||||||
|
bool Result = Bitfield == (Bitfield & Bitmask);
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Bitfield_Set ( int32& Bitfield, int32 BitsToAdd ) { Bitfield |= BitsToAdd; }
|
inline void Bitfield_Set ( int32& Bitfield, int32 BitsToAdd ) { Bitfield |= BitsToAdd; }
|
||||||
inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); }
|
inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); }
|
||||||
inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask ) { Bitfield ^= Bitmask; }
|
inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask ) { Bitfield ^= Bitmask; }
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
inline
|
||||||
|
bool Bitfield_IsSet(int32 Bitfield, EnumType Mask)
|
||||||
|
{
|
||||||
|
bool Result = int32(Mask) == (Bitfield & int32(Mask));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
template<typename EnumType> inline void Bitfield_Set ( int32& Bitfield, EnumType BitToAdd ) { Bitfield |= int32(BitToAdd); }
|
||||||
|
template<typename EnumType> inline void Bitfield_Remove( int32& Bitfield, EnumType BitToRemove ) { Bitfield &= (! int32(BitToRemove)); }
|
||||||
|
template<typename EnumType> inline void Bitfield_Toggle( int32& Bitfield, EnumType BitToToggle ) { Bitfield ^= int32(BitToToggle); }
|
||||||
}
|
}
|
||||||
#pragma endregion Bitfields
|
#pragma endregion Bitfields
|
||||||
|
|
||||||
|
0
Project/Source/Gasa/GasaContainers.cpp
Normal file
0
Project/Source/Gasa/GasaContainers.cpp
Normal file
14
Project/Source/Gasa/GasaContainers.h
Normal file
14
Project/Source/Gasa/GasaContainers.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GasaCommon.h"
|
||||||
|
|
||||||
|
template<typename KeyType, typename ValueType>
|
||||||
|
inline
|
||||||
|
void RemoveKeys(TMap<KeyType, ValueType> Map, TArray<KeyType> Keys)
|
||||||
|
{
|
||||||
|
for (KeyType& Key : Keys )
|
||||||
|
{
|
||||||
|
Map.Remove(Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user