[SOLVED] Npc keeps teleporting back into the middle

I know I post here a lot, but the code I made is odd because I’m not the best at coding.
This code is supposed to bring them to the middle of the last room, then go to the entrance of the last room.
It does the first part, but when it’s supposed to go to the entrance, it constantly goes back to the middle, eventually getting :Destroy()-ed.

local RunService = game:GetService("RunService")

local loop

local function checkLockers(CurrentRoom)
	local TweenService = game:GetService("TweenService")
	local speed = 10

	local goal = {}
	goal.Position = game.Workspace.Rooms[CurrentRoom.Value].Enter.Position

	local distance = (script.Parent.PrimaryPart.Position - game.Workspace.Rooms[CurrentRoom.Value].Enter.Position).Magnitude
	local timeInSeconds = distance/speed

	local tweenInfo = TweenInfo.new(timeInSeconds)

	local tween = TweenService:Create(script.Parent.PrimaryPart, tweenInfo, goal)

	tween:Play()
	wait(5)
	script.Parent:Destroy()
end
4 Likes

Is the npc a model? You might need to tween its cframe, such as its world origin, or something like that.

3 Likes

So replace script.Parent.PrimaryPart.Position with script.Parent.WorldPosition?

2 Likes

Try this for your tween, see if that makes any difference

local tween = TweenService:Create(script.Parent,tweenInfo,{WorldPivot = goal})

make sure goal is a cframe value

2 Likes

If you don’t mind, could you explain a little more on what you are actually wanting the npc to do?
I see you have a DoorPart, and A60Stop and you are checking magnitude in a loop and using MoveTo, but also using PivotTo. Its a bit confusing as to what you are actually wanting to happen.

1 Like

PivotTo is for when he reaches his destination. It pivots him back to the middle if he goes too far.
MoveTo is for him to go through the rooms because he has a humanoid and he’s an NPC.
DoorPart is just the Door.
A60Stop is the middle of the room, technically.
Heres a really weird drawing of what I want him to do.


Here’s the code.

local RunService = game:GetService("RunService")

local loop

local function checkLockers(CurrentRoom)
	local TweenService = game:GetService("TweenService")
	local speed = 10

	local goal = {}
	goal.Position = game.Workspace.Rooms[CurrentRoom.Value].Enter.CFrame

	local distance = (script.Parent.PrimaryPart.Position - game.Workspace.Rooms[CurrentRoom.Value].Enter.Position).Magnitude
	local timeInSeconds = distance/speed

	local tweenInfo = TweenInfo.new(timeInSeconds)

	local tween = TweenService:Create(script.Parent,tweenInfo,{WorldPivot = goal})

	tween:Play()
	wait(5)
	script.Parent:Destroy()
end

loop = RunService.Heartbeat:Connect(function()
	if game.ReplicatedStorage.CurrentRoom.Value ~= nil and script.Parent.Temp.Value == false and script.Parent.TargetReached.Value == false then
		local CurrentRoom = game.ReplicatedStorage:WaitForChild("CurrentRoom")
		script.Parent.Humanoid:MoveTo(game.Workspace.Rooms[CurrentRoom.Value].Door.DoorPart.Position)
		local distance = (script.Parent.HumanoidRootPart.Position - game.Workspace.Rooms[CurrentRoom.Value].Door.DoorPart.Position).Magnitude
		if script.Parent.HumanoidRootPart.Position.X < game.Workspace.Rooms[CurrentRoom.Value].Door.A60Stop.Position.X then
			script.Parent:PivotTo(game.Workspace.Rooms[CurrentRoom.Value].Door.A60Stop.CFrame)
			wait(2)
			checkLockers(CurrentRoom)
			loop:Disconnect()
		end
	end
end)

What is the purpose of having him PivotTo, after he stops?

Let me create something and you tell me if this is similar to what you need.

(idk why this counts as empty afkfhskjfhsdkfjhsdfjhf)

WalkingTest.rbxl (158.5 KB)

local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")

local room = workspace.Rooms:FindFirstChild(game.ReplicatedStorage.CurrentRoom.Value)
if room then
	local destination = room.Door.DoorPart.Position
	humanoid:MoveTo(destination)
	local timer = ((npc.PrimaryPart.Position - destination).Magnitude/ humanoid.WalkSpeed)+2
	while timer > 0 do
		if ((npc.PrimaryPart.Position * Vector3.new(1,0,1)) - (destination *Vector3.new(1,0,1)) ).Magnitude < 2 then
			break
		end
		timer = timer - task.wait()
	end
	npc.PrimaryPart:PivotTo(room.Door.A60Stop.CFrame)
end

If you will download the place file and run it, let me know if this is the result you are trying to achieve.

Not exactly. I want him to go to the A60 stop, then when he’s reached it, go to the entrance. I have to make it a tween, because sometimes the floor isn’t even there due to intentional gaps.

So he walks to the A60, then he stops there (does he stop there for a period of time?) then after that he moves to the entrance (does he walk there, or teleport there?)

Stops for 2 seconds.
Also he walks there.

There could also be a possibility he’s teleporting back because of this loop but I don’t know for sure.

Try this…
WalkingTest2.rbxl (159.0 KB)

function WalkToLocation(npc, dstCFrame)
	if dstCFrame and npc then
		local humanoid = npc:WaitForChild("Humanoid")
		humanoid:MoveTo(dstCFrame.Position)
		local timer = ((npc.PrimaryPart.Position - dstCFrame.Position).Magnitude/ humanoid.WalkSpeed)+2
		while timer > 0 do
			if ((npc.PrimaryPart.Position * Vector3.new(1,0,1)) - (dstCFrame.Position *Vector3.new(1,0,1)) ).Magnitude < 2 then
				break
			end
			timer = timer - task.wait()
		end
		npc.PrimaryPart:PivotTo(dstCFrame) 
	end
end

local room = workspace.Rooms:FindFirstChild(game.ReplicatedStorage.CurrentRoom.Value)
if room then
	npc = script.Parent
	WalkToLocation(npc,room.Door.A60Stop.CFrame)
	task.wait(2)
	WalkToLocation(npc,room.Door.DoorPart.CFrame)
	npc:Destroy()
end

Don’t use loops then.

while script.Parent do
	if game.ReplicatedStorage.CurrentRoom.Value ~= nil and script.Parent.Temp.Value == false and script.Parent.TargetReached.Value == false then
		local CurrentRoom = game.ReplicatedStorage:FindFirstChild("CurrentRoom")
		script.Parent.Humanoid:MoveTo(game.Workspace.Rooms[CurrentRoom.Value].Door.DoorPart.Position)
        script.Parent.Humanoid.MoveToFinished:Wait()

        task.wait(2)
        checkLockers(CurrentRoom)
	end
end)

Honestly, there is no need for while true loop also.

I use a while loop in mine, because of habit, sometimes my destination target moves, and I reset the MoveTo each iteration of the loop (and yes I know you can set MoveTo to be relative to a part, and I assume if that part moves, it will continue to follow that part, but I never tested it)

However in case the path is blocked and the npc can never reach the goal, I like to use a while so I can set a timer for the length of time it should take a humanoid to walk to the destination, and break out of the loop and pivotTo him to the destination. Its just to make sure he doesnt get stuck.

Script timeout: exhausted allowed execution time
im pretty sure “while script.parent do” is a loop

while script.Parent do
	if game.ReplicatedStorage.CurrentRoom.Value ~= nil and script.Parent.Temp.Value == false and script.Parent.TargetReached.Value == false then
		local CurrentRoom = game.ReplicatedStorage:FindFirstChild("CurrentRoom")
		script.Parent.Humanoid:MoveTo(game.Workspace.Rooms[CurrentRoom.Value].Door.DoorPart.Position)
        script.Parent.Humanoid.MoveToFinished:Wait()

        task.wait(2)
        checkLockers(CurrentRoom)
	end

    task.wait(0.5)
end)

Were you able to try out the WalkTest2 in my post above?
Is that more of what result you were needing?

Technically, but i need it to tween the model to the A60stop instead of walking. other than that it’s fine