Why my script not working?

this is a flashlight script for a horror game, the sound and pointlight are children of the local script, the client-sided script is located in Startercharacterscripts
script:

local uis = game:GetService("UserInputService")
local sfx = script.Sound
local light = script.Light
local plr = game:GetService("Players").PlayerAdded:Wait()
local char = plr.Character
local torso = char:WaitForChild("Torso")

uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	if inp.KeyCode == Enum.KeyCode.F then
		sfx:Play()
		light.Parent =torso
		light.Enabled = not light.Enabled
	end
end)
2 Likes

What is not working any errors?

Did you make sure the light is parented and enabled in the explorer tab to the character?

local plr = game:GetService("Players").PlayerAdded:Wait()

This line will wait for a new player to join and assign that as plr. I think the player you are looking for in this case is Players.LocalPlayer.

However, you don’t seem to use plr for anything other than getting the character so you don’t need it. Since scripts in StarterCharacterScripts get cloned and the clone is parented to the character, you can get the character in the following way

local char = script.Parent

Here’s the whole edited code (only changes are removing one line and changing another line).

local uis = game:GetService("UserInputService")
local sfx = script.Sound
local light = script.Light
local char = script.Parent
local torso = char:WaitForChild("Torso")

uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	if inp.KeyCode == Enum.KeyCode.F then
		sfx:Play()
		light.Parent =torso
		light.Enabled = not light.Enabled
	end
end)
2 Likes

is it possible to make the light follow where the player looks please

1 Like

If you only want light on the front side of torso, you can use a SurfaceLight or a SpotLight. They both have a face property. Set it to Enum.NormalId.Front. They also have an angle property to define how wide the light cone will be.

no i mean like if the player looks up the light follows where the player looks

Then you shouldn’t parent the light to the torso. Lights can be parented to attachments too.

Is it okay for your use case if the light originates from the camera position? If it’s okay then you can create an attachment, parent it to workspace.Terrain and parent the light to the attachment. Then, every frame, update Attachment.CFrame to be equal to the camera CFrame.

attachment.CFrame = workspace.CurrentCamera.CFrame

Otherwise, parent the Attachment to whichever part the light should originate from. Then you could get the world position of the mouse and calculate the attachments CFrame every frame in the following way:

attachment.CFrame = attachment.Parent.CFrame:ToObjectSpace(CFrame.lookAt(attachment.WorldPosition, mouseWorldPosition))

Here’s a simple way to get the mouse world position.

local mouse = Players.LocalPlayer:GetMouse()
local mouseWorldPosition = mouse.Hit

However, I think the recommended way to get mouse position these days is by using UserInputService:GetMouseLocation and Camera:ViewportPointToRay.

1 Like

If the light is a PointLight, you should first change it to a SpotLight.

local uis = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local sfx = script.Sound
local light = script.Light
local char = script.Parent
local torso = char:WaitForChild("Torso")
local runServiceConnection

local attachment = Instance.new("Attachment")

light.Face = Enum.NormalId.Front
light.Parent = attachment

attachment.Parent = workspace.Terrain

local function updateAttachmentCFrame()
	attachment.CFrame = workspace.CurrentCamera.CFrame
end

if light.Enabled then
	runServiceConnection = RunService.PreRender:Connect(updateAttachmentCFrame)
end

uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	if inp.KeyCode == Enum.KeyCode.F then
		sfx:Play()
		light.Enabled = not light.Enabled
		if light.Enabled then
			runServiceConnection = RunService.PreRender:Connect(updateAttachmentCFrame)
		else
			runServiceConnection:Disconnect()
		end
	end
end)

doesn’t work
line 21: attempt to index nil with “Enabled”

I had written the variable name wrong. Does it work now?

now there is no errors but doesn’t work, im sorry if im bothering you btw

uhhhhhh
image

why do you have 2 if statements that are responsible for the same thing?

1 Like

Perhaps moving a PointLight is actually a better option than using a SpotLight. Change the light back to a PointLight and try this code. It worked in my testing

local uis = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

-- You can change these but Roblox has some limitations (such as Light.Range being limited to 60).
local MAX_LIGHT_DIST: number = 100
local MIN_DIAMETER: number = 20
local CONE_ANGLE_IN_DEGREES: number = 45

local sfx = script.Sound
local light = script.Light
local char = script.Parent
local torso = char:WaitForChild("Torso")
local runServiceConnection

local attachment = Instance.new("Attachment")
light.Parent = attachment
attachment.Parent = workspace.Terrain

local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {char}

local function updateAttachmentCFrame()
	local cameraCf = workspace.CurrentCamera.CFrame
	local lightOrigin = cameraCf.Position
	local raycastVector: Vector3 = MAX_LIGHT_DIST * cameraCf.LookVector
	local raycastResult = workspace:Raycast(lightOrigin, raycastVector, raycastParams)
	local lightPos: Vector3, distFromLightOrigin: Vector3
	if raycastResult ~= nil then
		lightPos, distFromLightOrigin = raycastResult.Position, raycastResult.Distance
	else
		lightPos, distFromLightOrigin = lightOrigin + raycastVector, raycastVector.Magnitude
	end
	attachment.Position = lightPos
	light.Range = math.max(distFromLightOrigin * math.tan(.5 * math.rad(CONE_ANGLE_IN_DEGREES)), .5 * MIN_DIAMETER)
end

if light.Enabled then
	runServiceConnection = RunService.PreRender:Connect(updateAttachmentCFrame)
end

uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	if inp.KeyCode == Enum.KeyCode.F then
		sfx:Play()
		light.Enabled = not light.Enabled
		if light.Enabled then
			runServiceConnection = RunService.PreRender:Connect(updateAttachmentCFrame)
		else
			runServiceConnection:Disconnect()
		end
	end
end)

@notsad2, I added the first if statement just in case the light is initially enabled before the user presses the key for the first time.

2 Likes