Live Coding has corrupted my project - unremovable components

Hi,

I made a mistake of accidentally running live coding a few times before turning it off. I have base actor class in my game called RTSActor, and at one point in time I added a StaticMeshComponent called “StatusPlaneMesh” to it and ran the live coding. I added it using CreateDefaultSubObject() in the constructor, and called AddInstanceComponent() so that it correctly shows in the level editor component list. Everything worked well so I carried on working.

About 2 weeks later, I decided to make some changes to the actor structure, and I have removed StatusPlaneMesh and rebuilt the code. The StatusPlaneMesh component has remained in the two fundamental BP classes which derive from RTSActor class. It was in the component list, but the properties panel was empty. There was no way to remove it, since it was displayed as inherited C++ component.


image

I tried running various unregistering/component deleting method in the class constructor without any luck. I tried reparenting the BP classes to Actor and back to RTSActor, but even when I reparented the BP class to Actor, the StatusPlaneMesh component remained in the blueprint.

When I created a new BP class from scratch inheriting from RTSActor, the StatusPlaneMesh component was no longer there. But my BP classes (Building and Unit) were so fundamental to the project they were really heavy and referenced on many places. Recreating both BP classes from scratch would be very lengthy and extremely error prone, and would probably cause quite a few bugs for weeks to come.

I tried way too many things but nothing helped. Eventually, I decided to bite the bullet and spent couple of days reimplementing these two classes and replacing their references in about 20-30 classes. It was painful, but it worked, almost… For some reasons, bounds of my actors were wrong. When I started to debug using some logging I was shocked:

LogBlueprintUserMessages: [BPC_ConstructionManager] RootMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] StatusPlaneMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] PavementDecal
LogBlueprintUserMessages: [BPC_ConstructionManager] RootMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] StatusPlaneMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] PavementDecal
LogBlueprintUserMessages: [BPC_ConstructionManager] RootMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] StatusPlaneMesh
LogBlueprintUserMessages: [BPC_ConstructionManager] PavementDecal

The StatusPlaneMesh was still there, just not visible anywhere, not in the BP editor, not in the level editor, but internally still there, messing up the bounds of all the actors. Even when I crated completely new separate BP from scratch and ported the logic one function and variable at the time, the ghost StatusPlaneMesh still managed to somehow infect the new class like cancer. I again tried to reparent the BP class to just Actor, compiled it, saved it, ran the game, yet the component is still there.

This is the game:

I’ve spent on and off about 3 years making it. I was already close to having playable prototype in spring of next year, but this sets me back quite a bit.

“Why don’t you have version control backup?”
…because I work on the project as one man team. I though backing up regularly on GoogleDrive using powershell script should do the trick, since there was very little non-binary file data code. I always made sure to only backup the game at stable and reliable increments, but quite frequently. The issue here arose from the fact that for 2 weeks, I wanted the StaticMeshComponent to exist. Even if I used version control, I would have lost at least 2 weeks of work between the point of first adding the component to the base C++ class and then removing it. But I have learn my lesson to not trust UE again, so I will setup version control when/if I ever solve this.

Does anyone have any idea how to solve this? How to get rid of the ghost component that exists in the class (not just its instances), but is not visible anywhere? If not, I have no clue what to do…

I am back! With answers! :grimacing:

Big thanks to @Ysgrathe for help with this.

If you ever run into this issue of unremovable components caused by creating components in the C++ class constructor and removing them later, here’s what to do:

  1. Add the component of the same UPROPERTY name and same Component name again but change it’s type. So for example if you had:
.h:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
TObjectPtr<class UStaticMeshComponent> RootMesh = nullptr;
.cpp:
RootMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("RootMesh"));

then reintroduce the component as different class:

.h:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
TObjectPtr<class UBillboardComponent> RootMesh = nullptr;
.cpp:
RootMesh = CreateDefaultSubobject<UBillboardComponent>(TEXT("RootMesh"));
  1. Build the code, and run the editor and recompile and resave all the BP classes which got corrupted by the unremovable component. This doesn’t mean just parent classes, but any classes that inherit from the C++ class even indirectly. So in my case for example. If BP_Building inherited from the culprit C++ class, I had to recompile and resave not only BP_Building but also all the classes inheriting from BP_Building, and so on…

  2. Remove the component definition and creation from the header and cpp.

  3. Build and run again, the component should be finally gone!

1 Like