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

Does anyone know how to help me with this issue im having with my NPC follow player script?

Asked by 3 years ago

So im working on a game and im trying to get an NPC to follow a player around the map. So far i have this script going.

local NPC = game.Workspace.Matt
local pathfinding_service = game:GetService("PathfindingService")

function getClosestPlayer()
    local closest_player, closest_distance = nil, 200
    for i, player in pairs(workspace:GetChildren()) do
        if player:FindFirstChild("Humanoid") and player ~= NPC then
            local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
            if distance < closest_distance then
                closest_player = player
                closest_distance = distance
            end
        end
    end
    return  closest_player, closest_distance
end

while true do
    local path = pathfinding_service:CreatePath()
    local player, distance = getClosestPlayer()
    if player and distance > 10 then
        path:ComputeAsync(NPC.HumanoidRootPart.Position, player.PrimaryPart.Position)
        local waypoints = path:GetWaypoints()
        for _, waypoint in pairs(waypoints) do
            NPC.Humanoid.MoveTo(Waypoint.Position)
            while true do
                local distance = (NPC.PrimaryPart.Position - waypoint.Position).Magnitude
                local distance_from_player = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
                if distance < 5 then
                    break
                end
                if distance_from_player < 10 then
                    NPC.Humanoid:MoveTo((NPC.HumanoidRootPart.CFrame*CFrame.new(0,0,-3)).p)
                    break
                end
                wait()              
             end
         end
    end
    wait()
end


It is giving me this in the output

Workspace.Matt.Follow the Player:8: attempt to index nil with 'Position'

this is the line it is referencing

local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude

If anyone has any idea how to fix this issue, let me know please! thanks!

0
Try using the HumanoidRootPart instead of the primary part (NPC.HumanoidRootPart and player.HumanoidRootPart) WoTrox 345 — 3y
0
would i replace all PrimaryPart with what you suggested in the script? lucas99884 0 — 3y
0
PrimaryPart only works with models, ensure that NPC is a model JesseSong 3916 — 3y
0
Re-edited check my answer, this will work. JesseSong 3916 — 3y
0
also remove any other script in the model, except your script or scripts. JesseSong 3916 — 3y

2 answers

Log in to vote
0
Answered by
WoTrox 345 Moderation Voter
3 years ago
Edited 3 years ago

Here is a better way to get the closest player:

local closestM = math.huge --To make sure every number is less than this
local closestP = nil

for i,v in pairs(game.Players:GetPlayers()) do
    local mag = (NPC.HumanoidRootPart.Position - v.Character.HumanoidRootPart.Position).magnitude
    if mag < closestM then
        closestM = mag
        closestP = v
    end
end
--you can use the closestP as you want

I replaced the getClosestPlayer function with mine and every PrimaryPart with HumanoidRootPart. So now your script should look like this:

local NPC = game.Workspace.Matt
local pathfinding_service = game:GetService("PathfindingService")
function getClosestPlayer()
    local closest_distance = math.huge
    local closest_player = nil

    for i,v in pairs(game.Players:GetPlayers()) do
        local mag = (NPC.HumanoidRootPart.Position - v.Character.HumanoidRootPart.Position).magnitude
        if mag < closest_distance then
            closest_distance = mag
            closest_player = v
        end
    end
    return  closest_player, closest_distance
end

while true do
    local path = pathfinding_service:CreatePath()
    local player, distance = getClosestPlayer()
    local player_char = player.Character
    if player and distance > 10 then
        path:ComputeAsync(NPC.HumanoidRootPart.Position, player_char.HumanoidRootPart.Position)
        local waypoints = path:GetWaypoints()
        for _, waypoint in pairs(waypoints) do
            NPC.Humanoid.MoveTo(waypoint.Position)
            while true do
                local distance = (NPC.HumanoidRootPart.Position - waypoint.Position).Magnitude
                local distance_from_player = (NPC.HumanoidRootPart.Position - player_char.HumanoidRootPart.Position).Magnitude
                if distance < 5 then
                    break
                end
                if distance_from_player < 10 then
                    NPC.Humanoid:MoveTo((NPC.HumanoidRootPart.CFrame*CFrame.new(0,0,-3)).p)
                    break
                end
                wait()              
            end
        end
    end
    wait()
end
Ad
Log in to vote
0
Answered by
JesseSong 3916 Moderation Voter Community Moderator
3 years ago
Edited 3 years ago

Problem

The reason it didn't work was because there was no HumanoidRootPart, hence the error.

Check by clicking on this hyperlink

Make sure your NPC has a HumanoidRootPart by checking.

Fixed Script:

local NPC = game.Workspace.Matt
local pathfinding_service = game:GetService("PathfindingService")

function getClosestPlayer()
    local closest_player, closest_distance = nil, 200
    for i, player in pairs(workspace:GetChildren()) do
        if player:FindFirstChild("Humanoid") and player ~= NPC then
            local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
            if distance < closest_distance then
                closest_player = player
                closest_distance = distance
            end
        end
    end
    return  closest_player, closest_distance
end

while true do
    local path = pathfinding_service:CreatePath()
    local player, distance = getClosestPlayer()
    if player and distance > 10 then
        path:ComputeAsync(NPC.HumanoidRootPart.Position, player.PrimaryPart.Position)
        local waypoints = path:GetWaypoints()
        for _, waypoint in pairs(waypoints) do
            NPC.Humanoid:MoveTo(waypoint.Position)
            while true do
                local distance = (NPC.PrimaryPart.Position - waypoint.Position).Magnitude
                local distance_from_player = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
                if distance < 5 then
                    break
                end
                if distance_from_player < 10 then
                    NPC.Humanoid:MoveTo((NPC.HumanoidRootPart.CFrame*CFrame.new(0,0,-3)).p)
                    break
                end
                wait()              
            end
        end
    end
    wait()
end


Recommendation(s):

  • Use :MoveTo because .MoveTo isn't a function.

Also, ensure that your script is in Workspace.

Thanks, JesseSong

0
Since your script is inside of the NPC it will give you that error, just put the script in workspace. JesseSong 3916 — 3y
0
I can tell that it's inside the NPC, because of the error code: Workspace.Matt.Follow the Player:8: attempt to index nil with 'Position' JesseSong 3916 — 3y
0
Notice where it says the scripts location? Which in this case is "Follow the Player" JesseSong 3916 — 3y
0
And the screenshot you sent me is here: https://gyazo.com/2fe00def849dc73683bc546251cd98ab JesseSong 3916 — 3y

Answer this question