Help with turning npc

I’ve been trying to make it so an npc is facing the direction of a player when the player walks into a certain range, however the script I made to do this is just teleporting the character up and down really fast. Does anybody know how to fix this?

self.lookAt = true;
		
while self.lookAt do
	local currCF = self.model:GetPrimaryPartCFrame();
	local lookAt = CFrame.lookAt(currCF.p, root.Position);
			
	self.model:SetPrimaryPartCFrame(lookAt);
	RunService.RenderStepped:Wait();
end;

Change:

CFrame.lookAt(pos, rot)

To:

CFrame.new(pos, rot)

It’s doing the same exact thing as before

It’s the same thing. The latter is just no longer recommended.


@Q_ubit, don’t know if this would change anything, but try this:

self.lookAt = true;
		
while self.lookAt do
    local m = self.model;
	m:SetPrimaryPartCFrame(CFrame.lookAt(m:GetPrimaryPartCFrame().Position, root.Position));
	RunService.RenderStepped:Wait();
end;

If this still doesn’t work, then you can bind the function to a render event and disconnect it when it’s disabled.

self.lookAt = true;
		
local connection;

connection = game:GetService("RunService").Heartbeat:Connect(function()
    if not self.lookAt and connection then
       connection:Disconnect();
       return;
    end;

	self.model:SetPrimaryPartCFrame(CFrame.lookAt(self.model:GetPrimaryPartCFrame().Position, root.Position));
end);
1 Like

I’ve made some progress

self.lookAt = true;
local cos, sin = math.cos, math.sin
		
while self.lookAt do
	local currCF = self.model:GetPrimaryPartCFrame();
	local ori = player.Character.PrimaryPart.Orientation;
	local lookAt = CFrame.Angles(ori.X * 0, cos(ori.Y), sin(ori.Z));
			
	self.model:SetPrimaryPartCFrame(currCF * lookAt);
	RunService.RenderStepped:Wait();
end;

I know that the lookAt variable is calculating the correct angle, however since I’m multiplying currCF and lookAt it’s spinning the character. I’m not sure how to apply the change in orientation without multiplying those two variables.

I reduced some of the random spinning by making the ori variable equal to player.Character.PrimaryPart.Orientation * tick()

You can get the y rotation (probably what you want) by doing this:

local currentCFrame = self.model:GetPrimaryPartCFrame()
local targetVector = (currentCFrame.Position - root.Position)
local angle = math.atan2(targetVector.X, targetVector.Z)
self.model:SetPrimaryPartCFrame(CFrame.new(currentCFrame.Position) * CFrame.Angles(0, angle, 0))