I went back to this as I just hate random weirdness and being able to re-use classes like this is one of the major reasons to do it in C++ in the first place. Couldn’t find a fix I think that needs to come from Unreal but happy to be corrected if I missed something! but I do have a work around.
The workaround shows an additional major benefit of all the hard work refactoring and decoupling the code into sub object. That being reuse, it’s even more exciting than refactoring we have just created 2 sub components that with a bit of extra tweaking we could drop on any actor we want to have movement or movement replication, that’s super cool.
So currently we are creating the sub objects in the constructor of the parent class GoKart.cpp then the child class (BP_GoKart) is doing the rest this is where Unreal says to do it from what I can see but… This is where this issues happen in development, when you compile it can get into a really weird state where it doesn’t register properly in the child but doesn’t fail compile either. Eventually after plenty of button mashing and restarting and re-compiling code and blueprint you get lucky and the timing works and it sorts it self out then its stable from what I can see. I would bet creating something new relying on these classes if they had not been recompiled works fine but that’s not what we are doing.
Not great when you are doing rapid iterative development cycles.
The workaround
Remove the sub component create from the constructor in GoKart.cpp
AGoKart::AGoKart()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//make sure it replicates
bReplicates = true;
//MovementReplicator = CreateDefaultSubobject<UGoKartMovementReplicator>(TEXT("MovementReplicator"));
//MovementComponent = CreateDefaultSubobject<UGoKartMovementComponent>(TEXT("MovementComponent"));
}
Add the creating using the find class method to BeginPlay in GoKart.cpp
void AGoKart::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
NetUpdateFrequency = 1;
}
MovementComponent = FindComponentByClass<UGoKartMovementComponent>();
MovementReplicator = FindComponentByClass<UGoKartMovementReplicator>();
if (IsValid(MovementComponent))
{
UE_LOG(LogTemp, Warning, TEXT("Movement Component Loaded"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Movement Component Not Loaded"));
}
if (IsValid(MovementReplicator))
{
UE_LOG(LogTemp, Warning, TEXT("Replicator Component Loaded"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Replicator Component Not Loaded"));
}
}
Then recompile everything, the inherited sub components will now have gone from the BP_GoKart blueprint
Use addcomponent to re-add them in the blueprint this is why we move to beginplay as they wont be available for the constructor parent class.
recompile the blueprint
If all has gone well it should all start working and be reliable when you update the subcomponents as well.
Would love to hear if anyone has a better solution!