Hello,
I want to move static meshes continuously in one direction. I’m using the OnConstruction() function because I want to dynamically modify in the editor the number of static meshes, the distance between them, and the scale of each.
The problem is that I can’t move the static meshes created with OnConstruction(). I use SetActorLocation(), the actor’s coordinates change but the meshes don’t.
Here’s what I’ve done in my code:
Buildings.h
private:
UPROPERTY(VisibleAnywhere)
TArray<UStaticMeshComponent*> Pillars;
UPROPERTY(EditAnywhere)
int NumOfPillars = 10;
UPROPERTY(EditAnywhere)
float PillarGap = 500.0f;
UPROPERTY(EditAnywhere)
float MoveSpeed = -10.0f;
UPROPERTY(EditAnywhere)
float PillarHeightMin = 1.0f;
UPROPERTY(EditAnywhere)
float PillarHeightMax = 4.0f;
UPROPERTY(EditDefaultsOnly)
UStaticMesh* PillarMesh;
UPROPERTY(EditDefaultsOnly)
USceneComponent* Root;
UFUNCTION(BlueprintCallable)
void SpawnPillars();
public:
// Sets default values for this actor's properties
ABuildings();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Construction Script
virtual void OnConstruction(const FTransform& Transform) override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
Buildings.cpp
#include "Buildings.h"
void ABuildings::SpawnPillars()
{
UE_LOG(LogTemp, Warning, TEXT("Spawning Pillars"));
for (size_t i = 0; i < Pillars.Num(); i++)
{
if (Pillars[i])
{
Pillars[i]->DestroyComponent();
}
}
Pillars.Empty();
for (size_t i = 0; i < NumOfPillars; i++)
{
UStaticMeshComponent* smc = (UStaticMeshComponent*)AddComponentByClass(UStaticMeshComponent::StaticClass(), false, FTransform(), true);
if (smc)
{
smc->RegisterComponent();
smc->SetMobility(EComponentMobility::Movable);
smc->AttachToComponent(Root, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
smc->SetWorldLocation(GetActorLocation() + FVector(0, PillarGap * i, 0));
smc->SetWorldScale3D(FVector(1, 1, FMath::RandRange(PillarHeightMin, PillarHeightMax))); // Hauteur des meshs randomisés
smc->SetStaticMesh(PillarMesh);
Pillars.Add(smc);
}
}
}
// Sets default values
ABuildings::ABuildings()
{
// 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;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
SetRootComponent(Root);
}
// Called when the game starts or when spawned
void ABuildings::BeginPlay()
{
Super::BeginPlay();
}
void ABuildings::OnConstruction(const FTransform &Transform)
{
SpawnPillars();
}
// Called every frame
void ABuildings::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Moving pillars
SetActorLocation(GetActorLocation() + FVector(0, MoveSpeed * DeltaTime, 0));
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, GetActorLocation().ToString());
}
As you can see, I use SetActorLocation(GetActorLocation() + FVector(0, MoveSpeed * DeltaTime, 0));
The actor itself moves well, but my meshs don’t.
Thank you very much for your help.