Why when i dropping tool animation is still playing


heres server script

local Players           = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Debris            = game:GetService("Debris")

local DAMAGE        = 12.5
local REACH         = 8
local COOLDOWN      = 0.4

local EQUIP_ANIM_ID  = "rbxassetid://128332336030490"
local ATTACK_ANIM_ID = "rbxassetid://109333098941141"
local HIT_SOUND_ID   = "rbxassetid://7171761940"

local KatanaRemote = ReplicatedStorage:FindFirstChild("KatanaHit")
local StateRemote = ReplicatedStorage:FindFirstChild("KatanaState")
local ShowDamageRemote = ReplicatedStorage:FindFirstChild("ShowDamage")

local lastAttack = {}
local animData   = {}

local function getCharacterHum(player)
	local char = player.Character
	if not char then return nil, nil end
	local hum = char:FindFirstChildOfClass("Humanoid")
	local hrp = char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso")
	return hum, hrp
end

local function getKatanaTool(player)
	local char = player.Character
	if not char then return nil end
	for _, child in ipairs(char:GetChildren()) do
		if child:IsA("Tool") and child.Name == "Katana" then
			return child
		end
	end
	return nil
end

local function stopAllTracks(player)
	local data = animData[player]
	if not data then return end

	if data.idleTrack then
		data.idleTrack:Stop(0)
		data.idleTrack = nil
	end
	if data.attackTrack then
		data.attackTrack:Stop(0)
		data.attackTrack = nil
	end
end

local function ensureAnimData(player)
	local data = animData[player]
	if data then
		return data
	end

	local hum = select(1, getCharacterHum(player))
	if not hum then return nil end

	data = {
		hum         = hum,
		idleTrack   = nil,
		attackTrack = nil,
	}
	animData[player] = data

	hum.Died:Connect(function()
		stopAllTracks(player)
	end)

	return data
end

local function playIdle(player)
	local data = ensureAnimData(player)
	if not data or not data.hum then return end

	stopAllTracks(player)

	local idleAnim = Instance.new("Animation")
	idleAnim.AnimationId = EQUIP_ANIM_ID

	local track = data.hum:LoadAnimation(idleAnim)
	track.Looped   = true
	track.Priority = Enum.AnimationPriority.Idle
	track:Play()

	data.idleTrack = track
end

local function playAttack(player)
	local data = ensureAnimData(player)
	if not data or not data.hum then return end

	if data.attackTrack then
		data.attackTrack:Stop(0)
	end

	local anim = Instance.new("Animation")
	anim.AnimationId = ATTACK_ANIM_ID

	local track = data.hum:LoadAnimation(anim)
	track.Looped   = false
	track.Priority = Enum.AnimationPriority.Action4
	track:Play()

	data.attackTrack = track
end

local function playHitSound(player)
	local _, hrp = getCharacterHum(player)
	if not hrp then return end

	local tool   = getKatanaTool(player)
	local parent = tool and tool:FindFirstChild("Handle") or hrp

	local sound = Instance.new("Sound")
	sound.SoundId = HIT_SOUND_ID
	sound.Volume  = 1
	sound.Parent  = parent
	sound:Play()
	Debris:AddItem(sound, 3)
end

StateRemote.OnServerEvent:Connect(function(player, state)
	if type(state) ~= "string" then return end

	if state == "Equipped" then
		if getKatanaTool(player) then
			playIdle(player)
		end
	elseif state == "Unequipped"
		or state == "Removed"
		or state == "CharRemoving" then
		stopAllTracks(player)
	end
end)

KatanaRemote.OnServerEvent:Connect(function(player, targetPart)
	if typeof(player) ~= "Instance" or not player:IsA("Player") then return end
	if not targetPart or not targetPart:IsA("BasePart") then return end

	local now = tick()
	if lastAttack[player] and now - lastAttack[player] < COOLDOWN then
		return
	end
	lastAttack[player] = now

	local hum, hrp = getCharacterHum(player)
	if not hum or not hrp then return end

	if not getKatanaTool(player) then
		return
	end

	local victimModel = targetPart:FindFirstAncestorOfClass("Model")
	if not victimModel then return end

	local victimHum = victimModel:FindFirstChildOfClass("Humanoid")
	if not victimHum or victimHum.Health <= 0 then return end

	if victimModel == player.Character then
		return
	end

	local dist = (hrp.Position - targetPart.Position).Magnitude
	if dist > REACH then
		return
	end

	playAttack(player)

	victimHum:TakeDamage(DAMAGE)

	playHitSound(player)

	if ShowDamageRemote then
		ShowDamageRemote:FireAllClients(
			targetPart.Position + Vector3.new(0, 2, 0),
			DAMAGE,
			false
		)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	stopAllTracks(player)
	animData[player]   = nil
	lastAttack[player] = nil
end)

here local

local Players           = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer

local tool = script:FindFirstAncestorOfClass("Tool")

local hitRemote   = ReplicatedStorage:WaitForChild("KatanaHit")
local stateRemote = ReplicatedStorage:WaitForChild("KatanaState")

local ATTACK_COOLDOWN = 0.4

local mouse     = player:GetMouse()
local canAttack = true

local function sendState(state)
	if stateRemote then
		stateRemote:FireServer(state)
	end
end

tool.Equipped:Connect(function()
	sendState("Equipped")
end)

tool.Unequipped:Connect(function()
	sendState("Unequipped")
end)

tool.AncestryChanged:Connect(function(_, newParent)
	local char     = player.Character
	local backpack = player:FindFirstChild("Backpack")

	if not newParent then
		sendState("Removed")
		return
	end

	if newParent ~= char and newParent ~= backpack then
		sendState("Removed")
	end
end)

player.CharacterRemoving:Connect(function()
	sendState("CharRemoving")
end)

tool.Activated:Connect(function()
	if not canAttack then return end

	local target = mouse.Target
	if target and target:IsA("BasePart") then
		hitRemote:FireServer(target)
	end

	canAttack = false
	task.delay(ATTACK_COOLDOWN, function()
		canAttack = true
	end)
end)

the local script will be already turned off before the remote can fire (local scripts only work in client owned instances)

2 Likes

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