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

I try to fix the npcs so they don't attack eachother, but they still do. Fix?

The code is right here:

 	local Temp2 = nil
 	for x = 1, #List do
  		Temp2 = List[x]
  		if (Temp2.className == "Model") and (Temp2 ~= script.Parent) then
   			Temp = Temp2:findFirstChild("HumanoidRootPart")
   			Human = Temp2:findFirstChild("Humanoid")
			local plr = Human.Name
			if players:FindFirstChild(plr) then
   			if (Temp ~= nil) and (Human ~= nil) and (Human.Health > 0) then
    			if (Temp.Position - Position).magnitude < Distance then
     				Torso = Temp
     				Distance = (Temp.Position - Position).magnitude
						end
	    			end
	   			end
	 		end
		return Torso
	end
end
 



while true do
 	local target = findNearestPlayer(script.Parent.HumanoidRootPart.Position)
		if not target.Name == ("Goblin") then --how i try to make them not attack eachother
	  	if target ~= nil then
	  		script.Parent.Humanoid:MoveTo(target.Position, target)
		end
	end
end

I do not get any errors.

2 answers

✓ Accepted answer

Only search through players so that you won't have a chance of finding other goblins.

local function findNearestPlayer(pos)
    local closestRoot
    local closestDist
    for _, player in ipairs(game.Players:GetPlayers()) do -- Iterate over only the players
        local char = player.Character
        local humanoid = char and char:FindFirstChild("Humanoid") -- The "char and" is just in case a player's character is nil
        if humanoid and humanoid.Health > 0 then
            local root = char:FindFirstChild("HumanoidRootPart")
            if root then
                local dist = (root.Position - pos).Magnitude
                if not closestRoot or dist < closestDist then -- if this is the first player we've found or if it's closer than the closest player we've found so far
                    closestRoot = root
                    closestDist = dist
                end
            end
        end
    end
    return closestRoot
end

local root = script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
while true do
    wait(1) -- Don't forget to pause periodically to prevent freezing
    local target = findNearestPlayer(root.Position)
    if target then
        humanoid:MoveTo(target.Position, target)
    end
end

If you want them to attack other NPCs, you'll need to modify the function to look through all models in the workspace that could be a character (just like before), except this time ignore the model if it has a particular name (like "Goblin"), like so:

	-- inside the function...
	for _, model in ipairs(workspace:GetChildren()) do
		if model.Name == "Goblin" then continue end
		-- rest of for loop here, using 'model' instead of 'character'
	end

2 comments

0

although it does work, now the npc seems to detect me from any range

0

Set closestDist to the maximum range you want (ex local closestDist = 50 on line 3) and then remove not closestDist or on line 11 so that it just says if dist < closestDist then

try:

--[[
	function findNearestPlayer(pos)
	grab things at this position code using region3 and insert them into List code
]]
   local Torso = nil
   local Temp2 = nil
    for x = 1, #List do
        Temp2 = List[x]
        if (Temp2.className == "Model") and (Temp2 ~= script.Parent) then
            Temp = Temp2:findFirstChild("HumanoidRootPart")
            Human = Temp2:findFirstChild("Humanoid")
            local plr = Human.Parent.Name -- changed as Human.Name will return "Humanoid"
            if players:FindFirstChild(plr) then
            if (Temp ~= nil) and (Human ~= nil) and (Human.Health > 0) then
                if (Temp.Position - Position).magnitude < Distance then
                    Torso = Temp
                    Distance = (Temp.Position - Position).magnitude
                        end
                    end
                end
            end
			-- return Torso wrong place this will return anything, might be what's causing your npc's to attack each other
        end
	return Torso -- move it to here...
end




while true do

	-- we need to change this to account for a nil returning from our findNearestPlayer function
    local target = findNearestPlayer(script.Parent.HumanoidRootPart.Position)
	if(target ~= nil) then -- Done!
	
        if not target.Name == ("Goblin") then --how i try to make them not attack eachother
			if target ~= nil then
				script.Parent.Humanoid:MoveTo(target.Position, target)
			end
		end
	end
end

Hope this helps! :)

3 comments

0

it tells me that there is an extra end statment, but they i remove it and it says everything is wrong :(

0

To fix the syntax error: Delete lines 1 and 4 and add two dashes on what becomes the 2nd line (the one that starts with "grab things at", so that it reads "--grab things at")

0

However, this script's logic isn't quite right because if a Goblin is nearby, target.Name will be "Goblin" so that NPC will do nothing. That name check needs to occur in the findNearestPlayer function - better yet, only search through player characters.

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