#GAS PR Kaos Part 1 - Convenience methods

1 messages ยท Page 1 of 1 (latest)

cold tree
#

and ...

#

maybe instance structs on the context could be useful too

#

@shell crypt

#

I do have the code with a custom struct, which would be very easy to move to a PR

shell crypt
#

not sure they would do that

cold tree
#

yeah me neither

shell crypt
#

but that scalable float one seems good

#

we have similar one

#

not as fancy but

#
    static float GetScalableFloatValue(const FScalableFloat& InScalableFloat, int32 Level);```
#

does the job haha

cold tree
#

yeah

#

this is missing too

#
    static AActor* GetInstigatorFromGameplayEffectSpec(const FGameplayEffectSpec& Spec);`

AActor* UCustomAbilitySystemBlueprintLibrary::GetInstigatorFromGameplayEffectSpec(const FGameplayEffectSpec& Spec)
{
    return Spec.GetEffectContext().GetInstigator();
}```
shell crypt
#

hmm

cold tree
#

no way to get the instigator in a MMC without it

#

(there is other custom ways obv)

shell crypt
#

wouldnt that be a spec handle?

cold tree
#

MMC is using spec IIRC

shell crypt
#

this seems MMC specific for BP

#

i cant see a usecase outside of mmc

cold tree
#

almost MMC BP only

#

but pretty much can't do withtout it

#

CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec)

#

We got a BP Exec too ๐Ÿ˜„

shell crypt
#

MMC in BP seems very lack luster

cold tree
#

yeah

#

in 5.0 it was unusable

shell crypt
#

all of ours are in c++

#

but tbf its faster

#

for us lol

cold tree
#

like, the method is const, and the attribute evaluate method wasn't xD

shell crypt
#

we have a lot of mmc firing

#

bp was way too slow

cold tree
#

I see

#

we do a lot in BP but doesn't seem to cause issues

shell crypt
#

sec

cold tree
#

most of the calcs are very simple anyway

shell crypt
#

let me show you

#

a profile when it was in bp

shell crypt
#

moved to c++ tis about 1ms

cold tree
#

and bp ?

shell crypt
#

tbf, i really think it should call a native func

#

i hate that fact its BlueprintNativeEvent

#

cause that has a cost overhead

cold tree
#

mhhhhhhhhhh

shell crypt
#
    float CalculateBaseMagnitude(const FGameplayEffectSpec& Spec) const;```
#

this should be a normal func

#

that calls say K2_CalculateBaseMagnitude()

#

so if you do this in c++ you dont incur the findfunction shit

shell crypt
#

FScalableFloat is part of GameplayAbilities

#

this is modmag calc

cold tree
#

no relation with our bp exec then

shell crypt
#

well your one just calls a specific func for bp

#

with some extra stuff

#

oh

#

this is EffectExecutionCalc

#

not mod mag

#

but meh bp handling for Executions should be better

cold tree
#

yeah

shell crypt
#

the way you did it feels meh

cold tree
shell crypt
#

i know

#

though i prefer to do these in c++ anyway

#

but i understand it should be bp accessible

cold tree
#

that's not for me anyway, I do mine in c++ too

shell crypt
#

theres no reason FGameplayEffectCustomExecutionParameters

#

cant be bp exposed

cold tree
#

one of our user created it, and I refined it and included it in narxim's

shell crypt
#

ie throught some statics ofc

cold tree
#

that's why we created a proxy struct

shell crypt
#

or well just functions

#

in the execution

#

/** Struct representing the output of a custom gameplay effect execution. */
USTRUCT(BlueprintType)
struct GAMEPLAYABILITIES_API FGameplayEffectCustomExecutionOutput
{

#

cause these are marked as bp types

#

you can literally pass these out

#

and make wrapper funcs

#

unlike what was done in your example

cold tree
#

oh, I didn't see the output was

#

I assumed it wasn't as the in param wasn't

#

yeah, good point

shell crypt
#

that could be a better PR

#

for making executions BP accessible

cold tree
#

yeah

shell crypt
#

let me actually think about it

#

and have a play

#

maybe engine can have a BPExecutionWrapper

#

class

#

to avoid bloating the original EffectExecution

#

bit like how Behaviour tree does it

#

like UBTDecorator_BlueprintBase

#

is a wrapper for BP based bt decorators

#

same can be applied for EffectExecutions without touching any of the original

cold tree
#

could

shell crypt
#
/**
 *  Base class for blueprint based decorator nodes. Do NOT use it for creating native c++ classes!
 *
 *  Unlike task and services, decorator have two execution chains: 
 *   ExecutionStart-ExecutionFinish and ObserverActivated-ObserverDeactivated
 *  which makes automatic latent action cleanup impossible. Keep in mind, that
 *  you HAVE TO verify is given chain is still active after resuming from any
 *  latent action (like Delay, Timelines, etc).
 *
 *  Helper functions:
 *  - IsDecoratorExecutionActive (true after ExecutionStart, until ExecutionFinish)
 *  - IsDecoratorObserverActive (true after ObserverActivated, until ObserverDeactivated)
 */
#

like this is what the BP version has

#

it specificialy says for BP use only

#

do not make native from it

#

let me come up with a proof of concept for it

#

cause i feel that maybe a useful PR

cold tree
shell crypt
#

ofc

cold tree
#

we can't do anything with it stock

shell crypt
#

thats the idea of making a bp wrapper class

#

you shouldnt really be modifiying stuff directly like this

cold tree
#

talkling about /** Struct representing the output of a custom gameplay effect execution. */ USTRUCT(BlueprintType) struct FGameplayEffectCustomExecutionOutput

#

that's why we had a map before, which was parsed and moved over to OutExecutionOutput

#
void UBPGameplayEffectExecutionCalculation::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams, OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
    FBP_ExecutionParams BlueprintParams{};
    ConvertExecutionParams(ExecutionParams, BlueprintParams);

    if (!BlueprintParams.SourceAbilitySystemComponent || !BlueprintParams.TargetAbilitySystemComponent)
    {
        return;
    }

    const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
    TMap<FGameplayAttribute, FBP_ModifierInfo> BlueprintModifiers{};
    
    BPExecute(
        ExecutionParams,
        BlueprintParams,
        Spec,
        Spec.GetEffectContext(),
        *Spec.CapturedSourceTags.GetAggregatedTags(), // Always valid
        *Spec.CapturedSourceTags.GetAggregatedTags(), // Always valid
        BlueprintModifiers
        );

    if (BlueprintModifiers.IsEmpty())
    {
        return;
    }

    for (const auto& BpMod : BlueprintModifiers)
    {
        if (!BpMod.Key.IsValid())
        {
            UE_LOG(LogAbilitySystemComponent, Warning, TEXT("%s::Execute_Implementation - Attr %s: Invalid attribute, ignore"), *this->GetName(), *BpMod.Key.GetName());
            continue;
        }
        
        // Validate Magnitude
        if (!FMath::IsFinite(BpMod.Value.Magnitude))
        {
            UE_LOG(LogAbilitySystemComponent, Warning, TEXT("%s::Execute_Implementation - Attr %s: Magnitude is not finite, ignore"), *this->GetName(), *BpMod.Key.GetName());
            continue;
        }

        // Output values
        OutExecutionOutput.AddOutputModifier(
            FGameplayModifierEvaluatedData(
                BpMod.Key,
                BpMod.Value.ModifierOp,
                BpMod.Value.Magnitude
            )
        );
    }
}```
#
    const FGameplayEffectCustomExecutionParameters& ExecutionParams,
    const FBP_ExecutionParams& InParams,
    const FGameplayEffectSpec& Spec,
    const FGameplayEffectContextHandle& EffectContextHandle,
    const FGameplayTagContainer& SourceTags,
    const FGameplayTagContainer& TargetTags,
    UPARAM(ref) TMap<FGameplayAttribute, FBP_ModifierInfo>& OutModifiers) const
{
}```
#

I'll leave it as is for now until i'll have time to come up with a better solution

shell crypt
#

right but again not sure we have to be this specific about it

cold tree
#

I kinda hate to have to create more convenience just to accomodate structs being so locked in bp

shell crypt
#

cause the way i see it, the function should be overridable

#

and should return some values also like ShouldTriggerCues, etc

#

cause there is a bit more to it

#

also

cold tree
#

it is right now in the current Exec. The only thing is both output and the execution parameters can't be handled in BP

#

yeah, there is a bit more

#

although, I kinda noticed them rn ๐Ÿ˜„

#

basically ... make every method under FGameplayEffectCustomExecutionOutput as static convenience functions

#

o/

#

Hate a bit that the output is an array too

#

UE_API const TArray<FGameplayModifierEvaluatedData>& GetOutputModifiers() const;

#

I mean, it's not a big deal, but it also sucks if you ever want to find a value in there.
Which is probably never happening ... ๐Ÿ˜„

#

@shell crypt

    void BPExecute(
        const FGameplayEffectCustomExecutionParameters& ExecutionParams,
        const FBP_ExecutionParams& BPExecutionParams,
        const FGameplayEffectSpec& Spec,
        const FGameplayEffectContextHandle& EffectContextHandle,
        const FGameplayTagContainer& SourceTags,
        const FGameplayTagContainer& TargetTags,
        UPARAM(ref) FGameplayEffectCustomExecutionOutput& OutExecutionOutput
        ) const;
    
    UFUNCTION(BlueprintCallable, Category = "ExecutionCalculation")
    static void AddOutputModifier(
        UPARAM(ref) FGameplayEffectCustomExecutionOutput& ExecutionOutput,
        FGameplayAttribute Attribute,
        TEnumAsByte<EGameplayModOp::Type> ModifierOp,
        float Magnitude
        );```
#

Not commited yet, but seems to be working

#

no more proxy bp structure

#

those should be BP exposed

#

and not private ... ๐Ÿ˜„

shell crypt
#

ah but

#

you can call a function to mark it

cold tree
#

yeah, but would have been easier, that's it

#

that's what I'll add too

shell crypt
#
    /** Mark that the execution has manually handled the stack count and the GE system should not attempt to automatically act upon it for emitted modifiers */
    void MarkStackCountHandledManually();
cold tree
#

or one that is BP exposed, and just set the values

shell crypt
#

you just call this from your helper funcs

cold tree
#

I'll do that later on

cold tree
#

assuming Epic never does it, at least, we have one version that works ๐Ÿ™‚

#

take care !

#

thanks for the feedback btw

shell crypt
#

ill show you what i kinda was working on but like i said needs to be more fleshed out

#

if your interested

cold tree
#

that's cool too !

#

Yeah, I see what you meant by Wrapper

#

that would work too. probably a bit more complex to handle but all in all, similar

#

I was gonna let people use the evaluate from the target / source asc with the tags if they want to

#

which is similar, except for the capture

cold tree
shell crypt
#

Sure but the idea is to allow basically everything to be done I'm bp that cam be done

#

Without holding bp users hand