# Convert a Vector3 relative to a different CFrame?

Struggling to get this down, I’m recording an array of player’s positions, I also store the CFrame (labelled with the black dot with arrow). So in the case that CFrame changes, I want the positions to also change, they should have the same offset from eachother but be positioned in the same direction and area as the new CFrame.

Yeah I know it’s to do with converting to object space, I’m just not sure how to go about the operation.

This could also work. It will show the positions in the array relative to the CFrame of a part in workspace named “Part”

``````local function Point(CF)
local Part = Instance.new("Part")
Part.Material = Enum.Material.Neon
Part.Color = Color3.fromRGB(133, 255, 88)
Part.CanCollide = false
Part.CFrame = CF
Part.Shape = Enum.PartType.Ball
Part.Size = Vector3.new(0.3, 0.3, 0.3)
Part.Anchored = true
Part.Parent = workspace
coroutine.wrap(function()
Part:Destroy()
end)()
end

local Positions = {
Vector3.new(10, 0, 5),
Vector3.new(1, 5, 5)
}

local function Update()
local CF = workspace.Part.CFrame

for i, v in pairs(Positions) do
Point(CF * CFrame.new(v))
end
end

game:GetService("RunService").RenderStepped:Connect(function()
Update()
end)
``````

This is definitely super helpful, Right now though it seems to only work if CF is 0,0,0. So there’s some ObjectSpace or WorldSpace magic that needs to be figured out. I’ve tried PointToObjectSpace and VectorToObjectSpace but I fear I’m using them wrong.

(With the red part set to the origin, the result works great and as intended)

(If we shift the red part away from 0,0,0, the end position also ends up shifted)

PointToObjectSpace updated it so the sphere is always in the right place, but then shifting the red part didn’t update the sphere

If that was the result you wanted, let me explain how I did that.
I coded two arbitrary points that should be relative to the part by doing some CFrame manipulation. Later I used the `.Position` property of the manipulated CFrame to get a Vector3 position and generated a part there.
Script:

``````local parts = script.Parent:GetChildren();

for _,p in ipairs(parts) do
if not p:IsA("Part") then continue; end

local rightDot = p.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(-15), 0) * CFrame.new(0, 0, -5);
local leftDot = p.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(22.5), 0) * CFrame.new(0, 0, -8);

local p1 = Instance.new("Part");
p1.Anchored = true;
p1.Material = Enum.Material.Neon;
p1.Size = Vector3.new(0.5, 0.5, 0.5);
p1.Position = rightDot.Position;
p1.Parent = workspace;

local p2 = p1:Clone();
p2.Position = leftDot.Position;
p2.Parent = workspace;
end
``````
1 Like

I was just able to solve this a similar way but this was a very clear explanation, thank you.

1 Like