Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why doesn't my movement script work? (The npc get jittery then stops)

Hello! I've been working with a script that moves an npc between 2 parts. It works fine for like 50 loops and then it starts glitching out - the npc starts pausing and resuming movement and then ultimately freezes and returns false for moveToFinished reached variable. I ended up making a demo so I could test the script by itself - I've simplified it soo much but it still is broken. I was hoping maybe someone else could look at my scripts.

If you are interested in the background of the scripts:

  • In the workspace there is a folder named "Parts" - it contains TWO parts. These are the 2 objects the npc will go back to and from.

  • The npc is in the workspace, all parts are unanchored, and the main script is in it. (The one that decides where the npc will go) ---I gave the npc 200 walkspeed so the testing would be faster.

  • The npc contains a stringValue named "currentAction" - It changes based on what the npc is doing. It starts with no value, then switched between "Moving" and "Arrived". The npc should move when it is "Arrived" but shouldn't start moving somewhere else while it is already "Moving"

  • There is a bindable function in the replicated storage named "move" - When invoked it the second script (the one that handles movement) will fire!

  • Finally, the movement script that handles movement is in the server script storage.

Here is a link to the game if you'd like to copy it: https://www.roblox.com/games/4004562445/Movement-Testing


Here is the first script. This one is inside the npc, it determines where to go.

currentAction = script.Parent.currentAction --Gets the currentAction StringValue from npc
--This will hold a value for what the npc is currently doing
--It shouldn't be doing anything when the npc is moving
partsFolder = workspace.Parts --A simple folder with 2 parts. For this demo the npc will go between them.
moveFunction = game.ReplicatedStorage.move --This is a simple bindableFunction that will be invoked to make the npc move.
npc = script.Parent --Just the character model
local loopNum = 0 --This will go up per loop. Used to simpily determine which part to go to
while wait(0.1) do
	if not(currentAction.Value=="Moving") then --If the npc isn't currently moving
		loopNum = loopNum + 1--Increases the loop number
		partNum = (loopNum % 2)+1 --Returns the remainder of a division of 2. Returns either 1 or 2.
		part = partsFolder:GetChildren()[partNum] --Gets part
		moveFunction:Invoke(npc,part) --Invokes the bindableFunction with the character model and a part from the folder.
		currentAction.Value = "Moving" --Changes value.	
	end
end

Here is the second script. This one is inside the serverScriptStorage - it moves the npc where it needs to go

moveFunc = game.ReplicatedStorage.move --Gets the bindable function for movement
moveFunc.OnInvoke = function (character,object) --Takes the npc and object
	local curAct = character.currentAction --holds the currentAction stringValue of the npc
	local func -- This variable will be used to disconnect the function after it is done.
	--This function will run when the npc finishes moving.
	local function moveFinished(reached)
		if reached then --If the npc has reached the destination
			func:Disconnect() --Disconnect the function (because we are done with it)
			print("Arrived") --Print arrived
			curAct.Value = "Arrived" --Set the current value to arrived so the npc knows it can move again!
		else --If the npc didn't make it to destination in time.
			print("Didn't reach") --Print that it didn't reach
		end
	end
	local hum = character.Humanoid --npc humanoid
	func = hum.MoveToFinished:Connect(moveFinished) --Connect the MoveToFinished event to moveFinished function
	hum:MoveTo(object.Position) --Makes the npc move to the object's position
end 

If you test it you should see that it works for a few times, but then after a while it starts to jitter (pause and go) then it will just pause overall. I set the walkspeed to 200 to speed up the testing process - I also put the parts close together. (Sometimes it goes up to 200+ before it starts glitching out - sometimes it is only 40)

If you have any ideas, please let me know. Thank you!

1 answer

✓ Accepted answer

The NPC might be acting like this because of network ownership. Usually when players get near NPCs that move, the NPCs might lag a bit. I don't exactly know how to explain on why it happens, but the network ownership link I gave you should help explain.

To fix this, we'll need to set every part's network owner in the NPC to the server. To do that we can use :SetNetworkOwner() and add nil as an argument.

Here's a quick example:

local Character = script.Parent --Script is inside NPC.

for _,v in pairs(Character:GetDescendants()) do -- Get everything in the NPC.
	if v:IsA("BasePart") then -- Checks if instance is a part.
		v:SetNetworkOwner(nil) -- Sets part network owner to the server.
	end
end

If you have any questions, just comment!

1 comment

0

Woah, it works perfectly! Thank you!

This discussion is preserved as it was. New answers, comments, and votes are closed.