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