Prevent scaling of attached components

I have a pawn grandchild with a cube static mesh as its intended root. I want to scale the cube to be a certain size and attach camera and spline components to it at construction. Problem is as the title implies, no matter what variation of implementation I can think to try, the camera and spline seem to always scale with the cube they attach to, and I’d like to know if that could… not be the case. The camera scale isn’t a big deal, just annoying to look at, but when I use the spline generator to make a circle, it makes an oval, and I’d prefer it not to do that lol

// 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;

// scale the box mesh to be an appropriate hitbox for a gunship

VisualMesh->SetWorldScale3D(FVector(30.0f, 10.0f, 10.0f));

// set simulate physics to false

VisualMesh->SetSimulatePhysics(false);

// set up the camera in a position appropriate for the viewfinder of an AC-130

Viewfinder = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));

//Viewfinder->SetupAttachment(VisualMesh); // don't think we need to do this when we're using AttachToComponent? probably redundant

//FAttachmentTransformRules AttachmentRules = FAttachmentTransformRules(EAttachmentRule::SnapToTarget, EAttachmentRule::KeepRelative, EAttachmentRule::KeepRelative, true); // this is no better than SnapToTargetNotIncludingScale

Viewfinder->AttachToComponent(VisualMesh, FAttachmentTransformRules::SnapToTargetNotIncludingScale); // scale is included in snap anyways???

//Viewfinder->SetWorldScale3D(FVector(1.0f, 1.0f, 1.0f)); // this did not help either!!!

//Viewfinder->SetRelativeLocation(FVector(0.0f, -550.0f, 0.0f)); // works when subclassing DefaultPawn and the camera isn't scaled by RootComponent

Viewfinder->SetRelativeLocation(FVector(0.0f, -55.0f, 0.0f)); // have to use this when the camera inherits the VisualMesh's scaling as we subclass from Pawn instead

FRotator ViewfinderRotation = GetActorRotation();

ViewfinderRotation.Add(0.0, -90.0, 0.0);

Viewfinder->SetRelativeRotation(ViewfinderRotation);

// set up the spline component

SplineComponent = CreateDefaultSubobject<USplineComponent>(TEXT("Spline"));

SplineComponent->AttachToComponent(VisualMesh, FAttachmentTransformRules::SnapToTargetNotIncludingScale);

Do you have a blueprint based on this class? If so, just change the component scale to world:
image

1 Like

This does work! Curious though, is there really no way to enforce scale type via C++? I only ask because it seems like relying on a Blueprint based on a C++ class that is changing often at this stage in development can be a real pain, as the changes won’t apply to the blueprint until the project is completely reloaded (hot reload won’t apply them :frowning: )

Directly in c++ constructor
/// divide world scale by the parent scale

AMyActorScale::AMyActorScale()
{
	VisualMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Visual Mesh"));

 	// 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;	
	VisualMesh->SetWorldScale3D(FVector(30.0f, 10.0f, 10.0f));	
	VisualMesh->SetSimulatePhysics(false);	
	Viewfinder = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));		 
	Viewfinder->bCameraMeshHiddenInGame = false;
	Viewfinder->SetupAttachment(VisualMesh);

	Viewfinder->SetRelativeLocation(FVector(0.0f, -55.0f, 0.0f)); // have to use this when the camera inherits the VisualMesh's scaling as we subclass from Pawn instead
	FRotator ViewfinderRotation = GetActorRotation();
	ViewfinderRotation.Add(0.0, -90.0, 0.0);
	Viewfinder->SetRelativeRotation(ViewfinderRotation);
	SplineComponent = CreateDefaultSubobject<USplineComponent>(TEXT("Spline"));		
	SplineComponent->SetupAttachment(VisualMesh);
	
	Viewfinder->SetWorldScale3D(FVector(1.0f, 1.0f, 1.0f) / FVector(30.0f, 10.0f, 10.0f));
	SplineComponent->SetWorldScale3D(FVector(1.0f, 1.0f, 1.0f) / FVector(30.0f, 10.0f, 10.0f));
	
}
1 Like

Can i solve this problem with the content of this article?

Here is how I do it in C++ (Use SetAbsolute)

	...
	YourMeshComponent->SetStaticMesh(YourMeshAsset.Object);


	// Set Absolute Scale
	YourMeshComponent->SetAbsolute(false, false, true);

		
	// Ensure all components are attached correctly
	YourMeshComponent->SetupAttachment(RootComponent);
	...