How to spawn actor in C++? Been trying for 9 hours now

Can someone please show me a 5-10 step tutorial for spawning an actor properly according to standard Unreal Engine methodology? Are actors supposed to be spawned from player controller, character or actor? Is there a ten minute tutorial on youtube that shows you how to spawn an actor at FVector (0,0,0) when a key is pressed?

void AriseCPPPlayerController::OnPlaceObjectPressed()
{

//F KEY PRESS WORKS
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, ("At least the F key press works! Now let's spawn an actor."));

FActorSpawnParameters SpawnInfo;

FRotator myRot(0, 0, 0);
FVector myLoc(0, 0, 100);

//just spawn the god **** actor
AmySphere mySphere =  GetWorld()->SpawnActor<AmySphere>(this->GetClass(), myLoc, myRot, SpawnInfo);


//AActor* MySpawnedActor = World->SpawnActor<AmyWallSegmentCPP>(myWallSegmentClass, SpawnLocation, SpawnRotation);
//AmyWallSegmentCPP* const SpawnedPickup = World->SpawnActor<AmyWallSegmentCPP>(myWallSegmentClass, SpawnLocation, SpawnRotation, SpawnParams);
}

How would I get the above code to work at the most basic level of Unreal Engine C++? Let’s say from a keypress triggered from player controller. I’m trying, I really am, I’m so tired.

8 Likes

Try changing line 13 to something like

AmySphere* mySphere =  GetWorld()->SpawnActor<AmySphere>(AmySphere::StaticClass(), myLoc, myRot, SpawnInfo);

Depending on what MySphere is, you may want to also setup the SpawnInfo to set collision / owners etc (more information here: FActorSpawnParameters

5 Likes

Are you sure that the actor isn’t spawning? Aside from the compiler error on line 13 from trying to assign a pointer to a value, it should spawn. Are you sure it’s not spawning an empty actor that just doesn’t have any visuals attached to it?

I’m going to spend the entire day today trying to debug and find out the answer to your questions.

I am going to try again today.

If you’re in VS you should be able to just plop a breakpoint in there, but if not you can throw in some logs everywhere using the stuff here:

 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));

If you’re in the editor you should be able to look in the world outliner to see if your actors are popping up too.

Also try to set the spawn info to Always spawn:

SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

And like phil_me_up answered, first parameter of SpawnActor should be AmySphere::StaticClass()
U are calling this from the player controller so using this->GetClass() as first parameter will spawn another player controller.

Here are some examples of spawning actors in UE4

FActorSpawnParameters SpawnInfo;
SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
auto SwatAIController = GetWorld()->SpawnActor<ASwatAIController>(SpawnInfo);


FActorSpawnParameters SpawnInfo;
SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
auto Equipment = GetWorld()->SpawnActor<ASwatEquipment>(DefaultInventoryClasses[i], FVector(0.0f), FRotator(0, 0, 0), SpawnInfo);

Try changing the parameters myLoc and myRot to &myLoc and &myRot. Those parameters are pointers and need an address.

It’s really this easy:

FVector Location(0.0f, 0.0f, 0.0f);
FRotator Rotation(0.0f, 0.0f, 0.0f);
FActorSpawnParameters SpawnInfo;
GetWorld()->SpawnActor<AProjectile>(Location, Rotation, SpawnInfo);

And don’t forget to #include the thing you’re trying to spawn.

8 Likes

Really basic question, where should this go? In the main actor’s script or is there a main that would be more appropriate?

What do you mean? This would go wherever it is you need to spawn something.

Where would I put it if I want the actor to spawn at the start of a level?

Hi,
I had the same problem, and I found two possible solutions.

  1. If your actor is created in the Unreal Editor, then you can simply spawn it by code like this:

    UClass* MyItemBlueprintClass = StaticLoadClass(UObject::StaticClass(), NULL, TEXT("/Game/Weapons/axes/DoubleAxeActor.DoubleAxeActor_C"), NULL, LOAD_None, NULL);
    FActorSpawnParameters SpawnInfo;
    SpawnInfo.Owner = this;
    SpawnInfo.Instigator = Instigator;
    ApsItemActor* obj = spawnManager->currentWorld->SpawnActor(MyItemBlueprintClass, newlocation, GetActorRotation(), SpawnInfo);

The pre-requisite is that your actor is replicated. Please note that actors deriving from AActor are not replicated by default, so you need to add in their constructor:

bReplicates = true;

or within the editor you should flag your actor as “Replicates”. It is one of the properties in the details panel.

  1. If you want to create your actor completely within C++, and you have only the StaticMesh and the Material in the Editor (this was my case), you can create it like this:

    FActorSpawnParameters SpawnInfo;
    SpawnInfo.Owner = this;
    SpawnInfo.Instigator = Instigator;
    ApsItemActor* obj = GetWorld()->SpawnActor(ApsItemActor::StaticClass(), newlocation, GetActorRotation(), SpawnInfo);

    UStaticMeshComponent* MyMeshComponent = NewObject(obj, UStaticMeshComponent::StaticClass(), TEXT(“Mesh”));

    UStaticMesh* MeshAsset = Cast(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT(“StaticMesh’/Game/Weapons/axes/doubleaxe02abc.doubleaxe02abc’”)));
    UMaterial* MaterialAsset = Cast(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT(“Material’/Game/Weapons/axes/doubleaxe02c_Mat.doubleaxe02c_Mat’”)));

    MyMeshComponent->SetStaticMesh(MeshAsset);
    MyMeshComponent->SetMaterial(0, MaterialAsset);
    MyMeshComponent->SetWorldLocation(newlocation);
    MyMeshComponent->SetIsReplicated(true);

    MyMeshComponent->RegisterComponent();
    obj->AddOwnedComponent(MyMeshComponent);
    obj->SetRootComponent(MyMeshComponent);

Also in this case the pre-requisite is that your actor is replicated. Same case for case 1.

If your actor is invisible client side, means you didn’t replicate it, or you didn’t set the position properly. Please note the SetWorldLocation call despite the fact you are already giving the location in the spawnactor command. For me it works only if I call explicitely SetWorldLocation

1 Like

I am totally new to UE4 and C++. I really would like to know where to put this. I just want to create several actors when the game begins. Is there a C++ file which is called at first? No infos in the internet, I am searching for 3 days now.

A good place would be your GameMode class.
There is always just 1 instance of a game mode during gameplay, and it also only exist on the server during multiplayer games (which is resposible for spawning your actors)

If u want to spawn these actors when the game starts, u can use the StartPlay method

On beginplay

@phil_me_up could you give an insight on the idea behind “StaticClass” in EU4. In the templated function SpawnActor, we are already specifying the template type by AmySphere. Therefore we already say that we need an instance of this class. So what is a staticclass? Is it unreal way of saying an instance of the class?

Is it really that easy? or is this an obsolete solution? I’ve been trying for days to just spawn any object in any way, I will literally pay you to call me and walk me thru this.

oh god I included the .cpp rather than the .h

headdesk

thank you for the good solution; kaisellgren

now I can spawn things but they’re all at the same location as the first thing I spawn.

I’m also getting this error:

LogActor: Warning: FloatingActor /Game/StarterContent/Maps/UEDPIE_0_Minimal_Default.Minimal_Default:PersistentLevel.FloatingActor_0 has natively added scene component(s), but none of them were set as the actor's RootComponent - picking one arbitrarily

thoughts?

It means you didn’t declare a root component in your actor so it made one for you.

You just need to make a root component in your constructor:

// Setup root component
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));

// Attach your other component to the root (make it a child of the root component)
YourComponentNameHere->SetupAttachment(RootComponent);