Unable to pinpoint crash source

Hi,

I currently am working on a c++ door system. My current setup is made of two classes, AAutomatedDoorFramework and AADoor.

AADoor contains several functions to setup the door movement and actually run it (with Tick()). AAutomatedDoorFramework is supposed to instance it.

Here’s a code snippet :
AutomatedDoorFramework.h

UCLASS()
class DOORFRAMEWORK_API AAutomatedDoorFramework : public AActor
{
	GENERATED_BODY()
        ....
public:
	/*Door class*/
	UPROPERTY()
	class AADoor* DoorComponent;
        ...
}

AutomatedDoorFramework.cpp

AAutomatedDoorFramework::AAutomatedDoorFramework(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	//Door
	if (this->DoorComponent == NULL)
	{
        //Commenting this line results in no crash : problem is here
		this->DoorComponent = ObjectInitializer.CreateDefaultSubobject<AADoor>(this, "DoorComponent");
	}
    ...
}

ADoor.cpp

AADoor::AADoor(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	this->DoorHolder = ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, "Door Holder");
	this->RootComponent = this->DoorHolder;
	//Mesh init
	this->DoorMeshComponent = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, "DoorMeshComponent");

	//Timer init
	this->PrimaryActorTick.bCanEverTick = true;
	AADoor::SetActorTickEnabled(false);

	//Door movement init
	this->DoorState = EDoorState::DOWN;
	this->DoorPriority = EDoorPriorities::NONE;

	this->bUpRequest = false;
	this->bDownRequest = false;
}

AFAIK, the ObjectInitializer will call AADoor’s constructor in some way. However the crash report doesn’t seem to say that the problem was in the constructor :

MachineId:107F56DC41D1B594D26F1E9FD1217471 EpicAccountId:8d743fd0c5244c14b9b690ddf50864e8 Unknown exception - code 00000001 (first/second chance not available) Fatal error: [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.6\Engine\Source\Runtime\CoreUObject\Private\Templates\Casts.cpp] [Line: 11] Cast of AutomatedDoorFramework //Script//DoorFramework.Default__AutomatedDoorFramework to Level failed KERNELBASE + 37901 bytes UE4Editor_Core + 3092349 bytes UE4Editor_Core + 1597391 bytes UE4Editor_CoreUObject + 369143 bytes UE4Editor_Engine + 950092 bytes UE4Editor_Engine + 2406333 bytes UE4Editor_Engine + 10023998 bytes UE4Editor_Engine + 9907821 bytes UE4Editor_Engine + 9802856 bytes UE4Editor_Engine + 9482907 bytes UE4Editor_UnrealEd + 1700495 bytes UE4Editor_UnrealEd + 1691531 bytes UE4Editor_UnrealEd + 6487693 bytes UE4Editor!FEngineLoop::Init() + 1147 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\launchengineloop.cpp:1919] UE4Editor_UnrealEd + 6308564 bytes UE4Editor!GuardedMain() + 285 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\launch.cpp:123] UE4Editor!GuardedMainWrapper() + 26 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\windows\launchwindows.cpp:126] UE4Editor!WinMain() + 249 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\windows\launchwindows.cpp:202] UE4Editor!__tmainCRTStartup() + 329 bytes [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c:618]

I’ve been fiddling with this for quite some time, but am still quite new to UE4 so I’d need some pointers. Any kind of help would be appreciated :slight_smile:

You can’t initialize an actor as a subobject.

This line “//Script//DoorFramework.Default__AutomatedDoorFramework to Level failed” in the error message tells you that AADoor expects a level as its outer object.

You can use SpawnActor to spawn the door as an actor and then keep a reference to it. You could also try using a ChildActorComponent.

I’m still under 4.5 but from what I understand, you are trying to spawn an Actor as a component. First off, your Actor being name Component is a conceptual mistake. An Actor is NOT a component. It is was is holding components. Now ObjectInitializer.CreateDefaultSubobject is used to spawn component for the actor, not actual Actors.

To spawn Actors you want to use World::SpawnActor.

https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Actors/Spawning/index.html

Thanks to & Michaël, things are clearer in my head now. I’ll try this out immediatly.

Alright so now I use

 this->DoorComponent = (AADoor*)GetWorld()->SpawnActor(AADoor::StaticClass());

That causes no more crashes. However, I get 2 doors spawned. One when I drag the AAutomatedDoorFramework in the editor, and one when I release the mouse button. I end up with 1 AutomatedDoorFramework and 2 Doors. What could cause this ?

Yeah I kinda realized it was caused by the constructor being “called” several times due to preview and stuff.

However, I would like the door to be spawned in the editor so it can be moved and edited easily. BeginPlay would not fill that role. Is there such as thing as BeginEditor ?

Sure

The plan is to have a door framework that is generic enough, so that someone can use it to quickly populate a map with doors / elevators / whatnots. At the moment each DoorFramework holds one Door, but I plan to make it so a single DoorFramework can have several doors (to have doors ala Star Trek, or something even more complex like an Iris).

So yes, there can be several DoorFrameworks in a single scene.

That is our fault. You don’t want to spawn an actor inside another actor in the constructor. The same reason why it is not possible to spawn actors inside blueprint construction scripts.

When you drag the framework in the editor a preview actor is created. This preview actor spawns the first door. Your final framework actor spawns the second one. (Speculation)

When the preview actor is destroyed it doesn’t take the door with him. the ChildActorComponent would take care of that for you.

You could try using UChildActorComponent | Unreal Engine Documentation
or spawn the actor when starting the game (override BeginPlay)

Can you describe what you are trying to do? Are there going to be multiple DoorFrameworks?

You might be better off writing an editor plugin. I recommend opening a new question with your desired design / functionality. Maybe someone has a better idea.

Alright, thanks again for your time.

Maybe you should create each door as a component of your framework instead of holding Actors. Like just removing the AActor Door for an array of struct that are doors, but actually hold the static mesh component you need for your door(s).

You “DoorFramework” actor would then look like this =>

RootComponent->DoorRoot01->Door01SM01
RootComponent->DoorRoot01->Door01SM02
RootComponent->DoorRoot02->Door02SM01
RootComponent->DoorRoot02->Door02SM02
RootComponent->DoorRoot02->Door02SM03
etc…

Aye, that is also what I had in mind. Right now I’m trying to solve the duplication of doors issue with the drag-n-drop from the class viewer.