CFrame connect two parts and rotate/look at a third part

My knowledge of CFrames has always been flimsy at best and I’m running into some trouble. I’ll explain my problem with a picture:

Picture

I want to create a part connecting points A and B, looking at C. Connecting A and B is easy, but I’m having trouble rotating it on one axis to face C correctly.
Just setting the CFrame to ((a.Position + b.Position) / 2, a.Position) works, except it doesn’t face C.

Setting the CFrame to ((a.Position + b.Position) / 2, c.Position) doesn't work either

I just need the part to rotate on the X or Z axis to face point C, but I’m not sure how to accomplish that.

I’m a bit confused, are you trying to just get one axis to face the part but sort of “lock” the part to be between the 2 other parts?

1 Like

Yeah! So I’d normally just have it face Part A or B and call it a day, but I need it to also rotate on one axis to have a side face C too.

1 Like

CFrame.fromMatrix is a better constructor that lets you specify the three axes manually (or just two and infer the third)

local pos = (a + b) / 2
local right = c - pos -- swap to make left face point toward C
local back = a - b
local up = -right:Cross(back)
local cf = CFrame.fromMatrix(pos, right, up, back)

Now cf is positioned between a and b, with its right vector pointed towards c.

2 Likes

I feel like that’s one angle/side away from working perfectly. When A and B aren’t a single axis away (i.e. (3, 20, 1) instead of (20, 0, 0)), it doesn’t connect them

Summary

from:

Function
local function ConnectParts(part1, part2, facePos)
local a = part1.Position
local b = part2.Position
local c = facePos
local pos = (a + b) / 2
local right = c - pos
local back = a - b
local up = -right:Cross(back)
local cf = CFrame.fromMatrix(pos, right, up, back)
local clon = game.Workspace.Part:Clone()
clon.Name = "ConnectPart"
local length = (a - b).magnitude
clon.Size = Vector3.new(3, 3, length)
clon.CFrame = cf
clon.BrickColor = BrickColor.new("Really red")
clon.Transparency = 0
clon.Parent = game.Workspace.Folder
end

I still need help on this, bumpo

Oh, my bad, I know what’s wrong. Give me a bit to fix.

1 Like

Maybe this

local pos = (a + b) / 2
local ray = (b - a).Unit
local pOnRay = (c - a):Dot(ray) + a
local right = c - pOnRay -- swap to make left face point toward C
local up = right:Cross(ray)
local cf = CFrame.fromMatrix(pos, right, up, -ray)

Sorry can’t test myself

1 Like
local pOnRay = (c - a):Dot(ray) + a

The :Dot returns a single number and not a Vector3, so it can’t be added to a. I tried multiplying it instead but that didn’t work

Sorry yes you’re right.

local pOnRay = (c - a):Dot(ray) * ray + a

Woes of coding on my phone :slight_smile:

1 Like

Thank you!!! That works perfectly.