How to get a socket's position relative to it's parent component?

Hi everybody,

I’m having a bit of a problem getting the relative position of a socket with code.
I’ve tried numerous solutions I could find, but the functions always return an FVector of (0,0,0).

This is how the skeletal mesh’s (is this correct grammar? :D) skeleton looks:

https://dl.dropboxusercontent.com/u/101118701/SkeletonSocket.jpg

So, the problem is with the highlighted socket. Any other socket I have (Except the other turbine socket) works fine and returns the actual relative position, but not those two.

TL;DR How would I get the location of the socket relative to the base socket/bone (in this case, labelled “Chassis”)?

Anyway, here is how I get the positions:

//Vehicle_MovementComp.h
struct ThrusterTransform
{
	FVector direction;
	FVector location;
	FString tag;

	ThrusterTransform(
		FVector direction = FVector::ZeroVector, 
		FVector location = FVector::ZeroVector, 
		FString tag = TEXT("")) :
		direction(direction), location(location), tag(tag) 
	{

	}
};

//Foenix_Pawn.cpp
		//includes Vehicle_MovementComp.h

		//This is unique to every vehicle, this is the pawn's code
		//Fill up movementThrusterSockets array (Type USkeletalMeshSocket*)
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("Turbine_L_S")))));
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("Turbine_R_S")))));
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("steer_fl")))));
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("steer_fr")))));
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("steer_rl")))));
		movementThrusterSockets.Add(const_cast<USkeletalMeshSocket*>(foenixMesh->GetSocketByName(FName(TEXT("steer_rr")))));

		//This is what I want to be universal to every vehicle, this is going to be (hopefully) in the UMovementComponent derived class
		//Right now it is with the above code (as in, in the same file/class)
		//Fill up thrusters array (Type ThrusterTransform*)
		thrusters.SetNum(movementThrusterSockets.Num());
		for (int16 i = 0; i < thrusters.Num(); i++)
		{
			//foenixMesh type is USkeletalMeshComponent
			thrusters[i].location = foenixMesh->GetSocketTransform(movementThrusterSockets[i]->GetFName(), ERelativeTransformSpace::RTS_Actor).GetTranslation();
			thrusters[i].direction = movementThrusterSockets[i]->GetSocketTransform(foenixMesh).GetUnitAxis(EAxis::X);
		}
		//Set thrusters array element tags (this is unique to every vehicle)
		thrusters[0].tag = FString(TEXT("LMainEngine"));
		thrusters[1].tag = FString(TEXT("RMainEngine"));
		thrusters[2].tag = FString(TEXT("RSteeringEngine"));
		thrusters[3].tag = FString(TEXT("LSteeringEngine"));
		thrusters[4].tag = FString(TEXT("LSteeringEngine"));
		thrusters[5].tag = FString(TEXT("RSteeringEngine"));

The problem is with this row:

thrusters[i].location = foenixMesh->GetSocketTransform(movementThrusterSockets[i]->GetFName(), RelativeTransformSpace::RTS_Actor).GetTranslation();

it always returns FVector(0,0,0) for the first two sockets.

Other tries were:

//First:
thrusters[i].location = foenixMesh->GetComponentTransform().GetTranslation() + movementThrusterSockets[i]->RelativeLocation;
//Second
thrusters[i].location = foenixMesh->GetComponentLocation() + movementThrusterSockets[i]->RelativeLocation;

I think the problem is that it’s getting the position relative to the parent socket/bone (the “Turbine_R” bone), which in this case would be FVector(0,0,0), though I don’t understand why it doesn’t return the proper one even when I specify the RTS_Actor parameter.

So the question would be: How would I get the location of the socket relative to the base socket/bone (in this case, labelled “Chassis”)?

BTW, Sorry for the code formatting, it didn’t look like that on my screen :confused:

Here’s a better formatted one:

https://dl.dropboxusercontent.com/u/101118701/Formatted.txt

Hey -

From what I can see of the code it looks correct. Can you test this in the blueprint using the mesh by adding a “Get Socket Transform” node with the target set to your skeletal mesh, the socket name as your thruster, and the transform space set to RTS Actor. Break the Transform return value and wire the Location into a Print String node. If you call the Print String on a keypress it should show the relative location of the thruster on the screen. This can be tested further with a “Get Socket Location” node, however this will assume Transform Space is set to World.

Cheers

Hello!

With the blueprint it does seem to return the right transform, at least its not (0,0,0), even when setting it to RTS Component.

But with code, it doesn’t. Why would this be?

EDIT: I tested the code in the BeginPlay() fuction, and it works!
I might have forgotten to mention this was in the constructor of the pawn.

Does this really not work in the constructor? I would think after setting up the skeleton, it would know the relative position from the component’s pivot point, but I just started using UE4 like, 4 months ago, I might not know everything :wink:

The constructor should be reserved for setting up the actor’s defaults rather than trying to perform actions since it can’t be guaranteed which order things are constructed.

Thanks for helping me, I appreciate it!