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!
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!