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.
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 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);
}
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?