Patrooling, and chasing horror game character

So i am making a Horror game, and i want to add an NPC which patrools through a maze, but if detecting a Player in reach i want the npc to chase the Player. I have the simple chase script, but there is the Problem, if player out of reach the npc Stands still, i dont want that to happen. Can anyone help me out? Here is the Chasing code of the NPC :

local Monster = script.Parent


function FindPlayer(Position)
   local List = game.Workspace:GetChildren()
   local Torso = nil
   local Distance = 50
   local HumanoidRootPart = nil
   local Humanoid = nil
   local Player = nil

   for i = 1,#List do
   	Player = List[i]
   	if (Player.ClassName == "Model") and (Player ~= script.Parent) then
   		HumanoidRootPart = Player:FindFirstChild("HumanoidRootPart")
   		Humanoid = Player:FindFirstChild("Humanoid")
   		if (HumanoidRootPart ~= nil) and (Humanoid ~= nil) and (Humanoid.Health > 0) then
   			if (HumanoidRootPart.Position - Position).Magnitude < Distance then
   				Torso = HumanoidRootPart
   				Distance = (HumanoidRootPart.Position - Position).Magnitude
   			end
   		end
   	end
   end
   return Torso
end

while true do
   wait(1)
   local Target = FindPlayer(script.Parent.HumanoidRootPart.Position)
if Target ~= nil then
   	script.Parent.Humanoid:MoveTo(Target.Position, Target)
   end
end

You can make the NPC travel to points in the maze for some patrolling.
https://developer.roblox.com/en-us/articles/Moving-NPCs-Between-Points

but would the chase script work then?

I am pretty sure that it would be able to work. You should put the script outside the function when the NPC is chasing the player.

okay, i will try to add it :D, if im done and it works or not, i will tell

1 Like

Try using Raycasting in all directions to maybe 10 in the direction it’s going to. If it finds a player, you can use the chase to begin following them, if they get out of reach, then go to patrolling using @Based_Bern 's idea;

Also, try using Pathfinding to make the chaser follow the player!

1 Like

thank you for the post, the only problem on my side is, i dont even know what raycasting is (yes im a bad scripter), im still going to try implementing everything

Raycasting is where you’d create, basically a line of information, if it hits anything, it can; if you put it in a function, return that instance or it could delete it, clone it, or move it.

As an example; in a game I made, I used raycasting to find the point above the camera, and it would set it’s Y position to that. This is the function that I created for it;

local function rayAbove()
	local Origin : Vector3 = head.Position
	local direction : Vector3 = Vector3.new(0, 100, 0)
	
	local info = RaycastParams.new()
	
	info.FilterDescendantsInstances = {CameraPart, char}
	info.FilterType = Enum.RaycastFilterType.Blacklist
	
	local ray = workspace:Raycast(Origin, direction, info)
	
	if ray then
		local instance = ray.Instance
		if instance then
			--print(instance.Name)
			return instance.Position.Y - CameraPart.Size.Y / 4
		else
			return 35
		end
	end
end

This just returns the point it finds. This was it’s end result when finding the point;

As you can see, it is glitchy due to the house model having supports, and the ray detecting it, but it does work and it finds the point because it can find a part above it!

1 Like

so the normal moving npc is working ( have not tested with chase script)
but im quite struggeling with pathfinding

In the Developer Hub, it does over do things, what you want to do is something like this;

local hasWait = 0 -- If this is 0, then it won't wait, if it is higher, it will wait that ammount.

local function followPath(Character : Model, destination : Vector3)
	local Path = PathfindingService:CreatePath()
	Path:ComputeAsync(Character.PrimaryPart.Position, destination)
	local Waypoints = Path:GetWaypoints()
	
	for _, Point in pairs(Waypoints) do
		if Point.Action == Enum.PathWaypointAction.Jump then
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end
		Humanoid:MoveTo(Point.Position)
		Humanoid.MoveToFinished:Wait(hasWait) -- Because the nil value is 0, it won't wait anything because 0 is worth nothing. That is why we can use this instead of an if statement.
	end
end

so, i have not updated my status on that type of pathfinding, but i finally got it, but there is my next enemy: the chasing the player, and if there is no player, continue patrooling
like in the mimic the maze, part 1

Find the closest player in a certain radius, if nothing, go to a random waypoint which you can set in workspace.

2 Likes