Vector and CFrame math for BodyPosition

I am creating a BodyPosition Character that follows the player’s limbs with a set offset in a while loop.
To set the offset I simply calculate the offset when the limb instantiates and set it as the bodyPosition’s Position using the set offset. However, this doesn’t track the rotation of the object since it is a Vector, is there any way I can make it track the CFrame’s properties as well?

What I’m doing:

local offset = Limb.Position - TrailPart.Position
bodyPosition.Position = Limb.Position - offset

Offset Part from my hand. Looks alright.
image

But when I turn around 180 degrees, it’s now in front of my player.
image

I’m trying to make it so that I can still use BodyPosition, but maintain the Rotation and keep it behind the player even after my player rotates. How can I do this using Vector/CFrame math?

What you’re doing right now is shifting the position in world space. What you want to be doing is shifting it in object space.


The * operator of CFrames shifts things in object space. To get the CFrame directly behind Limb, you would use:

local cframe_behind = limb.CFrame * CFrame.new(0, 0, -1)

To get the position directly behind the limb, you can use one of the following:

local position_behind = (limb.CFrame * CFrame.new(0, 0, -1)).p  -- p gets the position of a cframe

or:

local position_behind = limb.CFrame * Vector3.new(0, 0, -1)  -- * with a vector returns a vector

If you need to set the CFrame of the parts using BodyMovers, you’ll need a BodyPosition and a BodyGyro. The BodyPosition will set the position, and the BodyGyro will set the rotation. The BodyGyro has a cframe property. You can combine the cframe_behind and position_behind values to set what you need in these BodyMovers. You can experiment with these examples to find out how to set it to new offsets or use a saved offset.

Alternatively, you could use the AlignPosition and AlignOrientation objects, which should work about the same. It might even be easier because you can just set an attachment’s CFrame to the offset you want then set the AlignPosition and AlignOrientation to the limb’s CFrame and they will do all of the math for you.


If you need to get a CFrame or position in object space, you can use:

local some_cframe_in_object_space = limb.CFrame:toObjectSpace(some_cframe)
local some_position_in_object_space = limb.CFrame:pointToObjectSpace(some_position)

You can convert back to world space with:

local some_cframe = limb.CFrame*some_cframe_in_object_space
local some_position = limb.CFrame*some_position_in_object_space
4 Likes