Npc goes to a really high position after touching the player

I have an NPC that is supposed to teleport slowly towards the nearest player with a distance limit, the full script here:

local evil = script.Parent
local humanoid = evil:WaitForChild("Humanoid")
local hitbox = evil.NotTorso
local snd = hitbox:WaitForChild("teleport")

function FindTarget()
	local maxDistance = math.huge
	local target = nil
	for i,v in pairs(workspace:GetChildren()) do
		if v:FindFirstChild("Humanoid") then
			if (v.Humanoid.RootPart.Position-evil.Humanoid.RootPart.Position).magnitude < maxDistance then
				target = v.Humanoid.RootPart
			end
		end
	end
	return target
end

task.defer(function()
	while task.wait(40 / (humanoid.WalkSpeed)) do
		local maxDistance = humanoid.WalkSpeed * 2.5
		local target = FindTarget()
		print(target, target.Position)
		if not target then return end
		local position = target.Position
		local direction = (humanoid.RootPart.Position - position).Unit
		local distance = (humanoid.RootPart.Position - position).Magnitude
		if distance > maxDistance then
			distance = maxDistance
		end

		local targetPos = (humanoid.RootPart.Position + direction * -distance)

		local RX, RY, RZ = CFrame.lookAt(humanoid.RootPart.Position, targetPos):ToOrientation()
		local lookAt = CFrame.Angles(0,RY,0)
		local targetCF = CFrame.new(targetPos) * lookAt.Rotation

		evil:PivotTo(targetCF)
		humanoid.Sit = false
	end
end)

For some reason, when the npc gets to the same position as the nearest player, it teleports to ~ (0,90000,0) and slowly teleports back down or gets destroyed.


rarely, it also disappears upon spawning to the same position.

i have narrowed the issue down to this part. it is supposed to get the orientation for the NPC to point towards the player.

		local RX, RY, RZ = CFrame.lookAt(humanoid.RootPart.Position, targetPos):ToOrientation()
		local lookAt = CFrame.Angles(0,RY,0)
		local targetCF = CFrame.new(targetPos) * lookAt.Rotation

what should i do about this issue?

The problem is actually in the direction (unit) and not the cframe.

The unit of a vector will be { NAN, NAN, NAN } if its magnitude is 0 (only if all of its values are 0). If you set any world instance’s position to a vector that contains NAN, it will bug.

Below is the code I used in the command bar to test this (the file is too big but you can do this too):

local pos = Vector3.new(10, 0, 0) - Vector3.new(10, 0, 0) -- result: vector{ 0, 0, 0 } (magnitude of 0)
local unit = pos.Unit -- result: vector{ NAN, NAN, NAN }

local Character = workspace.bossfighter3 -- your name won't be bossfighter3 of course

Character:PivotTo(CFrame.new(unit))

To fix your problem you can just use an if statement, when the distance is equal to 0.

1 Like

i changed the pivot to this, but nothing changed

if distance > 0 then
	evil:PivotTo(targetCF)
else
	evil:PivotTo(target.CFrame)
end

[i know im a little late, but to follow up with what bloxfight said, he’s right that the unit vector will return nan and should check if the distance is zero

I’ve basically made it so the npc can only move horizontally (preventing it from teleporting up)


task.defer(function()

	while task.wait(40 / (humanoid.WalkSpeed)) do
		local maxDistance = humanoid.WalkSpeed * 2.5
		local target = FindTarget()
		print(target, target.Position)
		if not target then return end
		
		local position = target.Position
		local offset = Vector3.new(position.X - humanoid.RootPart.Position.X, 0, position.Z - humanoid.RootPart.Position.Z)
		local distance = offset.Magnitude
		if distance == 0 then
			continue
		end
		if distance > maxDistance then
			distance = maxDistance
		end
		local direction = offset.Unit
		local targetPos = (humanoid.RootPart.Position + direction * distance)
		local RX, RY, RZ = CFrame.lookAt(humanoid.RootPart.Position, targetPos):ToOrientation()
		local lookAt = CFrame.Angles(0,RY,0)
		local targetCF = CFrame.new(targetPos) * lookAt.Rotation
		evil:PivotTo(targetCF)
		humanoid.Sit = false
	end

end)