Ai raycast question

i want to make an ai when you are being chased and go inside the save zone it will instantly leave and find the nearest player similar to this game

Cheese Escape [Horror] - Roblox

idk if it computes a bunch of paths and just goes there but please help me i think this takes raycast and pathfinding

(Also if this is the wrong area to post please tell me the right place to post at)

1 Like

robloxapp-20250109-0248328.wmv (5.3 MB)

This is a video of a reference i have

Not entirely sure what you’re asking, so here’s two answers.

The simplest way to go about the effect shown in the video is to use something like workspace:GetPartBoundsInRadius() (here), then use a Raycast from the enemy in the direction of the found character. If any parts are in the way that aren’t the humanoid, it won’t trigger.

Although, from your question itself, it sounds like you just want a safe area, which is different from wall detection. If that’s the case, you can run checks on the player’s character and add them a tag whenever they enter the safe zone, then take that tag whenever they exit. The tag would be checked for by the enemy before moving.

Then, either way you go about this, again, the simplest (but not the most effective way) is to use Humanoid:MoveTo(), but a much better way is via PathfindingService.
(Read the docs before asking further questions, unless there’s something else related that you have to ask.)

Hopefully this helps you.

how could i use the raycast from the enemy in the direction

Raycasts are mostly math. Specifically, rather than having two different points to raycast between, you’ll instead have to calculate the offset from the NPC, to the found target.

That’s pretty simple, though—subtracting the Position of the enemy HumanoidRootPart from the found target’s HumanoidRootPart should give you an “object-space” Vector3; i.e., an offset that can be used as the 2nd parameter to Raycast.

Do you know why this is not working the npc is not moving

-- Services
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")

-- Configuration
local SAFE_ZONE_TAG = "InSafeZone"
local ENEMY = workspace.Noob
local DETECTION_RADIUS = 50

-- Functions
local function isPlayerVisible(enemy, target)
	local direction = (target.Position - enemy.HumanoidRootPart.Position).Unit
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {enemy}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local raycastResult = workspace:Raycast(enemy.HumanoidRootPart.Position, direction * DETECTION_RADIUS, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart and hitPart:IsDescendantOf(target.Parent) then
			return true
		end
	end

	return false
end

local function onEnterSafeZone(player)
	if not player.Character then return end
	player.Character:SetAttribute(SAFE_ZONE_TAG, true)
end

local function onExitSafeZone(player)
	if not player.Character then return end
	player.Character:SetAttribute(SAFE_ZONE_TAG, nil)
end

local function moveToTarget(enemy, target)
	local path = PathfindingService:CreatePath({
		AgentRadius = 2,
		AgentHeight = 5,
		AgentCanJump = true,
		AgentJumpHeight = 7,
		AgentMaxSlope = 45
	})

	path:ComputeAsync(enemy.HumanoidRootPart.Position, target.Position)

	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()
		for _, waypoint in ipairs(waypoints) do
			enemy:MoveTo(waypoint.Position)
			enemy.Humanoid.MoveToFinished:Wait()
		end
	end
end

local function detectAndChase(enemy)
	while task.wait(1) do
		local partsInRadius = workspace:GetPartBoundsInRadius(enemy.HumanoidRootPart.Position, DETECTION_RADIUS)

		for _, part in ipairs(partsInRadius) do
			local player = Players:GetPlayerFromCharacter(part.Parent)
			if player and not player.Character:GetAttribute(SAFE_ZONE_TAG) then
				if isPlayerVisible(enemy, part) then
					moveToTarget(enemy, part)
				end
			end
		end
	end
end

local safeZone = workspace.Safezone
safeZone.Touched:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		onEnterSafeZone(player)
	end
end)

safeZone.TouchEnded:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		onExitSafeZone(player)
	end
end)

task.spawn(function()
	detectAndChase(ENEMY)
end)