AttachToComponent Setting Scale of Attached Actor to 0,0,0

I’ve copied over the VRPawn logic (plus grab component and interface) into my c++ framework. But I’m having an issue with the grab functionality.

When I “grab” an actor, it is successfully attached and teleported to the controller location, but the actor’s scale is being set to 0,0,0. I stepped through the code of USceneComponent::AttachToComponent to see what was happening:

/// In Debug:
			///Pre-Attach 
				/// this = StaticMesh scenecomponent
				/// OwnerPrivate: GrabActor_StaticMesh_Phsyics3_3
					/// OwnerPrivate->RootComponent = StaticMesh scenecomponent
				/// RelativeScale3D = (0.3, 0.3, 0.3)
				/// bAsboluteLocation = false
				/// bAbsoluteRotation = false
				/// bAbsoluteScale = false
				/// bShouldBeAttached = false
				/// bShouldSnapLocationWhenAttached = false
				/// bShouldSnapRoationWhenAttached = false
				/// bShouldUpdatePhysicsVolume = false
				/// bUseAttachParentBound - false
				/// TransformUpdated = empty
			/// During Attach
				///	We reach USceneComponent Line 2112, scale is still 0.3
				/// Breakpoints in USceneComponent::SetRelativeScale3D_Direct() are never reached via c++ AttachToComponent()
					/// Blueprint utilized K2_AttachToComponent (DisplayName Attach Component To Component" is just a call to AttachToComponent() 
				/// At line 2121: The following breakpoint was hit: When 0x429aee22488 (Original Expression : this->RelativeScale3D.X) changes(8 bytes) in process 'UnrealEditor.exe'
				/// When called from Blueprint GrabComponent, execution passes line 2121 without changing XY scale, and changes Z value to .5
	

Of note, this happens solely when called by my “GrabComponent”, whether it’s added as a strictly c++ class or a blueprint derivative. When using the Blueprint made “GrabComponent” in the project there is no issue.

Line 2121 falls in a #if With Editor space, specifically it is if(GEngine). The scale only changes once that line is actually ran. I tried packaging the project but unfortunately the scaling appeared to occur, though I couldn’t verify.

Has anyone had weird scaling issues with AttachToComponent?

What scale rule are you using? What is the scale of the component you’re attaching it to?

You may need to the Keep World scale rule, but depends on your situation.

	bool attached = GetAttachParent()->AttachToComponent(inMotionController, FAttachmentTransformRules(EAttachmentRule::KeepWorld, EAttachmentRule::KeepWorld, EAttachmentRule::KeepWorld, true));

Is what I’ve got. As for the scale of the component, I’m unsure. The component the object is attaching to is a UMotionControllerComponent spawned by UE (The attachment occurs from an input).

I also haven’t yet tested trying to bind an object to a different component as test case yet.

Those rules look fine… at least they shouldn’t be messing with the scale. I often use the predefined FAttachmentTransformRules::SnapToTargetNotIncludingScale if I’m attaching to something like a hand skelmesh bone.

Yeah, I’d try attaching to the root component or other scenecomponent based object and see if that fixes it.

1 Like

Precisely what I did, and of course what a dope I was. When I add the UMotionControllerComponents I initialize their FTransforms to all 0s. I never would have thought of scale being the issue if a friend hadn’t suggested it. Shame we can’t see the runtime outliner while “Play in VR”.

Thanks for helping though!

I have the same issue, but i still dont understand how to fix it

auto* CurrentHand = IsRightHand ? RightHand : LeftHand;
	ListOfActors[0]->DisableComponentsSimulatePhysics();
	ListOfActors[0]->AttachToComponent(CurrentHand,
	                                   FAttachmentTransformRules::SnapToTargetIncludingScale);
	ListOfActors[0]->SetActorTransform(CurrentHand->GetComponentTransform());

All init stuff

SceneComponent = CreateDefaultSubobject<USceneComponent>("VrRoot");
	SceneComponent->SetupAttachment(GetRootComponent());

	HealthComponent = CreateDefaultSubobject<UHealthComponent>("HealthComponent");


	LeftHand = CreateDefaultSubobject<UMotionControllerComponent>("LeftMotionControllerComponent");
	LeftHand->SetupAttachment(SceneComponent);

	SphereComponentL = CreateDefaultSubobject<USphereComponent>("LeftGrabCollision");
	SphereComponentL->SetupAttachment(LeftHand);
	SphereComponentL->InitSphereRadius(GrabCollisionsRadius);

	RightHand = CreateDefaultSubobject<UMotionControllerComponent>("RightMotionControllerComponent");
	RightHand->SetupAttachment(SceneComponent);

	SphereComponentR = CreateDefaultSubobject<USphereComponent>("RightGrabCollision");
	SphereComponentR->SetupAttachment(RightHand);
	SphereComponentR->InitSphereRadius(GrabCollisionsRadius);

	CameraComponent = CreateDefaultSubobject<UCameraComponent>("CameraComponent");
	CameraComponent->SetupAttachment(SceneComponent);
	CameraComponent->bLockToHmd = true;

	HealthTextComponent = CreateDefaultSubobject<UTextRenderComponent>("HeathWidget");
	HealthTextComponent->SetupAttachment(LeftHand);