NPC followers turn to the side after I stop walking?

I have an NPC party system like Deltarune’s, but the NPCs stop looking at the player when the player stops walking (I dunno how to explain this)

As seen in the video, after I stop walking, the NPCs just stop looking at the player resulting in… Weird positions?? To reproduce this, I have to walk in circles around the npc or jump on top of the npc.

This is the code in the gray dummy (the gray dummy and the glitchy guy have the same scripts except the glitch guy script follows the dummy rather than the player) (By the way I didn’t make most of the script myself, I just took it from a random dev forum post I found and edited it a little)

local NPC = script.Parent

game.Players.PlayerAdded:Connect(function(plr)
	wait(1)
	local otherNPC = plr.Character
	local NPCPos = otherNPC:WaitForChild("Torso")

	while true do
		wait(0.1)
		if (NPC.Torso.Position - NPCPos.Position).Magnitude > 6 then
			NPC.Humanoid:MoveTo(NPCPos.Position)
		else
			NPC.Humanoid:MoveTo(NPC.Torso.Position)
		end
	end
end)

Any help appreciated!

Its moving to the NPC’s position, I assume thats because you want it to stop walking. You can make it face the player once it’s stoped walking by putting this with it:

local CF1 = NPC.PrimaryPart.CFrame
local CF2 = NPCPos.PrimaryPart.CFrame
local X1, Y1, Z1 = CF1:ToEulerAnglesXYZ ( )
local X2, Y2, Z2 = CF2:ToEulerAnglesXYZ ( )

NPC:SetPrimaryPartCFrame(CFrame.new(CF1.Position) * CFrame.angles(X1, Y2, Z1))

Hi! The NPCs don’t follow me anymore… Did I put the code in the right place?

image

local NPC = script.Parent

game.Players.PlayerAdded:Connect(function(plr)
	wait(1)
	local otherNPC = plr.Character
	local NPCPos = otherNPC:WaitForChild("Torso")

	while true do
		wait(0.1)
		if (NPC.Torso.Position - NPCPos.Position).Magnitude > 6 then
			NPC.Humanoid:MoveTo(NPCPos.Position)
		else
			NPC.Humanoid:MoveTo(NPC.Torso.Position)
			local CF1 = NPC.PrimaryPart.CFrame
			local CF2 = NPCPos.PrimaryPart.CFrame
			local X1, Y1, Z1 = CF1:ToEulerAnglesXYZ ( )
			local X2, Y2, Z2 = CF2:ToEulerAnglesXYZ ( )

			NPC:SetPrimaryPartCFrame(CFrame.new(CF1.Position) * CFrame.angles(X1, Y2, Z1))
		end
	end
end)
1 Like

Yes, that is where I planned the code to be. I think it could be my fault the code is not working, I may have misspelled something. Tell me what it says in the output.

Oh no, looks like I did make a mistake.

I did a copy and paste and the CFrame article had spaces,
Try that.

local CF1 = NPC.PrimaryPart.CFrame
local CF2 = NPCPos.PrimaryPart.CFrame
local X1, Y1, Z1 = CF1:ToEulerAnglesXYZ()
local X2, Y2, Z2 = CF2:ToEulerAnglesXYZ()

NPC:SetPrimaryPartCFrame(CFrame.new(CF1.Position) * CFrame.angles(X1, Y2, Z1))

image
They follow me only once and then stay in the same place, but maybe there’s a problem with my loop. Idk though

Would you be able to show me a screenshot of the output window?

Ohhh I see now! Apparently the script is trying to check the primary part of the torso of the OtherNPC! I’ll fix it real quick


K I fixed it, now I get another error though

Show me the script that you changed and make sure to Include the line numbers in the screenshot.

Okay, looks like we need to fix this line of code so lets debug it.
Could you try changing it to:
NPC:SetPrimaryPartCFrame(CFrame.new())
See if it creates any errors there. If it does, then it might be something to do with NPC otherwise it’s the parameters.

No error in output, but this happens
robloxapp-20220626-1439290.wmv (1.5 MB)

I’m assuming that’s a good thing though as I don’t see any error in the output (Also, ironic how the devforum doesn’t support the video format that roblox uses to record videos)

I just want to come here and say that the SetPrimaryPartCFrame() methods are way too hacky for something like this.

So, what you want to do is add some form of a debounce. Although I see this while loop, constantly detecting the Magnitude of the distance, it doesn’t seem to be working. This is what we need to do.

I see a whole host of problems in the script, but let’s take a look at this one for now.

So, it looks like, from the code otherNPC is the player’s character (not sure why), and NPCPos is the character’s Torso (it should be HumanoidRootPart for R15 support, but that’s okay), now looking at the line if (NPC.Torso.Position - NPCPos.Position).Magnitude > 6 then this should have worked perfectly fine but it didn’t. This is obviously because you forgot a wait statement in the else statement!

Basically, the NPC will go at just the minimum position it can, but I would change two things.

  1. Change NPC.Humanoid:MoveTo(NPC.Torso.Position) to NPC.Humanoid:Move(Vector3.new(0,0,0)) since this should stop any problems with the wait statement above.

  2. Add a wait before that, so that there’s a bit of debounce when the NPC stops moving.

I hope this solution helped!

1 Like

This method will force the npc to face the player, which is what he wants.

It’s not a hacky solution.

By the way just wanna say the game forces R6 which is why I use the torso, I’m pretty sure it does the same thing as humanoid root part so I won’t change it, i’ll try the wait statement though. The problem is, I don’t want it to wait. But i’ll put it just to test ig

Yep, that’s what I’m trying to achieve

1 Like

No error in output? Thats good to hear.
That meants it’s the paramaters that are causing the error.
Now change it to this and check the output.

NPC:SetPrimaryPartCFrame(CFrame.new(CF1.Position))

Dont worry too much about what’s happening because we are just debugging.

Alright, I can give you a solution for that.

Still I don’t believe using SetPrimaryPartCFrame is such a good solution, I’m not completely sure how fast it is and if it’s good to run it constantly.

So, I would use NPC.HumanoidRootPart.CFrame = CFrame.lookAt(NPC.HumanoidRootPart.Position, NPCPos) and place it into that else statement you got there.

That block of code should look like this (although I recommend keeping a backup, just in case):

local NPC = script.Parent

game.Players.PlayerAdded:Connect(function(plr)
	wait(1)
	local otherNPC = plr.Character
	local NPCPos = otherNPC:WaitForChild("Torso")

	while true do
		wait(0.1)
		if (NPC.Torso.Position - NPCPos.Position).Magnitude > 6 then
			NPC.Humanoid:MoveTo(NPCPos.Position)
		else
			NPC.Humanoid:Move(Vector3.new(0,0,0)) --This will stop movement
            NPC.HumanoidRootPart.CFrame = CFrame.lookAt(NPC.HumanoidRootPart.Position, (NPCPos * Vector3.new(1, 0, 1)) + Vector3.new(0, NPC.HumanoidRootPart.Position.Y, 0))
		end
	end
end)

The code is longer, I would recommend copying this whole part.

I hope this helps.

It’s starting to work, I guess!

robloxapp-20220626-1505516.wmv (1.3 MB)