AI Pathfinding Problem

  1. What do you want to achieve?

I want to fix a bug where the ai stops moving when it kills someone

  1. What is the issue? Include screenshots / videos if possible!

This AI works great except for one problem that breaks my game when it kills a player it will stop moving until the dead player leaves game

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I have tried making it detect if a player is dead or not but it didnt work. Any help is appreciated

This is the script:


local aiDamage = 0		-- How much damage the ai inficts towards the player

local canWander = false

local WanderX, WanderZ = 5, 5

function getHumanoid(model)
	for _, v in pairs(model:GetChildren()) do
		if v:IsA'Humanoid' then
			return v
		end
	end
end

local ai = script.Parent
local human = getHumanoid(ai)
local hroot = ai.HumanoidRootPart
local zspeed = hroot.Velocity.magnitude


local pfs = game:GetService("PathfindingService")

function GetPlayerNames()
	local players = game:GetService('Players'):GetChildren()
	local name = nil
	for _, v in pairs(players) do
		if v:IsA'Player' then
			name = tostring(v.Name)
		end
	end
	return name
end

spawn(function()
	while wait() do

	end
end)

function GetPlayersBodyParts(t)
	local torso = t
	if torso then
		local figure = torso.Parent
		for _, v in pairs(figure:GetChildren()) do
			if v:IsA'Part' then
				return v.Name
			end
		end
	else
		return "HumanoidRootPart"
	end
end

function GetTorso(part)
	local chars = game.Workspace:GetChildren()
	local torso = nil
	for _, v in pairs(chars) do
		if v:IsA'Model' and v ~= script.Parent and v.Name == GetPlayerNames() then
			local charRoot = v:FindFirstChild'HumanoidRootPart'
			if (charRoot.Position - part).magnitude < SearchDistance then
				torso = charRoot
			end
		end
	end
	return torso
end

for _, zambieparts in pairs(ai:GetChildren()) do
	if zambieparts:IsA'Part' then
		zambieparts.Touched:connect(function(p)
			if p.Parent.Name == GetPlayerNames() and p.Parent.Name ~= ai.Name then -- damage
				local enemy = p.Parent
				local enemyhuman = getHumanoid(enemy)
				enemyhuman:TakeDamage(aiDamage)
			end
		end)
	end
end

-- no touchy
local path
local waypoint
local oldpoints
local isWandering = 0

if canWander then
	spawn(function()
		while isWandering == 0 do
			isWandering = 1
			local desgx, desgz = hroot.Position.x + math.random(-WanderX, WanderX), hroot.Position.z + math.random(-WanderZ, WanderZ)
			human:MoveTo( Vector3.new(desgx, 0, desgz) )
			wait(math.random(4, 6))
			isWandering = 0
		end
	end)
end

while wait() do
	local enemytorso = GetTorso(hroot.Position)	
	if enemytorso ~= nil then -- if player detected
		isWandering = 1
		local function checkw(t)
			local ci = 3
			if ci > #t then
				ci = 3
			end
			if t[ci] == nil and ci < #t then
				repeat
					ci = ci + 1
					wait()
				until t[ci] ~= nil
				return Vector3.new(1, 0, 0) + t[ci]
			else
				ci = 3
				return t[ci]
			end
		end

		path = pfs:FindPathAsync(hroot.Position, enemytorso.Position)
		waypoint = path:GetWaypoints()
		oldpoints = waypoint
		local connection;

		local direct = Vector3.FromNormalId(Enum.NormalId.Front)
		local ncf = hroot.CFrame * CFrame.new(direct)
		direct = ncf.p.unit
		local rootr = Ray.new(hroot.Position, direct)
		local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)

		if path and waypoint or checkw(waypoint) then
			if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
				human:MoveTo( checkw(waypoint).Position )
				human.Jump = false
			end

			-- CANNOT LET BALDI JUMPS --
			if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then
				human.Jump = true

				human:MoveTo( checkw(waypoint).Position )
				human.Jump = true
			else
				human.Jump = false
			end

			hroot.Touched:connect(function(p)
				local bodypartnames = GetPlayersBodyParts(enemytorso)
				if p:IsA'Part' and phit and phit.Name ~= bodypartnames and phit:IsA'Part' and rootr:Distance(phit.Position) < 5 then
					connection = human.Changed:connect(function()
						human.Jump = false
					end)
				else
					human.Jump = false
				end
			end)

			if connection then
				connection:Disconnect()
			end

		else
			for i = 3, #oldpoints do
				human:MoveTo( oldpoints[i].Position )	
			end
		end
	elseif enemytorso == nil and canWander then -- if player not detected
		isWandering = 0
		path = nil
		waypoint = nil
		human.MoveToFinished:Wait()

	end
end```

You aren’t updating the target player’s name after it killed the player.

1 Like

Now, the AI should only target and move towards players that are alive. If a player dies, the AI will continue wandering or target another player if one is in range.

function getHumanoid(model)
    for _, v in pairs(model:GetChildren()) do
        if v:IsA'Humanoid' then
            return v
        end
    end
end

-- ...

function GetTorso(part)
    local chars = game.Workspace:GetChildren()
    local torso = nil
    for _, v in pairs(chars) do
        if v:IsA'Model' and v ~= script.Parent and v.Name == GetPlayerNames() then
            local charRoot = v:FindFirstChild'HumanoidRootPart'
            local humanoid = getHumanoid(v)
            if (charRoot.Position - part).magnitude < SearchDistance and humanoid.Health > 0 then
                torso = charRoot
            end
        end
    end
    return torso
end

-- ...

while wait() do
    local enemytorso = GetTorso(hroot.Position)
    if enemytorso ~= nil then -- if player detected
        local enemy = enemytorso.Parent
        local enemyhuman = getHumanoid(enemy)

        if enemyhuman.Health > 0 then -- check if player is not dead
            -- ...
        end
    elseif enemytorso == nil and canWander then -- if player not detected
        -- ...
    end
end

Hello I am kind of new to scripting so i dont understand what goes where in the blanks in the “while wait do loop” can you fill in the gaps please. Thank you

Nevermind I got it to work thanks

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.