UPROPERTY component gets automatically attached to actor and crashes

Hi there guys, i’m baffled… hope you can help me out.

First of all, i’m creating a component that’s called ChannelSwitchableLightComponent, basically is a light component with a Channel index that can be called to trigger every component with the same channel. The object is as follow

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UChannelSwitchableLightComponent : public USceneComponent, public ISwitchableByChannelInterface
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UChannelSwitchableLightComponent();

	// Called when the game starts
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;

	virtual uint8 GetChannel() override;
	virtual void On() override;
	virtual void Off() override;

	//For constructing on editor
	virtual void OnRegister() override;
	virtual void OnUnregister() override;

	//The channel on which this light listens
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	uint8 Channel;

	//The light component to use
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	ULightComponent *LightComponent;
};

The ULightComponent appears in unreal editor, and it lets me choose from PointLight and others type of ULightComponent which is awesome.
The editor though automatically attaches the LightComponent to my actor and i would like it to be attached to my component instead so i did this.

void UChannelSwitchableLightComponent::OnRegister()
{
	Super::OnRegister();
	
	bool found = false;
	for (int i = 0; i < AttachChildren.Num(); i++)
	{
		UActorComponent *children = AttachChildren[i];
		if (children->IsA<ULightComponent>())
		{
			if (children != LightComponent)
				children->DestroyComponent();
			else
				found = true;
		}
	}

	if(LightComponent != nullptr && found == false)
		LightComponent->AttachTo(this);
}

Maybe not the most beautiful implementation (if there is another way i’ll gladly change this), but this let me attach the light component to my own component.

The problem raises with blueprints… (on plain components it works).

  1. If i try to add my component to a blueprint, and try to set the LightComponent to any value, it crashes with the message: “Template Mismatch during attachment. Attaching template component to instanced component.”

Here we can see it crashes at the moment it enters this piece of code on Register

if(LightComponent != nullptr && found == false)
         LightComponent->AttachTo(this);
  1. If i do this on an instance instead, it does not crash on this point, but it crashes in the moment i do any change that would trigger PostEditChangeProperty, because the Actor->GetRootComponent() fails the Assertion
    this is on the file
    ComponentInstanceDataCache.cpp
    on the FComponentInstanceDataCache::ApplyToActor method
    the line that fails is
    check(Actor->GetRootComponent());

I really don’t know what to do… am i doing something wrong at trying to attach the component, should i use a different aproach?
is there a way to make the user choose a type of light component to use and then instantiate it and attach it with no problems?

If you have crash always look up logs in Saved/Logs in project directory. Most crashes are controlled crashes when something is about to go wrong and UE4 leaves message about it in logs, so go there and the end of log

Here’s what it says

LogEditorViewport: Clicking on Actor (LMB): Samsung_LED_TV_Blueprint_C (Samsung_LED_TV_Blueprint)
[2015.12.16-04.23.57:979][461]LogSCSEditor:Warning: Calling UpdateTree() from Tick() more frequently than expected due to invalid tree node state. This might be a performance issue.
[2015.12.16-04.24.12:494][678]PIE:Warning: Warning AttachTo: ‘/Game/Pieza.Pieza:PersistentLevel.Samsung_LED_TV_Blueprint_40.Samsung_LED_TV’ already attached to ‘/Game/Pieza.Pieza:PersistentLevel.Samsung_LED_TV_Blueprint_40.ChannelSwitchableLight’, would form cycle. Aborting.
[2015.12.16-04.24.18:388][678]LogWindows:Error: Windows GetLastError: The operation completed successfully. (0)
[2015.12.16-04.24.18:388][678]LogCrashTracker:

[2015.12.16-04.24.18:388][678]LogWindows:Error: === Critical error: ===
Assertion failed: Actor->GetRootComponent() [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.10\Engine\Source\Runtime\Engine\Private\ComponentInstanceDataCache.cpp] [Line: 231]

[2015.12.16-04.24.18:513][678]LogExit: Executing StaticShutdownAfterError
[2015.12.16-04.24.18:516][678]LogWindows: FPlatformMisc::RequestExit(1)
[2015.12.16-04.24.18:517][678]Log file closed, 12/16/15 01:24:18

Ok let me explain this crash, it continuation of what i said comments :slight_smile:

What you have here it’s so called assertion fail, engine code is filled with self checks, checking if condition is as expected to be by farther code. It using check(x) function where x is bool condition (same as you use in “if”), if condition is false it will crash the engine and print the condition that failed (they can have custom errors but most of them don’t have it). it sounds crazy but there is good resoning behind it, your code is running direcly on CPU in as native machine code (C++ code lose it’s form once it is compiled, it’s compiled to native CPU code that executes in it), because of that if somethign whents wrong it crashes without much information, sometimes after series of misleading computations which makes uncontrolled crash a lot harder to debug, so insted of letting that happens UE4 code as predetermined asserts and if they fail it crashes engine now insted of risking hard to debug uncontrolled crash. here oyu have wiki if you want to learn more of this concept:

Now you case is pretty easy, your assert condition is:

Actor->GetRootComponent()

Which simply means root component is not exist :slight_smile: either in constructor where you define components do RootComponent = SomeComponent to declere it root component, or you destroyed root component.

In somecases to decode the assert fail you need to check the code where that happeded, surrounding code should hint what when wrong. YOu assert erro direclly poiunts where it happened:

[File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.10\Engine\Source\Runtime\Engine\Private\ComponentInstanceDataCache.cpp] [Line: 231]

If you don’t have any info in log and it like cutted log it means uncontrolled crash happened, in most cases it is either
call on null pointer (object varable) or call on invalid pointer (not null pointer but object that you calling was destroyed) or failed invalid native cast.

The problem is that i never desassign the RootComponent. I guess the clue is in here

Warning AttachTo: ‘/Game/Pieza.Pieza:PersistentLevel.Samsung_LED_TV_Blueprint_40.Samsung_LED_TV’ already attached to ‘/Game/Pieza.Pieza:PersistentLevel.Samsung_LED_TV_Blueprint_40.ChannelSwitchableLight’, would form cycle. Aborting. [2015.12.16-04.24.18:388][678]LogWindows:Error: Windows GetLastError: The operation completed successfully. (0) [2015.12.16-04.24.18:388][678]LogCrashTracker:

The blueprint tries to set the light component to the actor and aborts as i already set the parent as my component. But i don’t know in which part the actor blueprint sets itself as the parent of the ULightComponent that my component sets as property… any ideas?

Hello ,

It would most likely be better to focus on why the ULightComponent attaches directly to the actor and preventing that rather than needing a workaround, presumably avoiding the crash entirely. Would it be possible for you to upload all of the code (the .cpp basically) for this custom component so that I can take a look for what may be causing this?

Of course, here are the sources of the project I Commented the workaround, you can see that if you add the ChannelSwitchableLightComponent to a Blueprint, set the LightComponent property and then move it, it first throws the warning on this line of code:

SceneComponent.cpp Line 1173 (tries to attach the blueprint as child of the LightComponent, then aborts because it would form a cycle). This only happens on blueprints

https://www.dropbox.com/s/h077cjmkdw9zjw3/Source.?dl=0

Cheers!

On another ActorComponent, newly created i added a UPROPERTY component, when i fill the value on the editor, this Property Component gets not only ATTACHED to the Actor but becomes the new ROOT, and because this is NATIVE code it won’t let me change anything. I believe this to be a bug, any ideas?

I’m trying to figure out why the UPROPERTY specifier isn’t being recognized but it seems like you can get the LightComponent by adding these two line to the UChannelSwitchableLight component’s constructor.

LightComponent = CreateDefaultSubobject<ULightComponent>(TEXT("LightComponent"));
LightComponent->AttachTo(this);

I’ll continue looking into the UPROPERTY part and get back to you when I find something.

Well that wasn’t thorough now was it? Got the same crash you did upon attempting to choose a specific light type. I’ll keep looking into it.

Thanks, for the moment i won’t be using this implementation because it creates way too much errors.
There’s another one when replicating an object (non blueprint) which has this component via alt+drag, the light component doesn’t replicate and if you don’t set it right away it will crash.

Greetings