Attach actor by socket to another actor by socket? Align sockets?

Hello,

with AttachToComponent

Unbenannt.jpg

I can snap** the pivot point **of a target component to another component’s socket transform. How to snap a **socket transform **of a target component to a **socket transform **of a parent component? Both sockets should have the same world transform (same location, same rotation, same scale) after that.

Thank you,

Thilo

Hi man,
You have to create an abstracct “offset” something that create the difference you need.

For example
Lets say you have 2 planes, both with a “Socket” in a random place, that is not in the midde of the plane and not on the pivot.
One upper left, one upperight.
And you want to placce the two socket in the same place.

You have to get the difference between the “pivoot” and the “Socket” ,
Now Make a scene component in your plane, mmake the plane child of the scene comp.

Now if you attach the actor to the socket you just place the middle of the plane A, on the Socket of Plane B
What remain to add is the difference you calculated before,
So add a local position to the Scene component, based on the think we calculated before.

And here you should have the 2 planes with sockets in the same place

This is basically what I tried to get to work for two days. It didn’t work. Something is not okay with “rotational differences”… Maybe it’s inaccuracy, or something with Euler rotations or Quaternions… I don’t know. What in the end worked is this:

Rotating the target component to the world coordinate system by applying the inverse of the socket’s rotation (InvertRotator, so the rotation of the socket is (0,0,0)) and then rotating it to the parent’s socket rotation (CombineRotators). I thought you can make this in one step by calculating the delta rotation between those two rotators (Delta (Rotator)-Node), but for some reason this does not work…

I hope my solution holds. Needs some more tests.

my solution here:

  1. attach the target actor/component to another component’s socket
  2. calculate the inner “offset” value of target actor/componnet that is the difference between “the pivot point” and the “socket”
  3. add this “offset” to target actor/componnet (you can simply use AddWorldOffset)

I know this thread is already more than 1 year old, but I was also looking for a solution to this and this was one of the first results on google, so here’s a function I came up with that lets you attach the target component to the parent component while making sure the target’s socket and parent’s socket are aligned:

void AttachComponentsSocketToSocket(USceneComponent* Target, USceneComponent* Parent, FName TargetSocketName, FName ParentSocketName, bool bScaleToParentSocket)
{
	// Rotate in such a way that TargetSocket rotation becomes the same with ParentSocket rotation
	FVector OriginalTargetSocketLocation = Target->GetSocketLocation(TargetSocketName);
	FQuat DeltaRootQuat = Parent->GetSocketQuaternion(ParentSocketName) * Target->GetSocketQuaternion(TargetSocketName).Inverse();
	Target->SetWorldRotation(DeltaRootQuat * Target->GetComponentQuat(), false, nullptr, ETeleportType::TeleportPhysics);
	FVector RotationLocationOffset = OriginalTargetSocketLocation - Target->GetSocketLocation(TargetSocketName);
	Target->AddWorldOffset(RotationLocationOffset, false, nullptr, ETeleportType::TeleportPhysics);

	// Set location in such a way that TargetSocket location becomes the same with ParentSocket location
	Target->AddWorldOffset(Parent->GetSocketLocation(ParentSocketName) - Target->GetSocketLocation(TargetSocketName));

	// If scaling is needed, scale Target as specified by ParentSocket
	if (bScaleToParentSocket)
	{
		Target->SetWorldScale3D(Parent->GetSocketTransform(ParentSocketName, RTS_World).GetScale3D());
	}

	// Attach target to parent
	Target->AttachToComponent(Parent, FAttachmentTransformRules::KeepWorldTransform, ParentSocketName);
}

Hope this helps someone!

2 Likes

It’s worth noting that the ‘Attach Actor to Actor’ node might not behave as expected because this node attempts to attach to a socket on the Root Component.

For attaching to a character’s skeletal mesh, you should use the ‘Attach Actor to Component‘ node instead.

It’s so weird that no function exist for this. What’s the point of socket if you have to add code for location offset from pivot location anyway? Why using socket and not just offset from pivot location directly?