How to rotate and translate static mesh with code?

I have tried setting the relative, world, staticmeshcomponent, rootcomponent, god knows what else… the documentation is really lean sometimes…:


	FVector Position;
	Position.X = 0.0f;
	Position.Y = 0.0f;
	Position.Z = 0.0f;

	FRotator Rotation;
	Rotation.Yaw = -180.0f;
	Rotation.Pitch = 0.0f;
	Rotation.Roll = 0.0f;

	StaticMeshComponent->SetRelativeLocationAndRotation(Position, Rotation); // doesn't work

	RootComponent->SetWorldRotation(Rotation);
	RootComponent->SetWorldLocation(Position); // Both don't work

	FTransform Transform;
	Transform.SetLocation(Position);

	FQuat GRRRRR;
	GRRRRR.X = -180.0f;
	Transform.SetRotation(GRRRRR);

	StaticMeshComponent->SetWorldTransform(Transform); // Also doesn't work
        

	SetActorRotation(Rotation); // This doesn't either
	SetActorLocation(Position); // This doesn't either



Hi Jimmy,

When is this code executing? A root component on an actor doesn’t have a default or initial position/rotation since that is determined entirely by where the actor is spawned. If this code is in the constructor then it won’t do anything, but if you are running this code after the actor has already been spawned then I would expect any of your approaches to work (although you should probably be using a FRotator instead of FQuat, as -180 is not a valid value for a quaternion).

Cheers,
Michael Noland

It is in the actor construct…

The aim is to make my inheriting blueprint have a default rotation.

Hi Jimmy,

I’d add a USceneComponent ‘dummy’ above your mesh component then, which will let you set the relative rotation, etc… on the static mesh component.

Cheers,
Michael Noland

Not sure what that means,

I have added a USceneComponent:


SceneComponent = PCIP.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComp"));

made it the root:


RootComponent = SceneComponent;
StaticMeshComponent->AttachTo(RootComponent);



Applied rotation and location:


RootComponent->SetWorldLocationAndRotation(Position, Rotation);

What am I doing wrong… I’ve spent 3 hours on this now… :frowning:

Treat the root component as if it has no transform in the constructor (because it doesn’t, anything you set there will be ignored when the actor is spawned).

You need to call SetWorldLocationAndRotation on the StaticMeshComponent, not the RootComponent.

Cheers,
Michael Noland

Set Mobility to Movable!

You absolutely cannot move a Static Mesh Actor until you set its mobility to movable!

Constructor
Put this in your constructor for your Static Mesh Class:


//Mobility
StaticMeshComponent->SetMobility(EComponentMobility::Movable);

Spawned
Or you can call this code right after spawning the Static Mesh Actor, if you are not using your own Static Mesh Actor class (for other readers mainly).


//Mobility
MySpawnedSMA->StaticMeshComponent->SetMobility(EComponentMobility::Movable);

BP Defaults
You can also set this in your BP, in default properties, if you are using a BP of a static mesh actor.

So in summary:

Set Mobility to Movable!

Let us know how it goes!

Rama

PS: Static mesh actors default to static mobility for optimization reasons, allows lighting system of UE4 to do stuff it can’t do with moveable meshes.

Wow, thanks for the posts guys… I must be missing something obvious.

BasePlatform.h


#pragma once

#include "GameFramework/Actor.h"
#include "BasePlatform.generated.h"

UCLASS()
class ***_API ABasePlatform : public AActor
{

	GENERATED_UCLASS_BODY()

public:

	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Platforms") TSubobjectPtr<UStaticMeshComponent> StaticMeshComponent;
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Platforms") UStaticMesh * StaticMeshObject;
	TSubobjectPtr<USceneComponent> SceneComponent;

private:

	void InitializeComponents(const class FPostConstructInitializeProperties& PCIP);
	void SetupMeshes();
	void SetupOrientation();

};

BasePlatform.cpp


#include "BasePlatform.h"

ABasePlatform::ABasePlatform(const class FPostConstructInitializeProperties& PCIP)
	:	Super(PCIP)
{
	InitializeComponents(PCIP);
	SetupMeshes();
	SetupOrientation();
}

/*
	Instantiates objects used
*/

void ABasePlatform::InitializeComponents(const class FPostConstructInitializeProperties& PCIP)
{
	StaticMeshComponent = PCIP.CreateDefaultSubobject <UStaticMeshComponent>(this, TEXT("mySubObject"));
	SceneComponent = PCIP.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComp"));
}

/*
	Set up all the mesh related stuff
*/

void ABasePlatform::SetupMeshes()
{
	static ConstructorHelpers::FObjectFinder<UStaticMesh> staticMesh(TEXT("StaticMesh'/Engine/EditorMeshes/EditorPlane'"));
	StaticMeshObject = staticMesh.Object;
	RootComponent = SceneComponent;

	StaticMeshComponent->AttachTo(RootComponent);

	StaticMeshComponent->SetStaticMesh(StaticMeshObject);
}

/*
	Sets initial values for the platform position
*/

void ABasePlatform::SetupOrientation()
{
	FVector Position;
	Position.X = 0.0f;
	Position.Y = 0.0f;
	Position.Z = 0.0f;

	FRotator Rotation;
	Rotation.Yaw = -180.0f;
	Rotation.Pitch = 0.0f;
	Rotation.Roll = 0.0f;

	StaticMeshComponent->SetMobility(EComponentMobility::Movable);
	StaticMeshComponent->SetWorldLocationAndRotation(Position, Rotation);
}

My aim is to make a blueprint that starts off rotated in the correct orientation… Just to save me time (4 hours later… DOH)! But it will be the basis of all of my platforms considering it’s a side scroller :slight_smile:

Currently when I drag my blue print into the scene, it’s facing the wrong way by default.

Ignore the above post…

The compiler inside the editor was not getting the changes… I had to restart my editor with a re-build to get it to work.

Yoop yoop.