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

How to make NPC wander randomly/follow you and run away if you get too close?

Hello, So basically i'm trying to make a horror game in roblox studio, game like games from Rust_010.

I'm trying to make an NPC spawn, wander arround the map or follow the player, maybe die/respawn and run away when you get too close.

2 comments

0

Not a request site, but you can use WalkToPart inside of the Humanoid

0

you can also use the PathfindingService

2 answers

create a StringValue inside the NPC called "NpcMode"

this script will make it move around if the value is Normal

local CurrentPart = nil
local MaxInc = 16

function onTouched(hit)
	if hit.Parent == nil then
		return
	end

	local humanoid = hit.Parent:findFirstChild("Humanoid")

	if humanoid == nil then
		CurrentPart = hit
	end
end

function waitForChild(parent, childName)
	local child = parent:findFirstChild(childName)

	if child then
		return child
	end

	while true do
		print(childName)

		child = parent.ChildAdded:wait()

		if child.Name==childName then
			return child
		end
	end
end

local Figure = script.Parent
local Humanoid = waitForChild(Figure, "Humanoid")
local Torso = waitForChild(Figure, "Torso")
local Left = waitForChild(Figure, "Left Leg")
local Right = waitForChild(Figure, "Right Leg")

Humanoid.Jump = true

Left.Touched:connect(onTouched)
Right.Touched:connect(onTouched)

while true do
	wait(math.random(2, 6))

	if CurrentPart ~= nil and script.Parent.NpcMode.Value == "Normal" then

		Humanoid:MoveTo(Torso.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)), CurrentPart)
	end
end

and if the value is attacking, this script will make it chase the nearest Player

wait()
zombieParent = false

while zombieParent == false do

	wait()
	if script.Parent.NpcMode.Value == "Attacking" then
		zombieParent = true
	end

end

local larm = script.Parent:FindFirstChild("Left Arm")
local rarm = script.Parent:FindFirstChild("Right Arm")
local waitTimer = 0

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 10000
	local temp = nil
	local human = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.className == "Model") and (temp2 ~= script.Parent) then
			temp = temp2:findFirstChild("Torso")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					dist = (temp.Position - pos).magnitude

					if human.Health >= 1 then 
					script.Parent.Range.Value = true 
					else 
					script.Parent.Range.Value = false 
					end 
				end
			end
			if dist < 10 then 
				script.Parent.Attack.Value = true 
			else 
				script.Parent.Attack.Value = false 
			end 
		end
	end
	return torso
end

function Sit()
	if script.Parent.Humanoid.Sit == true then 
		script.Parent.Humanoid.Jump = true 
		print("Anti Seat Putter!!!")
	end 
end

script.Parent.Humanoid.Changed:connect(Sit)

while true do
	wait(1)
	local target = script.Parent.Target.Value
	if target ~= nil then
		rx = math.random(-3,3)
		ry = math.random(0,0)
		rz = math.random(-3,3)
		script.Parent.Humanoid:MoveTo(target.Position+Vector3.new(rx,ry,rz), target)
	else 
	end
end

oh, and create a StringValue with the "Target" name, the Npc will always chase the Player with his name in the Target value

please, if this help you, make as answer, thanks.

2 comments

0

Yes, thank you

0

please, could you mark my answer as the accepted? thanks

The main actions you want the NPC to perform are based on the distance from the player, so you'll need .magnitude for this.

For my example, I am adding an IntValue named "FarAway" inside the script so that you can get the magnitude set continuously and be able to activate the movement based on it.

local player = game.Players.LocalPlayer
workspace:WaitForChild(player.Name)

local npc = workspace.NPC
local humanoid = workspace.NPC.Humanoid
local debounce = true

script.FarAway.Changed:Connect(function()
if debounce == false then return end

local distance = script.FarAway.Value
	if distance > 10 and distance <= 25 then
		local randomx = math.random(-25, 25)
		local y = npc.HumanoidRootPart.Position.Y
		local randomz = math.random(-25, 25)
		npc:MoveTo(player.Character.HumanoidRootPart.Position + Vector3.new(randomx, y, randomz))
		humanoid.MoveToFinished:Wait()
	elseif distance > 25 and distance < 50 then
		debounce = false
		npc:MoveTo(player.Character.HumanoidRootPart.Position + Vector3.new(0, 0, 10))
		humanoid.MoveToFinished:Wait()
		debounce = true
	elseif distance >= 50 then
		debounce = false
		local randomx = math.random(-100, 100)
		local y = npc.HumanoidRootPart.Position.Y
		local randomz = math.random(-100, 100)
		npc:MoveTo(npc.HumanoidRootPart.Position + Vector3.new(randomx, y, randomz))
		humanoid.MoveToFinished:Wait()
		debounce = true
	end
end)
	
while true do
	script.FarAway.Value = (player.Character.HumanoidRootPart.Position - npc.HumanoidRootPart.Position).magnitude
end

I also added a debounce for the movements that are not too close to the player so that they can finish firing. If the player is too close, there is no debounce so that the random path the NPC takes is not continuously towards the player.

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