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");
}
...
}
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 :
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.
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 ?
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 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.
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 =>