Blind AI completly messed up

So, I’ve been trying to make a script for a blind AI, that would be able to hear any sounds in a certain radius, hear the player if he moves at a certain speed and “hear” chat too (because it’s technically talking, so, yeah). The thing is, the script is a huge mess, if a player goes slower the entity doesn’t detect it ever again and if the player doesn’t go in a straight line, he’ll be followed anyways (also, I geniunely don’t know how to use the chat service)
Any help is appreciated. Thanks in advance.

The script in question
wait(10)
print("script has started")

local ClosestDistance = math.huge
local closestSound = nil

local hum = script.Parent
local HumRootPart = hum.Parent.PrimaryPart
local RServ = game:GetService("RunService")
local plrs = game:GetService("Players")
local TargetDist = 100
local StopDist = 2
local PathFindingService = game:GetService("PathfindingService")

local path = PathFindingService:CreatePath()
local character = hum.Parent
local Chat = game:GetService("Chat")






function FindNearestPlayer()
	local plrList = plrs:GetPlayers()
	local nearestPlr = nil
	local dist = nil
	local direction = nil
	for _, player in pairs(plrList) do
		if player then
			local char = player.Character
			if char then
				local distVector = (player.Character.HumanoidRootPart.Position - HumRootPart.Position)

				if not nearestPlr then
					nearestPlr = player
					dist = distVector.Magnitude
					direction = distVector.Unit
				elseif distVector.Magnitude < dist then
					nearestPlr = player
					direction = distVector.Unit
					dist = distVector.Magnitude
				end
			else
				print([["The character is not there yet!"]])
			end
		end

	end
	return nearestPlr, dist, direction
end



function onLosePlayer()
	while wait() do
		for i,v in pairs(workspace:GetDescendants()) do
			if v:IsA("Sound") then
				if v.IsPlaying == true then
					if v.Parent:IsA("Part") then
						local distance = (v.Parent.Position - nomster.Parent.HumanoidRootPart.Position).Magnitude
						if distance < ClosestDistance then
							closestSound = v
							ClosestDistance = distance
						end
					elseif v.Parent:FindFirstChildOfClass("Part") then
						local distance = (v.Parent:FindFirstChildOfClass("Part").Position - nomster.Parent.HumanoidRootPart.Position).Magnitude
						if distance < ClosestDistance then
							closestSound = v
							ClosestDistance = distance
						end
					
					end
				else
					Chat.Chatted:Connect(function()
						
					end)
				end
			end
		end
		if closestSound then
			if closestSound.Parent:IsA"BasePart" then
				nomster:MoveTo(closestSound.Parent.Position)
				wait(5)
			elseif closestSound.Parent:FindFirstChildOfClass"BasePart" then
				nomster:MoveTo(closestSound.Parent:FindFirstChildOfClass"BasePart".Position)
				wait(5)
			
			end
		end
		
	end


end
	


while true do
	local nearestPlr, distance, direction = FindNearestPlayer()
	if nearestPlr then
		local WalkSpeedOfPlayer = nearestPlr.Character.Humanoid.WalkSpeed
		if distance <= TargetDist and distance >= StopDist and nearestPlr.Character:WaitForChild("Humanoid") then
			if WalkSpeedOfPlayer >= 6 then
				print("Player's walkspeed is possible to track, as it is currently "..WalkSpeedOfPlayer)
				nearestPlr.Character:WaitForChild("Humanoid").Running:Connect(function(speed)
					if speed > 0 then
						hum:MoveTo(nearestPlr.Character.PrimaryPart.Position)
						wait(5)
					else
						onLosePlayer()

					end
				end)
			else
				print("Player's walkspeed is "..WalkSpeedOfPlayer)
				onLosePlayer()
			end
				
		else
			onLosePlayer()

		end
	end
	wait()
end
1 Like

Also, yes, I am aware this is a pretty long script and that is one of the reasons why I’m struggling so badly with it…

You are creating a conneciton in a infinite loop, this is very dangerous as connections will stack and cause memory leaks.

I would recommend removing the while loop and checking player distance as part of the Running Connection.

The onLosePlayer function starts another infinite loop, this should be moved into it’s own while loops, but instead of always looping it will wait for the creature to stop moving.

---- nearest player and run speed replacement ----
local function listen_to_player(player: Player)
	player.CharacterAppearanceLoaded:Connect(function(character)
		local player_position = character:GetPivot().Position
		local humanoid = character:WaitForChild("Humanoid") :: Humanoid

		-- character and humanoid is loaded into the game, start checking distance when they run
		humanoid.Running:Connect(function(speed)
			if speed > 6 then
				local distance = (HumRootPart.Position - player_position).Magnitude
				if distance <= TargetDist and distance >= StopDist then
					hum:MoveTo(player_position)
					--wait(5) this wait does nothing since connections still recieve new events
				end
			end
		end)
	end)
end

-- connect function to all online players
for _, player in plrs:GetPlayers() do
	listen_to_player(player)
end
-- connect function to future players
plrs.PlayerAdded:Connect(listen_to_player)

---- onLosePlayer replacement ----
-- instead only check for new sounds when done moving. Lower lag, easier to tell when listening for sounds.
-- also won't run when chasing the players
while hum.MoveToFinished:Wait() do
	task.wait(1) -- extra 1 second of standing still
	local closestSound: Sound = nil
	
	for i,v in pairs(workspace:GetDescendants()) do
		if v:IsA("Sound")and v.IsPlaying then
			if v.Parent:IsA("Part") then
				local distance = (v.Parent.Position - nomster.Parent.HumanoidRootPart.Position).Magnitude
				if distance < ClosestDistance then
					closestSound = v
					ClosestDistance = distance
				end
			elseif v.Parent:FindFirstChildOfClass("Part") then
				local distance = (v.Parent:FindFirstChildOfClass("Part").Position - nomster.Parent.HumanoidRootPart.Position).Magnitude
				if distance < ClosestDistance then
					closestSound = v
					ClosestDistance = distance
				end

			end
		end
	end
	if closestSound then
		if closestSound.Parent:IsA("BasePart") then
			nomster:MoveTo(closestSound.Parent.Position)
			-- wait(5) instead of waiting here, we are using MoveToFinished:Wait()
		elseif closestSound.Parent:FindFirstChildOfClass("BasePart") then
			nomster:MoveTo(closestSound.Parent:FindFirstChildOfClass("BasePart").Position)
		end
	end
end
1 Like

The entity isn’t moving with the script, the thing is, I added print functions to see what’s wrong and nothing was wrong, no errors aswell, and it wasn’t facing the same way as he is when he normally spawns.

The only think that works is the system that makes him go towards the sounds

Edit: Sorry for replying this late

I finally figured what’s the matter with the blind AI…
For some reason, instead of sending the entity to the player, it sends it to those coordinates:

Other than than, the script works just fine.

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