Download

RootComponent issue when converting to blueprint

Hi All,

I have a strange issue affecting the RootComponent when I convert/create a blueprint from my C++ class, basically in my constructor I create some components, assign a spherecollider as the RootComponent and attach some other components to it, then in my Tick() function I check the RootComponent pointer is a specific component before carrying out some logic, its from a custom movable tutorial, here is the affected code:

Constructor:



	// Our root component will be a sphere that reacts to physics
	mFlyCollision = CreateDefaultSubobject<USphereComponent>(TEXT("FlyCollisions"));
	RootComponent = mFlyCollision;
	mFlyCollision->SetSphereRadius(40.f);
	mFlyCollision->SetCollisionProfileName(TEXT("Pawn"));

	// Pivot/Offset for pitching camera
	mPivot = CreateDefaultSubobject<USceneComponent>(TEXT("WalkCamPivot"));
	mPivot->SetRelativeLocation(FVector::ZeroVector);
	mPivot->SetupAttachment(RootComponent);

	// Our root component will be a sphere that reacts to physics
	mWalkCollision = CreateDefaultSubobject<UCapsuleComponent>(TEXT("WalkCollisions"));
	mWalkCollision->InitCapsuleSize(20.f, 88.f);
	mWalkCollision->SetCollisionProfileName(TEXT("Pawn"));

	// Create a camera and attach to our spring arm
	mViewCam = CreateDefaultSubobject<UCameraComponent>(TEXT("ViewCamera"));
	mViewCam->AttachToComponent(mPivot, FAttachmentTransformRules::KeepRelativeTransform);
	
	// Create an instance of our movement component, and tell it to update the root.
	OurMovementComponent = CreateDefaultSubobject<UWB3DCamMovementComponent>(TEXT("FlyCollideMovement"));
	OurMovementComponent->mMaxSpeed = mMaxMoveSpeed;
	OurMovementComponent->SetUpdatedComponent(RootComponent);

Tick:


if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
	{
	}

This works fine as a C++ class, however if I create a blueprint from this class, the comparison check fails in Tick() because the RootComponent points to the FlyCollideMovement component, which happens to be the last created component in the constructor. I can get around the issue by assigning the OurMovementComponent->UpdatedComponent pointer in BeginPlay() but my question is why is this the case and is there some hidden reason for it which I should be aware of for future bug hunting…?

Thanks, Sticky.

Everything that happens in C++ constructor is pre-BP initialization, you should only expect BP exposed pointers to be pointing to the right things in PostInitComponents() in C++ or in BP you should use BeginPlay or the BP constructor.

I dont precisely understand your case, but basically know that you can never expect BP to understand anything until after PostInitComponents() runs, and then after that c++ BeginPlay(), C++ Constructor is pre-BP. :slight_smile:

Rama

Excellent, that makes sense, thanks for the clarification! :slight_smile: