Check if a spotlight is shining on someone

I wanted to shine a spotlight over a dark area, and when the light shines over someone, they get “caught”, and thrown in prison.

I was thinking maybe I could use a cone and .Touched, but I was wondering if there was an alternative?

You can try to raycast from the character in the LookVector’s direction.

check the look vector thing

local Character -- the character
local Spotlight: Model -- a model i think

local function IsTouching()
	local Blacklist = {Cone}
	local RootPart = Character:FindFirstChild("HumanoidRootPart")

	for i, Item in pairs(Character:GetDescendants()) do
		if Item:IsA("BasePart") and Item ~= RootPart then
			table.insert(Blacklist, Item)
		end
	end

	local RaycastParam = RaycastParams.new()
	RaycastParam.FilterType = Enum.RaycastFilterType.Blacklist
	RaycastParam.FilterDescendantsInstances = Blacklist

	local Raycast = workspace:Raycast(
		RootPart.Position, 
		Spotlight:GetPivot().LookVector * 1000,
		RaycastParam
	)

	if Raycast and Raycast.Instance == RootPart then
		return true
	end
	
	return false
end

I mean, that only checks whether a ray can shoot from the rootpart to the spotlight part, right? it doesn’t actually check whether you’re in the light, correct?

– Check if the player is in the cone
while wait(0.5) do
if IsTouching() then
– do something
end
end

You could use Workspace.Raycast to cast a ray from the cone’s tip to the character’s root part.
local Character = game.Players.LocalPlayer.Character
local RootPart = Character.PrimaryPart – The character’s root part
local Cone = workspace.Cone

– Cast a ray from the cone’s tip to the character’s root part
local Raycast = workspace:Raycast(
Cone.Tip.Position,
RootPart.Position - Cone.Tip.Position,
Cone.Tip
)

– If the raycast hits the character’s root part, the character is in the cone
if Raycast and Raycast.Instance == RootPart then
print(“Character in cone”)
end

Note that if you want to cast a ray through a part, that part has to be passed to Raycast as the third argument.

Thanks, but I got by using Dot Product instead

1 Like

Try using this:

-- Assuming this script is within the "Spotlight" instance

local spotlight = script.Parent -- Reference to the spotlight
local coneAngle = math.rad(spotlight.Angle / 2) -- Convert half of the angle to radians for comparison
local range = spotlight.Range -- Get the range of the spotlight

-- Function to check if the spotlight is shining on a target
local function isSpotlightShining(target)
	local spotlightCFrame = spotlight.Parent.CFrame -- Assuming the spotlight is facing a particular direction based on its parent's CFrame
	local spotlightDirection = nil

	-- Determine the direction based on the Face property of the spotlight
	if spotlight.Face == Enum.NormalId.Left then
		spotlightDirection = -spotlightCFrame.RightVector
	elseif spotlight.Face == Enum.NormalId.Right then
		spotlightDirection = spotlightCFrame.RightVector
	elseif spotlight.Face == Enum.NormalId.Top then
		spotlightDirection = spotlightCFrame.UpVector
	elseif spotlight.Face == Enum.NormalId.Bottom then
		spotlightDirection = -spotlightCFrame.UpVector
	elseif spotlight.Face == Enum.NormalId.Front then
		spotlightDirection = spotlightCFrame.LookVector
	elseif spotlight.Face == Enum.NormalId.Back then
		spotlightDirection = -spotlightCFrame.LookVector
	end

	local targetDirection = (target.Position - spotlightCFrame.Position).unit

	local dotProduct = spotlightDirection:Dot(targetDirection)
	local angleBetween = math.acos(dotProduct)

	-- Check if the angle between the spotlight's direction and target is within the cone angle
	if angleBetween <= coneAngle then
		-- Check if the target is within the range of the spotlight
		if (target.Position - spotlightCFrame.Position).Magnitude <= range then
			return true -- The spotlight is shining on the target
		end
	end

	return false -- The spotlight is not shining on the target
end

-- Example usage: Check if a player is within the spotlight's cone
local function checkPlayer(player)
	local character = player.Character
	if character then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			if isSpotlightShining(humanoidRootPart) then
				print(player.Name .. " is within the spotlight!")
				-- You can apply damage or perform any action here
			else
				print(player.Name .. " is not in the spotlight.")
			end
		end
	end
end

-- Example: Check all players in the game
while true do
	wait(0.1)
	for _, player in pairs(game.Players:GetPlayers()) do
		checkPlayer(player)
	end
end