I feel like you’re mixing up what the server has to do here and what the client has to do.
Let’s write some pseudocode for what the server has to do:
--[[
When bread is touched
check if a player touched the bread
check if player's tool was activated
add storage
]]
Now, the pseudocode for what the client has to do:
--[[
When the tool is activated
play animation
]]
Now let’s try coding our pseudocode:
Server
local loaf = workspace.Bread:GetChildren()
for _, bread in pairs(loaf) do
bread.Touched:Connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if not player or not player:FindFirstChildOfClass("Tool") then return end
-- Keep in mind that this does not check for a specific tool, feel free to switch to a :FindFirstChild()
-- Check if player's tool is currently activated [INCOMPLETE]
if activated then
player.BackpackF.Storage.Value = player.BackpackF.Storage.Value + 1
end
end)
end
Client
local player = game.Players.LocalPlayer
local tool = script.Parent
local swinging = false
local swing = player.Character.Humanoid:LoadAnimation(script.Parent.Swing)
tool.Activated:Connect(function()
swinging = not swinging -- true turns false and false turns true
if swinging then
swing:Play()
swing.Stopped:Wait()
swinging = false
end
end)
So as of now, our scripts can:
- Play the animation
- Check if bread was touched and link it to a player
- Add storage
What’s missing is the check if player’s tool was activated part. We can achieve this by checking if the animation is playing:
local function isAnimPlaying(player, animName)
local tracks = player.Character.Humanoid:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.Name == animName then return true end
end
return false
end
Incorporating this into our previous server code:
local debounce = {}
local loaf = workspace.Bread:GetChildren()
local function isAnimPlaying(player, animName)
local tracks = player.Character.Humanoid:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.Name == animName then return true end
end
return false
end
for _, bread in pairs(loaf) do
debounce[bread] = {}
bread.Touched:Connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if not player or not player:FindFirstChildOfClass("Tool") then return end
if isAnimPlaying(player, "Swing") and not debounce[bread][player] then
player.BackpackF.Storage.Value = player.BackpackF.Storage.Value + 1
debounce[bread][player] = true
wait(1)
debounce[bread][player] = false
end
end)
end
That’s it, our scripts can together:
- Play an animation
- Check if a player touches the bread and if their tool is currently playing the animation and reward storage if so.
Final Scripts
Server
local debounce = {}
local loaf = workspace.Bread:GetChildren()
local function isAnimPlaying(player, animName)
local tracks = player.Character.Humanoid:GetPlayingAnimationTracks()
for _, track in pairs(tracks) do
if track.Animation.Name == animName then return true end
end
return false
end
for _, bread in pairs(loaf) do
debounce[bread] = {}
bread.Touched:Connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if not player or not player:FindFirstChildOfClass("Tool") then return end
if isAnimPlaying(player, "Swing") and not debounce[bread][player] then
player.BackpackF.Storage.Value = player.BackpackF.Storage.Value + 1
debounce[bread][player] = true
wait(1)
debounce[bread][player] = false
end
end)
end
Client
local player = game.Players.LocalPlayer
local tool = script.Parent
local swinging = false
local swing = player.Character.Humanoid:LoadAnimation(script.Parent.Swing)
tool.Activated:Connect(function()
swinging = not swinging
if swinging then
swing:Play()
swing.Stopped:Wait()
swinging = false
end
end)
This whole script is based on a lot of assumptions when it comes to what exactly you want to achieve, please tell me if this isn’t what you were aiming to do. If it was, mark this as the answer