I want to set a mesh to an actor that is spawned at a custom time and place in UE5.3. I tried using the SetStaticMesh()
method. Everything works fine in the BeginPlay()
method.
However, when I move the SetStaticMesh
method out of the BeginPlay()
method, e.g. in a timer, the mesh is not set to the actor. Even though the actor is spawned, as shown in the editor.
Are there other ways to set a mesh to an actor or is there something wrong with the code?
I have attached a minimal example.
I can only find examples that place the method in BeginPlay()
.
See also here: Spawning Static Mesh Actors at runtime - #2 by Hakaishin0895
// SpawnMinimal.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TimerManager.h"
#include "SpawnMinimal.generated.h"
UCLASS()
class SPAWNEMPTY_API ASpawnMinimal : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawnMinimal();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Schedule actor spawning
FTimerHandle TimerHandle;
void ScheduledSpawn();
};
// SpawnMinimal.cpp
#include "SpawnMinimal.h"
#include "Components/StaticMeshComponent.h"
#include "Components/SphereComponent.h"
#include "Engine/StaticMesh.h"
#include "Engine/StaticMeshActor.h"
#include "Engine/Engine.h"
// Sets default values
ASpawnMinimal::ASpawnMinimal()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ASpawnMinimal::BeginPlay()
{
Super::BeginPlay();
GetWorld()->GetTimerManager().SetTimer(ASpawnMinimal::TimerHandle, this, &ASpawnMinimal::ScheduledSpawn, 1.0f, false);
// Load the mesh asset
UStaticMesh* MeshAsset = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), nullptr, TEXT("/Engine/EngineMeshes/Sphere")));
// Spawn the mesh actor
AStaticMeshActor* MeshActor = GetWorld()->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0.f, 1000.f, 0.f), FRotator(0.0f, 0.0f, 0.0f));
MeshActor->GetStaticMeshComponent()->SetStaticMesh(MeshAsset);
}
// Called every frame
void ASpawnMinimal::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ASpawnMinimal::ScheduledSpawn()
{
// Load the mesh asset
UStaticMesh* MeshAsset = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), nullptr, TEXT("/Engine/EngineMeshes/Sphere")));
// Spawn the mesh actor
AStaticMeshActor* MeshActor = GetWorld()->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), FVector(0.f, 100.f, 0.f), FRotator(0.0f, 0.0f, 0.0f));
MeshActor->GetStaticMeshComponent()->SetStaticMesh(MeshAsset);
}