#Tags based movement speed modifier with mover

1 messages ยท Page 1 of 1 (latest)

rare marlin
#

so

#

here is what ive done so far
ive tested this with my movementstate based ability(walk, run,sprint) and and right now, its working ish with i handle the calculation inside my executioncalculation and use that movementspeed attribute and calculate that with modifier

#

this my my based charactermovementstateability

#

here my sprint ability that use that parent class

#

now for sprint, havent get it to fully working yet as inputhold type ability, i need to feed into movermodifier but that can be take care later

#

here my walkrun ability which great for this tagsbased solution

#

and here is where the attribute is calculated
here my executions

#

and that the attribute is set in my characterattributeset

#

damn i cannot forwards exisitng message into a thread :/

#

so from what i found with what i do now is if i apply the ability that apply the charactermovementstate ability, it will apply loose tags that my executioncalc will listen to

#

based on that, it will interate and get the multiplier to adjust the movementspeed attribute

#

and then in postgameplayeffectexecute in characterattributeset, on movementspeedattribute we will apply to movercommonlegacysettings maxspeed and acceleration to adjust the playerspeed

#

PROBLEMS:

#

input hold based ability wont work as attribute is applied ONCE even though input havent been released yet

#

previously, i use mover movement modifier and it will continuosly apply the modfiier UNTIL i inputreleased and end the ability there which clear up the handle and eveyrthing

#

here how it done previously

#

now my current solution is based on kaos dmage resistance blog

opal comet
#

For State-Based Movement (Walk/Run):

  • Use GAS attributes with execution calculations (your current approach)
  • Apply permanent/duration-based GameplayEffects

For Input-Hold Movement (Sprint):

  • Use Mover movement modifiers for continuous application
  • Apply loose tags via GameplayEffects for the modifier to read
#
// MovementSpeedExecutionCalculation.h
UCLASS()
class UMovementSpeedExecutionCalculation : public UGameplayEffectExecutionCalculation
{
    GENERATED_BODY()

public:
    UMovementSpeedExecutionCalculation();
    virtual void Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams, OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const override;

private:
    FGameplayEffectAttributeCaptureDefinition MovementSpeedDef;
};

// MovementSpeedExecutionCalculation.cpp
void UMovementSpeedExecutionCalculation::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams, OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
    const FGameplayTagContainer* SourceTags = ExecutionParams.GetSourceTags();
    const FGameplayTagContainer* TargetTags = ExecutionParams.GetTargetTags();

    FAggregatorEvaluateParameters EvaluateParameters;
    EvaluateParameters.SourceTags = SourceTags;
    EvaluateParameters.TargetTags = TargetTags;

    float BaseMovementSpeed = 0.0f;
    ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(MovementSpeedDef, EvaluateParameters, BaseMovementSpeed);

    // Calculate multiplier based on movement state tags
    float MovementMultiplier = 1.0f;
    
    if (TargetTags->HasTagExact(FGameplayTag::RequestGameplayTag(TEXT("MovementState.Walk"))))
    {
        MovementMultiplier = 0.5f;
    }
    else if (TargetTags->HasTagExact(FGameplayTag::RequestGameplayTag(TEXT("MovementState.Run"))))
    {
        MovementMultiplier = 1.0f;
    }

    float FinalMovementSpeed = BaseMovementSpeed * MovementMultiplier;
    OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UYourAttributeSet::GetMovementSpeedAttribute(), EGameplayModOp::Override, FinalMovementSpeed));
}
#
// SprintMovementModifier.h
UCLASS()
class USprintMovementModifier : public UBaseMovementModifier
{
    GENERATED_BODY()

public:
    virtual bool OnGenerateMove(const FMoverTickStartData& StartState, const FMoverTimeStep& TimeStep, FProposedMove& OutProposedMove) const override;
    virtual void OnSimulationTick(const FMoverTickStartData& StartState, const FMoverTimeStep& TimeStep, FMoverTickEndData& OutputState) const override;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    float SprintMultiplier = 2.0f;

private:
    bool ShouldApplySprintModifier(const FMoverTickStartData& StartState) const;
};

// SprintMovementModifier.cpp
bool USprintMovementModifier::OnGenerateMove(const FMoverTickStartData& StartState, const FMoverTimeStep& TimeStep, FProposedMove& OutProposedMove) const
{
    if (!ShouldApplySprintModifier(StartState))
    {
        return false;
    }

    // Apply sprint speed modification
    OutProposedMove.LinearVelocity *= SprintMultiplier;
    return true;
}

bool USprintMovementModifier::ShouldApplySprintModifier(const FMoverTickStartData& StartState) const
{
    // Check for sprint tags from GAS
    if (const APawn* Pawn = StartState.MovementComponent->GetPawnOwner())
    {
        if (const IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(Pawn))
        {
            if (UAbilitySystemComponent* ASC = ASI->GetAbilitySystemComponent())
            {
                return ASC->HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag(TEXT("MovementState.Sprint")));
            }
        }
    }
    return false;
}
#

GameplayEffect Setup:

  • Create a SprintTagEffect (Duration-based):
  • Duration Policy: Has Duration
  • Duration Magnitude: Infinite (or very long)
  • Granted Tags: MovementState.Sprint
  • No attribute modifiers needed - the modifier reads the tag directly
wide cradle
#

Why not simply use an abiity and its "WaitInputRelease" node ? Or does that not work with Mover?

#

i have my sprint that way and it works

#

im cmc though

wide cradle
#

also @opal comet Sry for the ping, was just wondering, one can apply exec calcs directly to attributes? Or what did you mean by "using gas attributes with exec calcs) , dont we need a GE in order to have exec calcs modify that?

#

(unrelated to his issue)

opal comet
wide cradle
#

Oh okay so just use them as regular intended gas way

opal comet
#

reading through the gameplay ability that is attached below notes the gameplay effect that is added ๐Ÿ˜„

opal comet
rare marlin
#

@opal comet @wide cradle @primal delta so yesterday and today i sat down and rethink this from scratch.
i was thinking, how about i always make this modfiier ALWAYS active and we never need to remove them and it will ONLY listen to any gameplaytag added and if that tag is added, do the calculation.

this is without GAS and purely mover.

this is a bit working but right now, having problem with registering the tag and adjusting the mover movementspeed based on the tag. the idea is still the same from previous example implementation i gave using GAS

this way, the modfiier ONLY need to listen to any tag added and do the calculation inside it and encapsulate the behaviour to outside GAS.

here my current atempt

#

im using a component rn to keep track of these tags changes

#

still W.I.P

#

tbh i think i am overcomplicated this as ive been working on this since last week

#

tbh i think i am at the point where i have no idea what the best approach to go. i would love to merge all of this solution together

#

thats enough rambling for today

#

prob will try again tomorrow with a fresh mind

primal delta
#

Exec won't be predicted at all, so you'll end up with frequent desync

opal comet
#

Excellent point, could use a ability task then to aid in the sync / prediction

primal delta
#

if its just for tags, just local determination on both client and server is enough

rare marlin
primal delta
#

alright ๐Ÿ™‚

rare marlin
#

@primal delta hey again, so an update, finally have a working 1.0 version of this modfiier ๐Ÿ˜„

#

now have to figure out the horrible tagrelationship that have in each ability right now using tagrelationshipmapping

#

dang took me another day to built it from scratch, finnaly found the middle ground that i like that combine mover movementmodifier and GAS