Replacing components in child classes

Hi there guys, I’ve had a query running around my head for a while, I have the need to edit both the CharacterMovementComponent and PathFollowingComponent. In the project I’m working on I’ve been simply editing the source code, which I feel is bad practice. I’d much rather be simply inheriting from them, the issue comes up with inherting, then, from character/AIController which both build in these components and make them private access.

If I were to not make them private, would it even work that in the class constructor I simply “replace” the component with a childed version?

Example:

ACharacter.h{
...
/*(was private)*/protected :
UCharacterMovementComponent* CharacterMovement;
...
}

ACharacter.cpp{
    ACharacter::ACharacter(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
    {
           ....
           CharacterMovement = CreateDefaultSubobject<UCharacterMovementComponent>(..
    }
}

AMyCharacterOverrideClass.cpp{
    AMyCharacterOverrideClass::AMyCharacterOverrideClass(const FObjectInitializer& objectInitializer) : 
        Super(objectInitializer)
    {
           CharacterMovement = CreateDefaultSubobject<USomeChildOfCharacterMovementComponent>
               (..
    }
}

I don’t like the idea of having to hack into the base classes at all to set values to protected, but it seems better than making large changes frequently to the path following component and character movement, and having to recompile the whole engine (and everyone on my team’s) every time I make a change. Is this something that’s even possible? Will it cause horrible unforseen issues like the original character movement component hanging about in memory for reasons beyond my understanding?

From my understanding you don’t need to declare it protected but can leave it private. The idea is something like this:

// ACharacter.h
static FName CharacterMovementComponentName; // set to some arbitrary name
private:
UCharacterMovementComponent* CharacterMovement;

// ACharacter.cpp
ACharacter::ACharacter(const FObjectInitializer& ObjectInitializer)
  : super(ObjectInitializer)
{
  CharacterMovement = CreateDefaultSubobject<UCharacterMovementComponent>(CharacterMovementComponentName);
  // ...
}

// AMyCharacter.cpp
AMyCharacter::AMyCharacter(const FObjectInitializer& ObjectInitializer)
  : super(ObjectInitializer.SetDefaultSubobjectClass<UMyCharacterMovementComponent>(CharacterMovementComponentName))
{
  // ...
}

This way the constructor of ACharacter does the assignment and the variable can remain private.

1 Like

That seems to have worked perfect, thanks so much for that!