Creating an Array of actors c++ not working

I have a Smart Object that is completely working in a class I can drop the actor in the scene and it works fine.

Now I have a secondary class that needs to make a array of these objects in the scene. Ive tried the following with them all failing in a engine crash:

		TArray<ABuildingModTile*> Column;

	FActorSpawnParameters SpawnInfo;
	ABuildingModTile* someItem = GetWorld()->SpawnActor<ABuildingModTile>(GetClass(), SpawnInfo);
	Column.Add(someItem);

Column.Add(ObjectInitializer.CreateDefaultSubobject < ABuildingModTile >(this, TEXT("BuildingModTile")));

I’m not understanding something,

Adding more information:
This is the base Class I am trying to create a array from:

#pragma once

#include "GameFramework/Actor.h"
#include "BuildingMod_Defines.h"
#include "BuildingModTile.generated.h"

/**
 * 
 */
UCLASS(Blueprintable, BlueprintType)
class RPGSYSTEM_DEMO_API ABuildingModTile : public AActor
{
	GENERATED_BODY()

	UPROPERTY()
		TSubobjectPtr<USphereComponent> BaseRoot;


	void OnConstruction (const FTransform & Transform) override;


	//Marks the Size of the modular set
	//X Width Y Depth Z Height
	FVector TileSize;

	//Movement Triggers
	bool RightShift;
	bool LeftShift;
	bool ForwardShift;
	bool BackShift;

	bool WaitForRelease;

	FVector CenterPOS;

	bool init_meshes;

	void BuildFloorAndWall(const FTransform & Transform);

public:

	ABuildingModTile(const FObjectInitializer& ObjectInitializer);
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Setup")
		TArray<UStaticMesh*> PartType_Meshes;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Enum)
		TEnumAsByte<BuildPart_Types::BuildPart_Type> FloorIndex;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Enum)
		TEnumAsByte<BuildPart_Types::BuildPart_Type> WallType;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Setup", Meta = (MakeEditWidget = true)) 
		FTransform CenteredControlWidget;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Enum)
		TEnumAsByte<BuildPart_POSTypes::BuildPart_POSType> WallPOS;
	

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Setup")
		TArray<FWallPOSType> WallRotPOSData;
	


	UPROPERTY()
		UInstancedStaticMeshComponent * Floor;

	UPROPERTY()
		UInstancedStaticMeshComponent * Wall;
	

	void UpdateWallMesh(bool IsUp);
	void UpdateWallPOS(bool IsPositive);
};

This is the new Class:

#include "GameFramework/Actor.h"
#include "BuildingModTile.h"
#include "BuildingModGen.generated.h"


/**
 * 
 */
UCLASS(Blueprintable, BlueprintType)
class RPGSYSTEM_DEMO_API ABuildingModGen : public AActor
{
	GENERATED_BODY()
	
	ABuildingModGen(const FObjectInitializer& ObjectInitializer);
	
	UPROPERTY()
	TSubobjectPtr<USphereComponent> BaseRoot;

public:
	//UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tiles")
		TArray<ABuildingModTile*> Column;
};

// Fill out your copyright notice in the Description page of Project Settings.

#include "RPGSystem_Demo.h"
#include "BuildingModGen.h"


ABuildingModGen::ABuildingModGen(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	BaseRoot = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(this, TEXT("BaseSphereComponent"));
	RootComponent = BaseRoot;

	FActorSpawnParameters SpawnInfo;
	ABuildingModTile* someItem = GetWorld()->SpawnActor<ABuildingModTile>(GetClass(), SpawnInfo);
	Column.Add(someItem);
	//Column[0]->AttachRootComponentToActor(this);


}

This on crashes on Spawn actor

The other version crashes at:

Column.Add(ObjectInitializer.CreateDefaultSubobject < ABuildingModTile >(this, TEXT(“BuildingModTile”)));

Hmm… your code looks fine to me. Not sure why it wouldn’t work. Have you considered using TActorIterator as a workaround?

I tried that and I’m getting errors within the Iterator object. I’m going to try to move this to the Onconstruction call back… maybe doing this in the constructor is killing it.

void ABuildingModGen::OnConstruction(const FTransform & Transform){
Super::OnConstruction(Transform);

	FActorSpawnParameters SpawnInfo;
	ABuildingModTile* someItem = GetWorld()->SpawnActor<ABuildingModTile>(GetClass(), SpawnInfo);
	Column.Add(someItem);
}


This isnt working either... Can you not make array of objects? Seems like it should be simple. I'm looking over other examples and it looks like im doing this correctly.

You can’t spawn things in the constructor (I believe GetWorld () will return an invalid/null reference) as far as I’m aware. Try moving that code into an overidden begin play method (virtual void BeginPlay () override;).

Hmm this would be an issue I’m trying to create a tool to build things in the editor I thought you could create objects via construction script and onConstruction. This is my main plight

Hmm if you’re trying to build tools for the editor you may need to make an editor module, but that’s a whole other complex subject.

That last code snippet you posted will likely work in any other overidden method (like Tick and Begin Play).

I’m trying to understand why I can do things like :

	Floor = ObjectInitializer.CreateDefaultSubobject < UInstancedStaticMeshComponent >(this, TEXT("InstancedMeshComponent0"));
	Wall = ObjectInitializer.CreateDefaultSubobject < UInstancedStaticMeshComponent >(this, TEXT("InstancedMeshComponent1"));

But I cant do this with custom Objects? I would have to make my object a Module? But the object only consist of 2 Instance mesh objects and code to handle parameter changes… :confused:

I’m not familiar with those methods, but I’m guessing its because those methods are to be used with Objects and not Actors. (Actor classes start with “A” and Object classes start with “U”).

At this point it may be easier for you to tell me what exactly you’re trying to achieve otherwise I doubt I’d be of much help.

Above is a video of the smart tile i created to control a modular section of a building. I need tiles to create the floors for a building then an array of that object to make floors of a building. To help me make a building or rooms faster than normally placing modular parts:

You are calling SpawnActor incorrectly. If you pass in a UClass as the first parameter, you are saying you want to create an actor of that class. With the templated version, this is so that you can create an actor of some derived class type (often a blueprint) but say that the returned pointer should be of the template parameter class type. In which case, the template parameter class must be a base class of the UClass.

In your code, you are passing GetClass(), which is the class of your calling method. Whatever that is, presumably it’s not derived from ABuildingModTile, hence the crash. You should call

SpawnActor< ABuildingModTile >(ABuildingModTile::StaticClass(), SpawnInfo);

In fact though this is the default implementation; all you need is SpawnActor< ABuildingModTile >();

1 Like

if(GetWorld())
You should check the validity of GetWorld incase it returns an invalid reference, then proceed with spawning.

Also having UPROPERTY on the TArray would be nice for garbage collection.

Ah yes, this is true. You should try this as it may be the problem.

This worked. Thanks. I’m still trying to learn this API it seems some what confusing at times.