Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 5 years ago

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

Log in to vote
1
Answered by 5 years ago

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!

0
Woah, it works perfectly! Thank you! Adv3rtizement 101 — 5y
Ad

Answer this question