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

[SOLVED] How do I make this pathfinding AI, create path more often?

TO MAKE IT MORE SIMPLE HERE IS A MODEL OF THE AI:

https://web.roblox.com/library/8293330612/Test

What could be happening is in the code there is a for i, v in pairs()waypoints do this is causes it to repeat waypoint creation. This means it will not recreate the path therefore going to the players last location or it could be there is a humanoid.MoveToFinished:Wait() at line 32 stopping the script making it un able to repeat the path after removing the humanoid.MoveToFinished:Wait() it will constantly update the path but travel in a straight line towards the player

here is the full script (I didn't make the torso finding bit) I have had a few try's at fixing which I'm doing right now but I struggle to find a fix

local pathService = game:GetService("PathfindingService")
local humanoid = script.Parent.NOOB
humanoid.Parent.PrimaryPart:SetNetworkOwner(nil)

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 800
	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("HumanoidRootPart")
			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
				end
			end
		end
	end
	return torso
end

local function move(v)

		
	humanoid:MoveTo(v.Position)
	humanoid.MoveToFinished:Wait()
	end



	

local path
while true do
	wait(0.1)
local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	if target ~= nil then

		path = pathService:CreatePath()
		
		path:ComputeAsync(script.Parent.HumanoidRootPart.Position, target.Position)

		local waypoints = path:GetWaypoints()
		if path.Status == Enum.PathStatus.Success then
			
			for i,v in pairs(waypoints) do
				
				local part = Instance.new("Part", workspace)
				part.Anchored = true
				part.CanCollide = false
				part.Material = Enum.Material.Neon
				part.Position = v.Position
				part.Size = Vector3.new(0.6,0.6,0.6)
				part.Shape = "Ball"

					if v.Action == Enum.PathWaypointAction.Jump then
					humanoid.Jump = true
					
					end
					
					move(v)
				
			end
		end
	end
end

1 comment

0

one of my ideas of how to fix this was to pick up and repeat getting one waypoint at a time instead of multiple but that could cause the ai to constantly pause and I struggled to work out how to do that

1 answer

✓ Accepted answer

Just re-wrote your AI with something I had in storage.

Code:

local Me = script.Parent

local MyBase = Me:WaitForChild("HumanoidRootPart",10)
local Humanoid = Me:WaitForChild("NOOB",10)
Me.PrimaryPart:SetNetworkOwner(nil)

local Index = 3 -- this is needed to start from 3 otherwise the npc will turn away then back!.
local Points = {}

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 800
	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("HumanoidRootPart")
			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
				end
			end
		end
	end
	return torso
end



local blockedConnection

local function computePathtoV3(Target)
	if(MyBase ~= nil) then
		

		local PFS = game:GetService("PathfindingService")

		local path = PFS:CreatePath(
			{
				AgentRadius = 4, -- This tells how wide or FAT your npc is!
				AgentHeight = 8, -- How high they can jump (i think!)
				AgentCanJump = true, -- and Can they jump?
				Costs = { -- this can be used to define prefered path or not by setting the values from 0
					--// the higher this number the more chance your npc will advoid it!
					
					
					--[[ 
						to use this you need a part in the workspace 
						with a PathfindingModifier with the ModifierId set to this id (KillBrick)
						then this Ai will avioid this part!
						you can change this name just make sure this key matches exactly the one set in the modifireId
						in your PathfindingModifier object! 
					]]
					KillBrick = math.huge
				}
			}
		)

		local success, errorMessage = pcall(function()
			path:ComputeAsync(MyBase.Position, Target)
		end)

		blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
			-- Check if the obstacle is further down the path
			print(blockedWaypointIndex, Index)
			if blockedWaypointIndex >= Index then
				-- Stop detecting path blockage until path is re-computed
				blockedConnection:Disconnect()
				-- Call function to re-compute new path
				computePathtoV3(Target)
			end
		end)
	
		if success and path.Status == Enum.PathStatus.Success then
			return path:GetWaypoints()
		elseif(path.Status == Enum.PathStatus.NoPath) then
			
			computePathtoV3(Target)
		end

	end
	return {}
end
local Goal
local MyPath


local GIndex = 1

local DebugPathBits = {}
local Debug = true
while true do

	Goal = findNearestTorso(MyBase.Position)
	if(Goal ~= nil) then

	MyPath = computePathtoV3(Goal.Position)	
		if(Debug == true) then
			for k,v in pairs(DebugPathBits) do
				v:Destroy()
			end
			table.clear(DebugPathBits)
		for i,v in pairs(MyPath) do

			local part = Instance.new("Part", workspace)
			part.Anchored = true
			part.CanCollide = false
			part.Material = Enum.Material.Neon
			part.Position = v.Position
			part.Size = Vector3.new(0.6,0.6,0.6)
			part.Shape = "Ball"
			DebugPathBits[i] = part
		end
	end


	if(Index <= #MyPath) then
		local Dist = (MyBase.Position - MyPath[Index].Position).magnitude
		--print(Humanoid:GetState())
		if  MyPath[Index].Action == Enum.PathWaypointAction.Jump 
			and Humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then
			
			Humanoid:MoveTo(MyPath[Index].Position)

			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid.MoveToFinished:wait()
	
		end
		Humanoid:MoveTo(MyPath[Index].Position)
			
		if(Dist <= 2) then -- using Distance to make sure our ai gets to this point!
			Index = Index +1
		end

	else
		
		GIndex = GIndex +1 <= #Points and GIndex +1 or 1
		Index = 3
		end
	end
	wait()
end

There's still a chance of the Ai getting stuck while jumping, but it should work.

Also, Happy Holidays! :) and if you need help just let me know :)

2 comments

0

Thank you so much ill try add a unstuck function, but this works so well exactly what I was looking for

0

to stop it getting stuck between jumps switch Humanoid:MoveTo(MyPath[Index].Position) and Humanoid.MoveToFinished:wait()

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