How can I disconnect my camera script?

I have a tool and it’ll set the camera to a position and move the avatar on camera turn sorry if I couldn’t say it well.

I want to disconnect this on tool unequip. Current script gives an error per frame.

local workspaceService = game:GetService("Workspace")
local runService = game:GetService("RunService")
local playersService = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

-- config:
local SENSITIVITY = 0.4
local WORLD_OFFSET = Vector3.new(0, 2, 0)
local LOCAL_OFFSET = Vector3.new(3, -2, 9.5)
local tool = script.Parent

-- variables:
local camera = workspaceService.CurrentCamera
local localPlayer = playersService.LocalPlayer
local xAngle = 0
local yAngle = -25

tool.Equipped:Connect(function()
	 -- main:
	-- handle camera moving
	userInputService.InputChanged:Connect(function(input, isProcessed)
	    -- validate input
	    if isProcessed then return end
	    if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
	    -- get delta
	    local delta = input.Delta
	    local deltaX = delta.X
	    local deltaY = delta.Y
	    -- update angles
	    xAngle = xAngle - deltaX * SENSITIVITY
	    yAngle = math.clamp(yAngle - deltaY * SENSITIVITY, -80, 80)
	end)
	
	-- handle camera update
	runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
	    -- get necessary data
	    local cameraSubject = camera.CameraSubject
	    if not cameraSubject then return end
	    local isLocalPlayer = false
	    local subject
	    local ignoredInstance
	    -- check camera subject class
	    if cameraSubject:IsA("Humanoid") then
	        ignoredInstance = cameraSubject.Parent
	        if not ignoredInstance:IsA("Model") then return end
	        subject = ignoredInstance.PrimaryPart
	        if not subject then return end
	        if localPlayer.Character == ignoredInstance and cameraSubject.Health > 0 then
	            isLocalPlayer = true
	        end
	    elseif cameraSubject:IsA("BasePart") then
	        subject = cameraSubject
	        ignoredInstance = cameraSubject
	    else return end
	    -- get positioned, world offset, and rotated cframe
	    local xAngleCFrame = CFrame.Angles(0, math.rad(xAngle), 0)
	    local anglesCFrame = xAngleCFrame:ToWorldSpace(CFrame.Angles(math.rad(yAngle), 0, 0))
	    local cameraPosition = subject.Position + WORLD_OFFSET
	    local startCFrame = CFrame.new(cameraPosition):ToWorldSpace(anglesCFrame)
	    -- get camera focus and local offset cframe
	    local cameraCFrame = startCFrame:ToWorldSpace(CFrame.new(LOCAL_OFFSET))
	    local cameraFocus = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -LOCAL_OFFSET.Z))
	    -- assign camera properties
	    camera.Focus = cameraFocus
	    camera.CFrame = cameraCFrame
	    camera.CFrame = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -camera:GetLargestCutoffDistance({ignoredInstance})))
	    -- rotate character
	    if isLocalPlayer then
	        local primaryPartCFrame = ignoredInstance:GetPrimaryPartCFrame()
	        local newCFrame = CFrame.new(primaryPartCFrame.Position):ToWorldSpace(xAngleCFrame)
	        ignoredInstance:SetPrimaryPartCFrame(newCFrame)
	    end
	end)
	
	-- init
	userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	
	tool.Unequipped:Connect(function()
		camera = nil
	end)
end)

Use an if statement to check if the tool is equipped (whenever you’re firing whatever controls the camera, typically renderstepped).

You should use the :Disconnect() function:

local Connection 
Connection = runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()

end)
Connection:Disconnect() -- Stops the connection, or, "disconnects" it

I tried disconnecting on InputChanged but it didn’t let me.

You can use:

local UserInputConnection 
UserInputConnection = UserInputService.InputChanged:Connect(function(input, isProcessed)

end)

UserInputConnection:Disconnect()
1 Like

I changed your script in some parts and tested it and worked for me, let me know if it works for u asweel!

local workspaceService = game:GetService("Workspace")
local runService = game:GetService("RunService")
local playersService = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

-- config:
local SENSITIVITY = 0.4
local WORLD_OFFSET = Vector3.new(0, 2, 0)
local LOCAL_OFFSET = Vector3.new(3, -2, 9.5)
local tool = script.Parent

-- variables:
local camera = workspaceService.Camera
local localPlayer = playersService.LocalPlayer
local IsEquiped = false
local xAngle = 0
local yAngle = -25

runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
	   -- get necessary data
	if camera.CameraSubject == nil or not IsEquiped then return end
	local cameraSubject = camera.CameraSubject
	local isLocalPlayer = false	
	local subject
	local ignoredInstance
		    -- check camera subject class
	 if cameraSubject:IsA("Humanoid") then
		ignoredInstance = cameraSubject.Parent
		if not ignoredInstance:IsA("Model") then return end
		subject = ignoredInstance.PrimaryPart
		if not subject then return end
		if localPlayer.Character == ignoredInstance and cameraSubject.Health > 0 then
		  isLocalPlayer = true
		end
	elseif cameraSubject:IsA("BasePart") then
		subject = cameraSubject
		 ignoredInstance = cameraSubject
	else return end
	-- get positioned, world offset, and rotated cframe
	local xAngleCFrame = CFrame.Angles(0, math.rad(xAngle), 0)
	local anglesCFrame = xAngleCFrame:ToWorldSpace(CFrame.Angles(math.rad(yAngle), 0, 0))
	local cameraPosition = subject.Position + WORLD_OFFSET
	local startCFrame = CFrame.new(cameraPosition):ToWorldSpace(anglesCFrame)
	-- get camera focus and local offset cframe
	local cameraCFrame = startCFrame:ToWorldSpace(CFrame.new(LOCAL_OFFSET))
	local cameraFocus = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -LOCAL_OFFSET.Z))
	-- assign camera properties
	camera.Focus = cameraFocus
	camera.CFrame = cameraCFrame
	camera.CFrame = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -camera:GetLargestCutoffDistance({ignoredInstance})))
	-- rotate character
	if isLocalPlayer then
		local primaryPartCFrame = ignoredInstance:GetPrimaryPartCFrame()
		local newCFrame = CFrame.new(primaryPartCFrame.Position):ToWorldSpace(xAngleCFrame)
		ignoredInstance:SetPrimaryPartCFrame(newCFrame)
	end
end)

tool.Equipped:Connect(function()
	IsEquiped = true
	 -- main:
	-- handle camera moving
	cheackInput = userInputService.InputChanged:Connect(function(input, isProcessed)
	    -- validate input
	    if isProcessed then return end
	    if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
	    -- get delta
	    local delta = input.Delta
	    local deltaX = delta.X
	    local deltaY = delta.Y
	    -- update angles
	    xAngle = xAngle - deltaX * SENSITIVITY
	    yAngle = math.clamp(yAngle - deltaY * SENSITIVITY, -80, 80)
	end)
	
	-- handle camera update
	
	-- init
	userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	
	tool.Unequipped:Connect(function()
		cheackInput:Disconnect()
		IsEquiped = false
	end)
end)

I took the runService function of out ToolEquiped and made a Variable called IsEquiped to know when to run the loop in camera changed!

1 Like