Trouble Stopping Animations in Server-Client Setup

I want that the animations stop playing. It seems like the animation idle does not wanna stop or the animation shooting after i’m done shooting.

Here is a example:
253caad9ee1c160afca38a7d0a798561

I tried adding waits, check upon what is currently playing and more. Feel free to read though my script and thank you for reading!

File:
beamgun.rbxm (216.9 KB)

image

Server script:

-- Services
local Debris = game:GetService("Debris")
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

-- Parts
local tool = script.Parent
local beamPart = ReplicatedStorage:FindFirstChild("Beam")
local gunPointerFromHandle = tool.Handle.GUN:WaitForChild("GunPointA")

-- Configuration
local GunConfig = tool:WaitForChild("Configuration")
local range = GunConfig:WaitForChild("Range")
local shootSpeed = GunConfig:WaitForChild("ShootSpeed").Value
local OnCooldown = false

-- Folders
local remoteEventsFolder = tool:WaitForChild("RemoteEventsFolder")
local animationsFolder = tool:WaitForChild("AnimationsFolder")
-- RemoteEvents
local remoteEvent = remoteEventsFolder:WaitForChild("RemoteEvent")
local animationEvent = remoteEventsFolder:WaitForChild("AnimationEvent")



remoteEvent.OnServerEvent:Connect(function(Player, mouseTarget)
	local startPos = gunPointerFromHandle.Position
	local aimDirection = (mouseTarget - startPos).unit
	local distance = (mouseTarget - startPos).magnitude
	print("Mouse Target Position:", mouseTarget)
	print("Distance:", distance)
	print("Aim Direction:", aimDirection)

	if mouseTarget and Player.Character and range.Value >= distance and not OnCooldown then
		print("Range reached, calculating ray result")

		-- Set OnCooldown to true when the gun fires
		OnCooldown = true

		-- Normalize the aimDirection and multiply by range
		local aimVector = aimDirection * range.Value
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {Player.Character, tool.Handle} --ignore the character and tool when raycasting
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		local rayResult = workspace:Raycast(startPos, aimVector, raycastParams)

		if rayResult then
			print("Ray hit something")
			local hitPart = rayResult.Instance
			local hitPos = rayResult.Position

			local laserPart = Instance.new("Part")
			laserPart.Anchored = true
			laserPart.Name = "Laser"
			laserPart.BrickColor = BrickColor.new("Really red")
			laserPart.CanCollide = false
			laserPart.Size = Vector3.new(0.2, 0.2, distance)
			laserPart.CFrame = CFrame.new(startPos, hitPos) * CFrame.new(0, 0, -distance / 2)
			laserPart.Parent = workspace

			task.wait(shootSpeed)
			laserPart:Destroy()

			-- Reset OnCooldown after the cooldown period
			task.wait(shootSpeed)  -- Change this value to your desired cooldown period
			OnCooldown = false

		else
			print("Ray did not hit anything")
			-- Reset OnCooldown even if the ray did not hit anything
			task.wait(shootSpeed)  -- Change this value to your desired cooldown period
			OnCooldown = false
		end
	else
		print("Conditions not met. Either mouseTarget is nil, player doesn't have a character, range is too short, or tool is on cooldown.")
	end
end)


animationEvent.OnServerEvent:Connect(function(Player, AnimationRequest)
	
	
	local animator = Player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("Animator")
	local idleAnim = animator:LoadAnimation(animationsFolder:WaitForChild("IdleAnim"))
	local shootingAnim = animator:LoadAnimation(animationsFolder:WaitForChild("ShootingAnim"))
	
	if AnimationRequest == "idle" then
		print("Now playing:", AnimationRequest)
		idleAnim:Play()
	elseif AnimationRequest == "stopIdle" then
		print("Now playing:", AnimationRequest)

		idleAnim:Stop()
		shootingAnim:Stop()
	elseif AnimationRequest == "shootingAnim" then
		if not shootingAnim.IsPlaying  then
			print("Now playing:", AnimationRequest)

			idleAnim:Stop()
			shootingAnim:Play()	
		end
	elseif AnimationRequest == "stopShooting" then
		print("Now playing:", AnimationRequest)
		task.wait(0.5)
		shootingAnim:Stop()
		idleAnim:Play()

	end
end)


Client script:

---- Services
--local runService = game:GetService("RunService")
--local players = game:GetService("Players")

---- Player-related
--local player = players.LocalPlayer
--local mouse = player:GetMouse() 

---- Tool-related
--local tool = script.Parent

---- Folders
--local remoteEventsFolder = tool:WaitForChild("RemoteEventsFolder")
--local remoteEvent = remoteEventsFolder:WaitForChild("RemoteEvent")

---- Configuration
--local gunConfig = tool:WaitForChild("Configuration")
--local currentAmountOfAmmo = gunConfig:WaitForChild("CurrentAmountOfAmmo")

---- Other
--local activated = false -- Flag to track the activation state
--local heartbeat -- Variable to store the heartbeat connection

--function Fire()
--	remoteEvent:FireServer(mouse.Hit.Position)
--end

--tool.Activated:Connect(function()
--	activated = true -- Set the activation flag to true

--	-- Check if the gun is automatic
--	if gunConfig:WaitForChild("IsAutomatic").Value == true then
--		-- Connect to the Heartbeat event for automatic firing
--		heartbeat = runService.Heartbeat:Connect(function()
--			if activated then
--				Fire() -- Fire the remote event
--			else
--				heartbeat:Disconnect() -- Disconnect the heartbeat connection
--			end
--		end)
--	else
--		remoteEvent:FireServer(mouse.Hit.Position) -- Fire the remote event with the hit position of the mouse as an argument
--	end
--end)

--tool.Deactivated:Connect(function()
--	task.delay(.01,function() -- Schedules a function to be executed after delayTime seconds have passed, without yielding the current thread.
--		--Delay the execution of the following code by 0.01 seconds
--		if activated then
--			activated = false -- Set the activation flag to false
--		end
--	end)
--end)

--tool.Unequipped:Connect(function()
--	activated = false -- Set the activation flag to false when the tool is unequipped
--	if heartbeat then
--		heartbeat:Disconnect() -- Disconnect the heartbeat connection if it exists
--	end
--end)

--tool.Equipped:Connect(function()
--	-- Additional logic when the tool is equipped
--end)


-- Services
local runService = game:GetService("RunService")
local players = game:GetService("Players")

-- Player-related
local player = players.LocalPlayer
local mouse = player:GetMouse() 

-- Tool-related
local tool = script.Parent

-- Folders
local remoteEventsFolder = tool:WaitForChild("RemoteEventsFolder")
local remoteEvent = remoteEventsFolder:WaitForChild("RemoteEvent")
local animationEvent = remoteEventsFolder:WaitForChild("AnimationEvent")

-- Configuration
local gunConfig = tool:WaitForChild("Configuration")
local currentAmountOfAmmo = gunConfig:WaitForChild("CurrentAmountOfAmmo")

-- Flag to track the activation state
local activated = false
local heartbeat -- Variable to store the heartbeat connection

-- Function to update the remote event with mouse position
function UpdateRemote()
	if activated then
		remoteEvent:FireServer(mouse.Hit.Position)
	end
end

-- Modify the Activated event to continuously update the remote event
tool.Activated:Connect(function()
	activated = true

	-- Check if the gun is automatic
	if gunConfig:WaitForChild("IsAutomatic").Value == true then
		-- Connect to the Heartbeat event for automatic firing
		heartbeat = runService.Heartbeat:Connect(UpdateRemote)
		local AnimationRequest = "shootingAnim"
		animationEvent:FireServer(AnimationRequest)
	else
		UpdateRemote()
	end
end)

-- Modify the Deactivated event to disconnect the heartbeat
tool.Deactivated:Connect(function()
	activated = false
	if heartbeat then
		heartbeat:Disconnect()
	end
	-- Fire a new animation request to stop shooting animation
	local AnimationRequest = "stopShooting"
	animationEvent:FireServer(AnimationRequest)
end)


tool.Equipped:Connect(function()
	local AnimationRequest = "idle"
	animationEvent:FireServer(AnimationRequest)
end)

tool.Unequipped:Connect(function()
	local AnimationRequest = "stopIdle"
	animationEvent:FireServer(AnimationRequest)
	local AnimationRequest = "stopShooting"
	animationEvent:FireServer(AnimationRequest)
end)

You should disable loop on your animation and it will solve your current issue.

Wouldn’t loop be required when you want the idle animation/shooting animation to keep going? Like as in to continue shooting or keep doing idle animation until the player unequip the tool?

You should unloop it if a player unequipped the tool.

I have tried that just now but seems not to work

Seems like the issue is that if you run animations on serverside using client remoteEvent and on your own animator it basically break. Adding it to the localscript works and is no need for serverside animation.

Thanks anyhow for the help.

-- Services
local runService = game:GetService("RunService")
local players = game:GetService("Players")

-- Player-related
local player = players.LocalPlayer
local mouse = player:GetMouse() 

-- Tool-related
local tool = script.Parent

-- Folders
local remoteEventsFolder = tool:WaitForChild("RemoteEventsFolder")
local animationsFolder = tool:WaitForChild("AnimationsFolder")
local remoteEvent = remoteEventsFolder:WaitForChild("RemoteEvent")

-- Configuration
local gunConfig = tool:WaitForChild("Configuration")
local currentAmountOfAmmo = gunConfig:WaitForChild("CurrentAmountOfAmmo")

-- Flag to track the activation state
local activated = false
local heartbeat -- Variable to store the heartbeat connection

-- Function to update the remote event with mouse position
function UpdateRemote()
	if activated then
		remoteEvent:FireServer(mouse.Hit.Position)
	end
end

-- animations
local animator = player.Character:FindFirstChildOfClass("Humanoid"):WaitForChild("Animator")
local idleAnim = animator:LoadAnimation(animationsFolder:WaitForChild("IdleAnim"))
local shootingAnim = animator:LoadAnimation(animationsFolder:WaitForChild("ShootingAnim"))

-- Modify the Activated event to continuously update the remote event
tool.Activated:Connect(function()
	activated = true

	-- Check if the gun is automatic
	if gunConfig:WaitForChild("IsAutomatic").Value == true then
		-- Connect to the Heartbeat event for automatic firing
		heartbeat = runService.Heartbeat:Connect(UpdateRemote)
		shootingAnim:play()
	else
		UpdateRemote()
	end
end)

-- Modify the Deactivated event to disconnect the heartbeat
tool.Deactivated:Connect(function()
	activated = false
	if heartbeat then
		heartbeat:Disconnect()
	end
	-- Fire a new animation request to stop shooting animation
	shootingAnim:stop()
	idleAnim:play()
end)


tool.Equipped:Connect(function()
	idleAnim:play()
	shootingAnim:stop()
end)

tool.Unequipped:Connect(function()
	activated = false -- Set the activation flag to false when the tool is unequipped
	if heartbeat then
		heartbeat:Disconnect() -- Disconnect the heartbeat connection if it exists
	end
	idleAnim:stop()
	shootingAnim:stop()

end)

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