Trying to make my own CFrame LookAt

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Making my CFrame LookAt works as intended

  2. What is the issue? It doesn’t

  3. What solutions have you tried so far? Any solutions Did you look for solutions on the Developer Hub? I haven’t found so far

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local part1 = workspace.Part1
local part2 = workspace.Part2

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local relativity = part2.CFrame:ToObjectSpace(part1.CFrame)
	local xAngle = -math.deg(math.atan2(relativity.Y,relativity.X))
	local yAngle = math.deg(math.atan2(relativity.X,relativity.Z))
	
	part1.Orientation = Vector3.new(xAngle,yAngle,0)

	print("Two angle between two parts are: "..math.floor(xAngle).."°".." "..math.floor(yAngle).."°")
end)

The Y rotation works fine, but for X and Z axis, it doesn’t work as intended

5 Likes

Is there any reason to really do this? Or is it just for a project. Also if I were to do this I’d use trig on the difference between the two positions to get the angles.

1 Like

I already used a trig function which is (atan2) that allows the angle up to 360°

1 Like

Oh wait mb I see what you mean. The code kinda got cut off because I’m on mobile.

1 Like

I believe you have to find out if both values are negative, then set the angle to negative if that is the case. Might also have to do it for when one of the angles is negative and the other isn’t.

1 Like

It’s funny that lookAt functions typically employ cross and dot products rather than trigonometric functions. But because Roblox has limited matrix support, we are forced (kind of) to use spherical coordinates. Though it is a little disappointing, it’s okay. This strategy is more trigonometric.

function LookAt(Eye: Vector3, Target: Vector3)
	local dx = Eye.X - Target.X
	local dy = Eye.Y - Target.Y
	local dz = Eye.Z - Target.Z

	local r = math.sqrt(dx^2 + dy^2 + dz^2)

	local theta = math.acos(dz / r)
	local phi = math.atan2(dy, dx)

	local Hat_r = Vector3.new(
		-math.sin(theta) * math.cos(phi),
		-math.sin(theta) * math.sin(phi),
		-math.cos(theta)
	)

	local Hat_theta = Vector3.new(
		-math.sin(phi),
		math.cos(phi),
		0
	)

	local Hat_phi = Vector3.new(
		math.cos(theta) * math.cos(phi),
		math.cos(theta) * math.sin(phi),
		-math.sin(theta) -- Adjusted sign
	)

	return CFrame.fromMatrix(
		Eye,
		Hat_theta,
		-Hat_phi,
		-Hat_r
	)
end

If you noticed me reacting, it’s because I tried the traditional approach but it wasn’t very effective. When the eye part’s x and z coordinates matched, my part was being expelled into nothingness. Anyway, here are some resources you may look at if you want to learn more about spherical coordinates or the conventional method of doing it.

Please ask me if you have questions or issues. I’m not bothered.

Spherical coordinates (The “magic”)

Conventional method for lookAt functions

Footage of the old method

I selected the part in the explorer and pushed F to get to it.

Footage of the new method (Spherical coordinates are very cool don’t you agree? :+1:)

Anyways a follow or like would be REALLY appreciated :exploding_head::exploding_head::exploding_head:!!! :sob: :sob: :sob: :sob: :sob: PLEAAASEEEEEEEEE PLEAASEEEEEEEEE PLEAAASEEEEEEEEEEE PLEAAASEEEEEEEEEEEE PLEAAAAAASEEEEEEEEEE :sob: :sob: :sob: :sob: :sob:

2 Likes

pretty complex, but anyway, sorry to break it but it doesn’t work

What’s the issue? Could you be more specific?

1 Like

as totally it doesn’t work, the function doesn’t

1 Like

Could you maybe share a short clip/video?

1 Like

1 Like

How did you implement it into the script? Can we see the source?

1 Like

wait, I think I misused it, let me check real quick

yep, I misused it, so it actually works but when I place the target to the same position as the eye, the eye disappears

Could you show the source and a quick clip?

That’s wierd. Doesn’t do that for me though? Could you maybe send the script’s content and your part dimensions (the size)?

1 Like
local part1 = workspace.Part1
local part2 = workspace.Part2

function LookAt(Eye: Vector3, Target: Vector3)
	local dx = Eye.X - Target.X
	local dy = Eye.Y - Target.Y
	local dz = Eye.Z - Target.Z

	local r = math.sqrt(dx^2 + dy^2 + dz^2)

	local theta = math.acos(dz / r)
	local phi = math.atan2(dy, dx)

	local Hat_r = Vector3.new(
		-math.sin(theta) * math.cos(phi),
		-math.sin(theta) * math.sin(phi),
		-math.cos(theta)
	)

	local Hat_theta = Vector3.new(
		-math.sin(phi),
		math.cos(phi),
		0
	)

	local Hat_phi = Vector3.new(
		math.cos(theta) * math.cos(phi),
		math.cos(theta) * math.sin(phi),
		-math.sin(theta) -- Adjusted sign
	)

	return CFrame.fromMatrix(
		Eye,
		Hat_theta,
		-Hat_phi,
		-Hat_r
	)
end

while task.wait() do
	part1.CFrame = LookAt(part1.Position, part2.Position)
	print("debug")
end

eye’s size is (9,1,2) while target’s size is (4,1,2)

1 Like

It seems like we can’t do anything about that since the normal CFrame.lookAt function has this problem too. I don’t know how but you found a super specific problem. :skull:

It’s not that big of a deal tho since you arent going to be in that situation often (I hope)

1 Like

regardless of these issue, I would say you have a stellar skills about programming especially math, and thank you for knowing how LookAt works and good luck on your next projects!

1 Like