First person light cuts off

The script I have cuts off when I look a little bit downwards but not upwards. The first person can see the full body except the head. The flashlight is suppose to be looked at anywhere my mouse is pointing to in first person. I will be glad if you can help me with this issue. Here is the script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()

local LightEnabled = false
local LightContainer = nil -- The Part that will hold the SpotLight

function UpdateLightOrientation()
	if LightEnabled and LightContainer and LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Head") then
		local Head = LocalPlayer.Character.Head
		local Camera = Workspace.CurrentCamera
		local Ray = Camera:ViewportPointToRay(Mouse.X, Mouse.Y)
		local RaycastResult = Workspace:Raycast(Ray.Origin, Ray.Direction * 100)

		local TargetPosition
		if RaycastResult then
			TargetPosition = RaycastResult.Position
		else
			TargetPosition = Ray.Origin + Ray.Direction * 100
		end

		local HeadLookVector = Head.CFrame.LookVector
		LightContainer.Position = Head.Position + HeadLookVector * 2

		LightContainer.CFrame = CFrame.lookAt(LightContainer.Position, TargetPosition)
	end
end

function ToggleLight()
	if LightContainer then
		LightContainer:Destroy()
		LightContainer = nil
		LightEnabled = false
		script.FlashLightSound:Stop()
	else
		local Camera = Workspace.CurrentCamera
		local StartPosition = Camera.CFrame.Position + Camera.CFrame.LookVector * 2

		LightContainer = Instance.new("Part", Workspace)
		LightContainer.Name = "LightContainer"
		LightContainer.Anchored = true
		LightContainer.CanCollide = false
		LightContainer.Size = Vector3.new(0.1, 0.1, 0.1)
		LightContainer.CFrame = CFrame.new(StartPosition)

		local SpotLight = Instance.new("SpotLight", LightContainer)
		SpotLight.Name = "MouseLight"
		SpotLight.Range = 60
		SpotLight.Angle = 60
		SpotLight.Shadows = true

		LightEnabled = true
		script.FlashLightSound:Play()
	end
end

Workspace.GameFolder.Light.Changed:Connect(function(NewValue)
	if NewValue == true then
		ToggleLight()
	elseif LightContainer then
		ToggleLight()
	end
end)

RunService.RenderStepped:Connect(UpdateLightOrientation)

if Workspace.GameFolder.Light.Value == true then
	ToggleLight()
end```
2 Likes

would it be possible to just parent the LightContainer to camera instead of Workspace?

1 Like

I have tried that but it acts the same. And also heres the clip. I might need to also fix the light moving wherever the mouse is pointing to

Maybe try using CurrentCamera.CFrame instead of GetMouse?

1 Like

This works a bit better now, but the part is not always infront of the camera/head itself

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local LightEnabled = false
local LightContainer = nil

function UpdateLightOrientation()
	if LightEnabled and LightContainer and LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Head") then
		local Head = LocalPlayer.Character.Head
		local Camera = Workspace.CurrentCamera

		local TargetPosition = Camera.CFrame.Position + Camera.CFrame.LookVector * 100

		LightContainer.Position = Head.Position + Head.CFrame.LookVector * 2

		LightContainer.CFrame = CFrame.lookAt(LightContainer.Position, TargetPosition)
	end
end

function ToggleLight()
	if LightContainer then
		LightContainer:Destroy()
		LightContainer = nil
		LightEnabled = false
		script.FlashLightSound:Stop()
	else
		local Camera = Workspace.CurrentCamera
		local StartPosition = Camera.CFrame.Position + Camera.CFrame.LookVector * 2

		LightContainer = Instance.new("Part", Workspace)
		LightContainer.Name = "LightContainer"
		LightContainer.Anchored = true
		LightContainer.CanCollide = false
		LightContainer.Size = Vector3.new(0.1, 0.1, 0.1)
		LightContainer.CFrame = CFrame.new(StartPosition)

		local SpotLight = Instance.new("SpotLight", LightContainer)
		SpotLight.Name = "MouseLight"
		SpotLight.Range = 60
		SpotLight.Angle = 60
		SpotLight.Shadows = true

		LightEnabled = true
		script.FlashLightSound:Play()
	end
end

Workspace.GameFolder.Light.Changed:Connect(function(NewValue)
	if NewValue == true then
		ToggleLight()
	elseif LightContainer then
		ToggleLight()
	end
end)

RunService.RenderStepped:Connect(UpdateLightOrientation)

if Workspace.GameFolder.Light.Value == true then
	ToggleLight()
end

made a couple changes sorry for late response, im tired

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local LightEnabled = false
local LightContainer = nil

function UpdateLightOrientation()
	if LightEnabled and LightContainer and LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Head") then
		local Head = LocalPlayer.Character.Head
		local Camera = Workspace.CurrentCamera
		
		local DesiredPosition = Head.Position + Camera.CFrame.LookVector * 2

		local TargetPosition = DesiredPosition + Camera.CFrame.LookVector * 10
		
		LightContainer.CFrame = CFrame.lookAt(DesiredPosition, TargetPosition)
	end
end

function ToggleLight()
	if LightContainer then
		LightContainer:Destroy()
		LightContainer = nil
		LightEnabled = false
		script.FlashLightSound:Stop()
	else
		local Camera = Workspace.CurrentCamera
		local StartPosition = Camera.CFrame.Position + Camera.CFrame.LookVector * 2 -- updated by renderstep

		LightContainer = Instance.new("Part", Workspace)
		LightContainer.Name = "LightContainer"
		LightContainer.Anchored = true
		LightContainer.CanCollide = false
		LightContainer.Size = Vector3.new(0.1, 0.1, 0.1)
		LightContainer.CFrame = CFrame.new(StartPosition)

		local SpotLight = Instance.new("SpotLight", LightContainer)
		SpotLight.Name = "MouseLight"
		SpotLight.Range = 60
		SpotLight.Angle = 60
		SpotLight.Shadows = true
		SpotLight.Face = Enum.NormalId.Front -- make sure light always faces front

		LightEnabled = true
		script.FlashLightSound:Play()
		
		UpdateLightOrientation() -- update position relative to the head
	end
end

Workspace.GameFolder.Light.Changed:Connect(function(NewValue)
	if NewValue == true then
		ToggleLight()
	elseif LightContainer then
		ToggleLight()
	end
end)

RunService:BindToRenderStep("UpdateLightOrientation", Enum.RenderPriority.Camera.Value + 1, UpdateLightOrientation) -- runs before frame is rendered for better positioning

if Workspace.GameFolder.Light.Value == true then
	ToggleLight()
end
1 Like

This works a lot better but when I look up or down, the light is not centered to the mouse position

What if you increase Camera.CFrame.LookVector * 10 to Camera.CFrame.LookVector * 100 (or higher)

Nothing happens its just the same

he will get the same result as any other value

I don’t know what your plan for the game is with the flashlight but to me it seems fine as long as you dont see the LightContainer Part, or you could just remake how the flashlight works since this way of doing is a little over complicated.

Well what kind of remake then?

I have finally fixed it but I used the same strategy in the script, thanks everyone for helping