Is there any way to disconnect the remote event after unequipping a tool

I want to make a script that gets the camera up when a remoteevent is being fired but when i reequip the tool in this script it gets fired 3,6,9,12… times. Why is that?

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local LogService = game:GetService("LogService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

local function setupViewModel()
	-- Destroy existing viewmodel if it exists
	if workspace.CurrentCamera:FindFirstChild("ViewModelMP5SD") then
		workspace.CurrentCamera.ViewModelMP5SD:Destroy()
	end

	-- Clone the viewmodel from ReplicatedStorage
	local viewmodel = ReplicatedStorage:WaitForChild("ViewModelMP5SD"):Clone()
	viewmodel.Parent = workspace.CurrentCamera

	-- Get the Animator
	local animator = viewmodel:WaitForChild("Humanoid"):WaitForChild("Animator")

	-- Load the animations
	local Ranimation = Instance.new("Animation")
	Ranimation.AnimationId = "rbxassetid://121937746273937" -- Replace with your animation ID
	local RanimationTrack = animator:LoadAnimation(Ranimation)
	RanimationTrack.Priority = Enum.AnimationPriority.Action2
	local REanimation = Instance.new("Animation")
	REanimation.AnimationId = "rbxassetid://75766370456110" -- Replace with your animation ID
	local REanimationTrack = animator:LoadAnimation(REanimation)
	REanimationTrack.Priority = Enum.AnimationPriority.Action4
	local REEmptyAnimation = Instance.new("Animation")
	REEmptyAnimation.AnimationId = "rbxassetid://111792193575216" -- Replace with your animation ID for empty reload
	local REEmptyAnimationTrack = animator:LoadAnimation(REEmptyAnimation)
	REEmptyAnimationTrack.Priority = Enum.AnimationPriority.Action4
	local RanimationL = Instance.new("Animation")
	RanimationL.AnimationId = "rbxassetid://118944095797406" -- Replace with your animation ID for last shot
	local RanimationLTrack = animator:LoadAnimation(RanimationL)
	local WalkAnimation = Instance.new("Animation")
	WalkAnimation.AnimationId = "rbxassetid://88135397333059" -- Replace with your animation ID
	local WalkAnimationTrack = animator:LoadAnimation(WalkAnimation)
	WalkAnimationTrack.Looped = true
	-- Function to stop all playing animations
	local function stopAllAnimations()
		for _, track in ipairs(animator:GetPlayingAnimationTracks()) do
			track:Stop()
		end
	end
	local camera = workspace.CurrentCamera

	local function moveCameraUp()
		local currentCFrame = camera.CFrame
		local newCFrame = currentCFrame * CFrame.Angles(math.rad(0.8), 0, 0)
		camera.CFrame = newCFrame
	end

	-- Function to play the animations
	local function RecoilAnimation()
		stopAllAnimations()
		RanimationTrack:Play()
	end

	local function ReloadAnimation()
		stopAllAnimations()
		REanimationTrack.Priority = Enum.AnimationPriority.Action4
		REanimationTrack:Play()
	end

	local function ReloadEmptyAnimation()
		stopAllAnimations()
		REEmptyAnimationTrack:Play()
	end

	local function LastShotAnimation()
		stopAllAnimations()
		RanimationLTrack:Play()
	end

	-- Lock position at the end of the last shot animation
	RanimationLTrack.Stopped:Connect(function()
		local lastFrameCFrame = viewmodel.PrimaryPart.CFrame -- Assuming PrimaryPart is set
		viewmodel:SetPrimaryPartCFrame(lastFrameCFrame)
	end)

	local MP5SDFire = game.ReplicatedStorage["MP5SD RE"]:WaitForChild("MP5SDFire")
	local MP5SDFireLast = game.ReplicatedStorage["MP5SD RE"]:WaitForChild("MP5SDFireLast")
	local ReloadMP5SDNotEmpty = game.ReplicatedStorage["MP5SD RE"]:WaitForChild("ReloadMP5SDNotEmpty")
	local ReloadMP5SDEmpty = game.ReplicatedStorage["MP5SD RE"]:WaitForChild("ReloadMP5SDEmpty")
	
	MP5SDFire.OnClientEvent:Connect(function()
		moveCameraUp()
		RecoilAnimation()
	end)
	MP5SDFireLast.OnClientEvent:Connect(function()
		moveCameraUp()
		LastShotAnimation()
	end)
	ReloadMP5SDNotEmpty.OnClientEvent:Connect(function()
		ReloadAnimation()
	end)
	ReloadMP5SDEmpty.OnClientEvent:Connect(function()
		ReloadEmptyAnimation()
	end)
	-- Function to handle walking animation
	local function updateWalkingAnimation()
		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if not WalkAnimationTrack.IsPlaying then
				WalkAnimationTrack:Play()
			end
		else
			if WalkAnimationTrack.IsPlaying then
				WalkAnimationTrack:Stop()
			end
		end
	end

	-- Connect the walking animation update to the RenderStepped event
	RunService.RenderStepped:Connect(updateWalkingAnimation)
end


-- Function to handle tool equipped
local function onToolEquipped(tool)
	if tool.Name == "MP5SD" then
		setupViewModel()
	end
end

-- Connect the tool equipped event
player.Character.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		onToolEquipped(child)
	end
end)

-- Handle tool replacement
player.Character.ChildRemoved:Connect(function(child)
	if child:IsA("Tool") and child.Name == "MP5SD" then
		setupViewModel()
	end
end)

If yall know the answer pls reply to this post!

Move the remote event connection out of the main function, so you don’t keep making a new connection each time a player equips the tool.

but then they arent defined properly. should i move the other parts with them too?

you can set them to empty variables, or you can do something like this.

local RemoteEvent = game.ReplicatedStorage.RemoteEvent

local func = RemoteEvent.OnServerEvent:Connect(function()
	print("Hello world!")
end)

task.wait(10)

func:Disconnect()

you can set a variable to a function and disconnect it later.

1 Like

why is that not defined idk why
Zrzut ekranu 2024-09-25 210803

oh wait im dum nvm sry for tht

why doesnt this work?

local setupDone = false
local equippedConnection
local unequippedConnection

local function onToolEquipped(tool)
	if tool.Name == "MP5SD" and not setupDone then
		setupViewModel()
		setupDone = true
	end
end

local function onToolUnequipped(tool)
	if tool.Name == "MP5SD" then
		setupDone = false
	end
end

local function connectToolEvents()
	if equippedConnection then
		equippedConnection:Disconnect()
	end
	equippedConnection = player.Character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") then
			onToolEquipped(child)
		end
	end)

	if unequippedConnection then
	end
	unequippedConnection = player.Character.ChildRemoved:Connect(function(child)
		if child:IsA("Tool") then
			onToolUnequipped(child)
		end
	end)
end

-- Initial connection
connectToolEvents()

Are you setting something here? I think your forgetting to disconnect. Also I would recommend to put the disconnect functions below the function.

so get equipped and unequippedconnection out of the function?

You can try that.

now it just didnt work at all.

You can try disconnecting the function after firing:

unequippedConnection = player.Character.ChildRemoved:Connect(function(child)
		if child:IsA("Tool") then
			onToolUnequipped(child)
            unequippedConnection:Disconnect()
		end
	end)

it works with the camera moving up but the animation stops playing should i give u the whole script?

nvm i fixed it. Thx for the help!

RBXScriptSignal:Once() might be a better solution that just disconnecting the remote after its fired, as it disconnects the function BEFORE running the function.

Try it but can it be used in a localscript

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.