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

How do I make a smart NPC AI Navigate to find a player?

I'm making a game where you walk around a forest and hunt bears. As it is a forest, there are trees that get in the way. The problem with NPC's is that they walk into the wall and do not notice barriers. I really need help on this. Are there any people out there who know how to use AI on Roblox it would help me so much!

I understand that this is a lot. But thanks!

2 comments

2

This is not a request site. Read here to learn how to do this independently, and come back here when you need help with your code. http://wiki.roblox.com/index.php?title=Pathfinding

1

Thanks!

1 answer

✓ Accepted answer

roblox has a pathfinding service such that u dont need to waste ur time learning one(not that i discourage). Place this in a script in the Bear:

local root = script.Parent.HumanoidRootPart
local hum = script.Parent.Humanoid

function findTarget() -- this is the function that would locate the nearest human; we will constantly be spamming this.
	local dist = 200
	local target = nil
	for i, v in pairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local head = v:FindFirstChild("Head")
		
		if human and head and v.Name ~= "Bear" then -- u could remove this if u want ur bear to attack other bears
			local mag = (head.Position - root.position).Magnitude
			
			if mag < dist and human.Health > 0 then
				dist = mag
				target = head
			end
		end
	end
	
	return target
end

while wait(.1) do
	local head = findTarget()
	
	if head then
		local ray = Ray.new(root.Position, (head.Position - root.Position).Unit * 200)
		
		local hit, pos = workspace:FindPartOnRay(ray, script.Parent, true, false) -- ignore list
		if hit:IsDescendantOf(head.Parent) then
			hum:MoveTo(head.Position)
			
		else
			hum:MoveTo(head.Position) -- less choppy movement; a lot of the following is also for such
			wait(.05)
			path = game:GetService("PathfindingService"):FindPathAsync(root.Position, head.Position) -- get the Pathfinding service
			points = path:GetWaypoints()
			
			if path.Status == Enum.PathStatus.Success then
				for i, v in pairs(points) do
					hum:MoveTo(v.Position)
					hum.MoveToFinished:Wait(2) -- 2 as a safety precaution
					if v.Action == Enum.PathWaypointAction.Jump then -- if the bear is required to jump then we make the bear jump
						hum.Jump = true
					end
					if (points[#points].Position - head.Position).Magnitude > 15 then
						break
					end
				end
			else
				hum:MoveTo(head.Position)
			end
		end
	end
end

3 comments

0

You shouldn't be using wait() as your loop's condition, and you don't need to recalculate every .1 seconds, a second or two should suffice. And MoveToFinished:Wait(2) won't wait 2 seconds. It will yield until the event has fired.

0

exactly

0

also when i tried using 1 it was very choppy

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