I’m trying to make a system where there is an NPC walking back and forth from point A to point B, and when they see the player they will start chasing them.
My system works, however it is really easy to not get spotted as I am using Raycasting to check if there is a player in front of them, meaning that they will only start chasing the player once the player is directly in front of them, and this is my issue.
As far as I know, there aren’t any other tutorials or posts on this, so I have made one myself as a last resort.
Here is the script that casts the ray:
local filter = {guard} -- the npc that is detecting the player
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = filter
local ray = workspace:Raycast(guard.Head.Position, guard.Head.CFrame.LookVector * 12.5, params)
if ray and ray.Instance and game.Players:GetPlayerFromCharacter(ray.Instance.Parent) then
chasing = true
humanoid:MoveTo(closestPlayer.Character.HumanoidRootPart.Position)
break
else
chasing = false
end
You could either amend your current ray cast script to fire rays in a cone, rather than a single line, which would create the FOV effect you were looking for, or create a hitbox part in the shape of a cone and use that as the form of detection but I would recommend firing ray casts in a cone as it’s more reliable.
This post might have what you need to create ray casts that fire in a cone, if not, there’s many other posts that would have the necessary information.
After some hassle, I managed to get a system in place that I liked without really looking at other tutorials. I knew what I wanted but didn’t know how to get there so I did testing and came with a solution. Here is the script that I ended up creating (inside of a part due to testing)
local function rayFunction(angle, castAmount)
local current = 0-math.abs(angle)
for i=1, castAmount do
local filter = {script.Parent, workspace.test}
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = filter
local rayCFrame = script.Parent.CFrame
local rayAngle = rayCFrame * CFrame.Angles(0, math.rad(current), 0)
local ray = workspace:Raycast(script.Parent.Position, rayAngle.LookVector * 20, params)
if ray and ray.Instance and game.Players:GetPlayerFromCharacter(ray.Instance.Parent) then
ray.Instance.Parent.Humanoid.Health -= 5
print("Damaged Someone")
end
current += math.abs(angle)*2 / castAmount
end
end
while wait(2) do
rayFunction(35, 20)
end
And here is the result:
For the example I just created parts at the end of the ray, and it works great for detecting players within an angle.
I had also tried other solutions in a 3d cone, but ultimately they were very performance costly, and this is runs very smoothly when put in a while wait() do loop.
Thanks for sending me a link to the other page as it helped me research other similar things.