CFrame.LookAt teleporting a block?

Currently I’m trying to make it so an NPC will always look at a player, even while moving.
How I’m trying to do it now is having a part constantly teleport and look at the player and use allignorientation between the NPC and the block, however this is what has ended up happening to the block that is supposed to be following and looking at the player.
image
It doesn’t move from this position.

If I remove the CFrame.LookAt part of the code, it’ll teleport to me fine.


I have both the block and the script that teleports the block parented to the player.
Here is the script that teleports, it is disabled be default and parented to the script under this one.

local following = script.Parent.HumanoidRootPart
local block = script.Parent:FindFirstChild("TheGuy")

while true do
	block.Position = following.Position
	wait(.5)
end

Here is the relevant part of the script that gives the script and block, note that it is parented to the NPC.

		if blockfollowing == false then
			blockfollowing = true
			local block = Instance.new("Part")
			block.Transparency = 0
			block.CanCollide = false
			block.Name = ("TheGuy")
			block.Parent = target.Parent
			block.Anchored = true
			local scr = script.childscript:Clone()
			scr.Parent = target.Parent
			scr.Enabled = true
		end

And here is the full NPC script.

local larm = script.Parent:FindFirstChild("HumanoidRootPart")
local rarm = script.Parent:FindFirstChild("HumanoidRootPart")

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 10000
	local temp = nil
	local human = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.className == "Model") and (temp2 ~= script.Parent) then
			temp = temp2:findFirstChild("HumanoidRootPart")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and game.Players:GetPlayerFromCharacter(human.Parent) then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					
					dist = (temp.Position - pos).magnitude
				end
			end
		end
	end
	return torso
end



local blockfollowing = false

while true do
	wait(.5)
	local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	if target ~= nil then
		if blockfollowing == false then
			blockfollowing = true
			local block = Instance.new("Part")
			block.Transparency = 0
			block.CanCollide = false
			block.Name = ("TheGuy")
			block.Parent = target.Parent
			block.Anchored = true
			local scr = script.childscript:Clone()
			scr.Parent = target.Parent
			scr.Enabled = true
		end
		script.Parent.Humanoid:MoveTo(target.Position - Vector3.new(5,5,5))
		script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
	end
end

Any help?

2 Likes

Whats happening is when setting cf.lookat it sets the cf to be its current cf with new angles, this means when teleporting you have 2 lots of cf positions which buggs out your script. Ideally you need a way of stopping the lookat while its teleporting, this would have no effect at stopping the lookat effect as you can still teleport and make it face where you want

1 Like

I assume that the line of code you tried using with CFrame.LookAt looked something similar to this:

block.CFrame = CFrame.new(following.Position, following.Position) -- (Position, LookAt)

Note that both the Position and LookAt parameters are the same exact location. When this happens the position usually sets to what your screenshots show. To fix this, you must make sure you are passing two different vector positions. What I recommend is adding the LookVector of the player being followed to the position parameter as shown below:

local following = script.Parent.HumanoidRootPart
local block = script.Parent:FindFirstChild("TheGuy")

while true do
    local look = following.CFrame.LookVector
	block.CFrame = CFrame.LookAt(following.Position + look, following.Position)
	wait(.5)
end

I believe there are simpler options to create what you are hoping for, but this should fix the problem you were having setting the CFrame of the part.

I typed this outside of studio so let me know if there are any bugs!

1 Like

Thank you! It’s working now. May I ask what you think the simpler option is? I couldn’t get LookAt on the NPC to work.

1 Like

I might have misspoken when I said simpler. It’s more complicated math wise, but in the end is more efficient and easier to handle.

I would get rid of the whole concept of using a teleporting part to align the NPC and instead get the direction from the NPC to the player using vector math.

NOTE before removing any of your code I would first make sure that what i suggest works

But I would recomend replacing your while true loop within the main script with this:

while true do
	wait(.5)
	local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	if target ~= nil then
		local targetCFrame = target.CFrame
		local NPCRoot = script.Parent.HumanoidRootPart
		local NPCFrame = NPCRoot.CFrame
		local direction = targetCFrame.Position - NPCFrame.Position -- getting direction from npc to player
		local xzDirectionUnit = Vector3.new(direction.X, 0, direction.Z).Unit
		script.Parent.Humanoid:MoveTo(target.Position - (xzDirectionUnit * 5))
		NPCRoot.CFrame = CFrame.lookAt(NPCFrame.Position, NPCFrame.Position + xzDirectionUnit)
	end
end

I think this should work the way you intended it to without the need of a block. However, I am not able to test it myself. If it doesn’t work, I would ignore this for now and continue with your method.

Hope this helps!

This is what I tried and it worked, however the NPC won’t move after moving a single time it’s the same issue I had when I tried it, thank you for the help though!

2 Likes

That’s weird not sure why that would happen. I’m glad the other way worked for you though! Hope the rest of your project goes well!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.