Monster Random Help

Hello, I’m making a monster in a maze, but there’s glitches where the monster will not move when not in range. It’s supposed to be moving randomly when no one is in range, but instead it moves to the point and just stops until a player goes close. Which is even more weird it sometimes works then breaks :confused: . Please help.
Script:

local Players = game:GetService("Players")

local ServerStorage = game:GetService("ServerStorage")
local SimplePath = require(ServerStorage.Server_Modules.SimplePath)
local Zone = require(ServerStorage.Server_Modules.Zone)

local container = workspace.Map.Barriers.Barrier
local zone = Zone.new(container)

local Events = game:GetService("ReplicatedStorage"):WaitForChild("Events")
local DiedEvent = Events:WaitForChild("DiedEvent")

local PointsFolder = workspace.Map.Points

local npc = script.Parent
local rootPart = npc:WaitForChild("HumanoidRootPart")
local humanoid = npc:WaitForChild("Humanoid")
local head = npc:WaitForChild("Head")
local HitBox = npc:WaitForChild("Hitbox")

local players = {}
local targetRoot = nil
local reachable = false
local maxDistance = 25
local debounce = {}
local Goal = Vector3.new()

local randomPoints = {}
local lastPoint = Vector3.new(-83, 1.5, 91)
local movePoint = false

for _, point in pairs(PointsFolder:GetChildren()) do
	table.insert(randomPoints, point.Position)
end

local agentParams = ({
	AgentRadius = 3, --(The Radius Of The Object(Half Its width))
	AgentHeight = 6.5, --(The Height Of The Object)
})

local Path = SimplePath.new(npc, agentParams)

zone.playerEntered:Connect(function(player)
	for i = 1, #players do
		if players[i] == player then
			table.remove(players, i)
		end
	end
end)

zone.playerExited:Connect(function(player)
	if player.TeamColor == BrickColor.new("Deep orange") then return end
	table.insert(players, player)
end)

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoid = character:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			for i = 1, #players do
				if players[i] == player then
					table.remove(players, i)
				end
			end
		end)
	end)
end)

local function onHit(hit)
	if hit:FindFirstAncestorWhichIsA("Model"):FindFirstChild("Humanoid") then
		local character = hit:FindFirstAncestorWhichIsA("Model")

		if game:GetService("Players"):GetPlayerFromCharacter(character) and not debounce[character]  then

			debounce[character] = true

			local player = Players:GetPlayerFromCharacter(character)

			local humanoid = hit:FindFirstAncestorWhichIsA("Model"):FindFirstChild("Humanoid")
			humanoid.Health = 0

			DiedEvent:FireClient(player)
			
			targetRoot = nil
			
			task.wait(2)

			debounce[character] = nil
		end
	end
end

local function getClosestPlayer()
	for _, player in pairs(players) do
		local character = player.Character or player.CharacterAdded:Wait()
		local targetRoot = character:WaitForChild("HumanoidRootPart")
		local distance = (rootPart.Position - targetRoot.Position).Magnitude
		
		if distance <= maxDistance then
			return targetRoot
		else
			return nil
		end
	end
end

task.spawn(function()	
	while npc do
		targetRoot = getClosestPlayer()
		
		if targetRoot and Path:Run(targetRoot.Position) then
			Goal = targetRoot.Position
			Path:Run(Goal)
		else
-- Probably where error is
			local reached = false
			Goal = randomPoints[math.random(1, #randomPoints)]

			if Goal == lastPoint then
				repeat task.wait()
					Goal = randomPoints[math.random(1, #randomPoints)]
				until Goal ~= lastPoint
			end
			
			Path:Run(Goal)	
			
			Path.Reached:Connect(function()
				reached = true
			end)
			
			
			repeat task.wait()
				targetRoot = getClosestPlayer() 
				print(reached, targetRoot, Path.LastError)
			until reached or targetRoot or Path.StatusType == SimplePath.StatusType.Idle or Path.LastError ~= nil
			return
		end
	end
end)

HitBox.Touched:Connect(onHit)

Thank you.

1 Like

What does it print?

1 Like

Most of the time:

false, nil, nil

When it errors:

true, nil, nil

The repeat should end, but it doesn’t.

1 Like

So it keeps printing it?

1 Like

Yes, it does. I don’t know why, but it does.

1 Like

Try covering

until reached or targetRoot or Path.StatusType == SimplePath.StatusType.Idle or Path.LastError ~= nil

in parentheses

until (reached or targetRoot or Path.StatusType == SimplePath.StatusType.Idle or Path.LastError ~= nil)
2 Likes

Now it stops the loop, but I think the loop breaks because it prints “true, nil, nil” then stops. No prints nothing.

1 Like

Bump because I still need help.

Have you tried printing different messages in different parts of code? This should help us debug better.

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