Download

Is it possible to change character's movement component at runtime?

Greetings,

I have implemented a few different custom character movement components for different movement styles (such as Quake strafe jumping, Quake bunny hopping, Quake crouch sliding, etc), and I want my character to be able to switch between different movement styles in game. But it looks like I can only instantiate the movement component sub-object in character’s constructor like this:

AQLCharacter::AQLCharacter(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer.SetDefaultSubobjectClass<UQLMoveComponentQuake>(ACharacter::CharacterMovementComponentName))
{
    ...
}

That restricts the movement component to one class only. My current makeshift approach is messy: just adding a lot of if(MovementStyle == option 1) ... else if(MovementStyle == option 2) ... to UQLMoveComponentQuake's methods, and changing the MovementStyle variable at runtime. How should I go about having a more elegant solution? Thanks for any advice!

That’s how CharacterMovementComponent does it. There’s a CustomMovementMode that you can set, which you then do a switch() on and decide what to do there.

I don’t know the ins and outs of what accesses MovementComponent, but I don’t see any reason why you couldn’t do what you want to do.

If there is something preventing that, then you could subclass CharacterMovementComponent, and have it call to your custom MovementComponents

Do you have a reason for needing to separate these movement modes into separate sub-classes? Unless you’re creating a modular movement mode system, in which you want to be able to add movement mode components onto different characters (ie. Add on a FlyingMovementComponent to allow a character to fly). I think you’re making more work for yourself.

If you’re just building a single character movement then you’re better of containing those movement modes inside a class derived from CharacterMovementComponent and overriding the CustomMovementMode in that. It’s not really messy since you still separate it out into independent functions (ie. PhysJump(), PhysCrouchSlide() etc.).

However if you really do want to use separate MovementComponents for different MovementModes then you need to override the CharacterMovement component in the ACharacter class.

The default character movement component is created in ACharacter on line.85 as such:

CharacterMovement = CreateDefaultSubobject<UCharacterMovementComponent>(ACharacter::CharacterMovementComponentName);

so I would suggest creating multiple default subobjects and then switching out the CharacterMovement variable based on user input.

HOWEVER this will get really complicated really fast, so please please do think about whether you really need to go to this level of division in your movement modes, as for most use-cases this is definitely overkill.

An alternative solution if you still want to separate movement modes into sub-classes, would be to use a single CharacterMovementComponent and create default subobjects from there, and then switch between the active MovementModeComponent within your CharacterMovementComponent which would be like a hybrid version of the CharacterMovementComponent while using your subclasses.

However, even this is overkill if it’s a single character behaviour you’re making, and not some complex modular or procedural character generation system. So please consider the initial decision of simply overriding the CharacterMovementComponent and overriding the functions there for things like PhysWalking, PhysFlying, and PhysCustom.

Hope this helps,

Tim