CFrame.LookVector/:LookAt without creating a new CFrame table?

Hello! I’ve been trying to learn about Lua more in depth so I could optimize the scripts I make in better ways and keep their foot prints as small as possible. Turns out one of the most intensive tasks for Lua is indexing things like tables or instances etc. so I wanna write a function that returns a position and an orientation from a given position and orientation kind of similar to CFrame.LookVector except without a table that has 12 diff numbers that I don’t need/not interested in. So far this is what I got:
image

The problem is it only works in x rotation/y position and I couldn’t get it to work on other axises to get full pointing capability I’d like to know if there are any alternatives to CFrame:LookAt(PosAt,Pos) etc. or if there is a possible way to get my script to work. I’ve been trying for 2 days but I’ve gotten nowhere, this is what it looks like in its current form:

local pi = math.pi
local sin, cos, tan = math.sin, math.cos, math.tan
local new, Vector3new, CFramenew, CFrameAngles, C3new = Instance.new, Vector3.new, CFrame.new, CFrame.Angles, Color3.new
local HBeat, TweenService = game:GetService("RunService").Heartbeat, game:GetService("TweenService")
local Size = Vector3new(.1,.1,.1)
local Pos = Vector3new(0,15,0)
for i = 1, 20 do
	local Rot = (pi/10)*i
	for i = 1, 20 do
		local Part = new("Part",script)
		Part.Size = Size
		Part.Anchored = true
		Part.Position = Vector3new(sin(Rot)*10*sin(i*(pi/10)),cos(i*(pi/10))*10,cos(Rot)*10*sin(i*(pi/10)))+Pos
	end
end

function LookVector(X,Y,Mag)
	return Vector3new(0,cos(Y)*Mag,cos(X)*Mag*sin(Y))
end
--[[function LookVector(X,Y,Mag)
	return Vector3new(sin(X)*Mag,0,cos(X)*Mag)
end
function LookVector(X,Y,Mag)
	return Vector3new(sin(X)*Mag*sin(Y),cos(Y)*Mag,cos(X)*Mag*sin(Y))
end]]

local Size2 = Vector3new(.3,.3,.3)
local Size3 = Vector3new(.3,.3,10)

for I = 1, 20 do
	local Rot = (I/10)*I
	for i = 1, 20 do
		local Y = (i/10)*pi
		local Part = new("Part",script)
		Part.Size = Size2
		Part.Anchored = true
		Part.Color = C3new(1,0,0)
		Part.Position = LookVector(Rot,Y,5) + Pos
		local Part_ = new("Part",script)
		Part_.Size = Size3
		Part_.Anchored = true--CFrameAngles((pi/10)*15+Y,0,0) + LookVector(0,Y,5) + Pos
		Part_.CFrame = CFrameAngles((pi/2)*3+Y,0,0) + LookVector(0,Y,5) + Pos --CFrameAngles(cos(Y+(pi*2)),Rot,0) + LookVector(Rot,Y,5) + Pos 
		wait()
	end
end

Keep in mind the whole reason why I want something like this in the first place is to reduce lag via eliminating the unnecessary table/dictionary creation luau does every time you use something like CFrame:LookAt(PosAt,Pos).

A little bit of hyperbole there—the culprit for performance problems will almost never be that you’re indexing tables instead of using local variables. Your algorithm is usually much more important. Don’t prematurely micro-optimize :slight_smile:. But in certain cases it can have an affect, sure.

But you should always test your code to see where the speed is actually being lost instead of assuming.

IMO, replacing things like Vector3.new with Vector3new, etc. usually causes more issues with readability than it solves with “speed”.

That’s all just my opinion, though. Write your code how you want!


To answer your actual question: you probably won’t be able to beat the speed of CFrame.LookAt.

You could re-implement it using fromMatrix:

local UP = Vector3.new(0, 1, 0)
local function CFrameLookAt(from, to)
	local back = from - to
	local right = UP:Cross(back)
	local up = back:Cross(up)
	return CFrame.fromMatrix(from, right, up, back)
end

You could even implement Cross yourself. You could even use the CFrame.new(...components...) constructor which takes the 12 variables that make up the rotation matrix and position and calculate each of them yourself.

…But, why would you? CFrame.LookAt does all of this, and it does it in C instead of lua. It also is hyper-optimized already, well tested, and easy to understand when you read it!

Have you checked that this is causing any lag? Have you benchmarked code? Also CFrame.LookAt isn’t implemented in lua in the first place, it’s a bound C function. There’s almost certainly nothing you’d be able to do to beat it. Luau native functions are really fast.

1 Like