Currently trying to implement my inventory system into my game but I’ve encountered something that is literally going to make me go crazy. So, I have a script (below) inside of the tool which works fine when the tool is placed in starterpack. However, when i place the tool inside of a folder within serverstorage (to be added to the inventory system) it behaves oddly and just stops working.
The weapon suddenly does no damage and if I unequip the weapon while running the run animation just plays infinite. If anybody can take a look at the script and maybe see what’s going on that would be amazing.
local tool = script.Parent
local player = game.Players.LocalPlayer
local animations = {
"rbxassetid://LEFTBLANKONPURPOSE",
"rbxassetid://LEFTBLANKONPURPOSE",
"rbxassetid://LEFTBLANKONPURPOSE",
"rbxassetid://LEFTBLANKONPURPOSE",
"rbxassetid://LEFTBLANKONPURPOSE",
"rbxassetid://LEFTBLANKONPURPOSE"
}
local idleAnimationId = "rbxassetid://LEFTBLANKONPURPOSE" -- Replace with your idle animation ID
local runAnimationId = "rbxassetid://LEFTBLANKONPURPOSE" -- Replace with your run animation ID
local swingTracks = {}
local idleTrack
local runTrack
local bladeSensor
local isAttacking = false -- Flag to track if an attack is in progress
local currentAnimationIndex = 1 -- Track the current animation index
local runningConnection
local stateConnection
local originalWalkSpeed
local attackRange = 10 -- Adjust this value as needed
local faceEnemyConnection
local function stopAllAnimations()
if idleTrack then
idleTrack:Stop()
end
if runTrack then
runTrack:Stop()
end
for _, track in pairs(swingTracks) do
track:Stop()
end
end
local function handleStateChange(humanoid, newState)
if newState == Enum.HumanoidStateType.Freefall or newState == Enum.HumanoidStateType.Jumping then
stopAllAnimations()
elseif newState == Enum.HumanoidStateType.Landed then
if humanoid.MoveDirection.Magnitude > 0 then
runTrack:Play()
else
idleTrack:Play()
end
end
end
local function faceClosestEnemy()
local character = player.Character
local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local closestEnemy = nil
local shortestDistance = attackRange
for _, enemy in ipairs(workspace.Enemies:GetChildren()) do
local enemyHumanoidRootPart = enemy:FindFirstChild("HumanoidRootPart")
if enemyHumanoidRootPart then
local distance = (humanoidRootPart.Position - enemyHumanoidRootPart.Position).Magnitude
if distance < shortestDistance then
closestEnemy = enemyHumanoidRootPart
shortestDistance = distance
end
end
end
if closestEnemy then
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, closestEnemy.Position)
end
end
tool.Equipped:Connect(function()
if player.Character and player.Character:FindFirstChild("Humanoid") then
local humanoid = player.Character.Humanoid
originalWalkSpeed = humanoid.WalkSpeed
-- Load idle animation
local idleAnimation = Instance.new("Animation")
idleAnimation.AnimationId = idleAnimationId
idleTrack = humanoid:LoadAnimation(idleAnimation)
idleTrack:Play()
-- Load run animation
local runAnimation = Instance.new("Animation")
runAnimation.AnimationId = runAnimationId
runTrack = humanoid:LoadAnimation(runAnimation)
-- Load swing animations
for _, animationId in ipairs(animations) do
local animation = Instance.new("Animation")
animation.AnimationId = animationId
local swingTrack = humanoid:LoadAnimation(animation)
table.insert(swingTracks, swingTrack)
-- Add event listener for the animation event to deal damage
swingTrack:GetMarkerReachedSignal("DealDamage"):Connect(function()
local function checkRegionForEnemies()
if bladeSensor then
local regionSize = Vector3.new(5, 5, 5) -- Define the size of the region
local regionCFrame = bladeSensor.CFrame
local region = Region3.new(
regionCFrame.Position - regionSize / 2,
regionCFrame.Position + regionSize / 2
)
region = region:ExpandToGrid(4) -- Ensure the region size is a multiple of 4
-- Visualize the region for debugging
local part = Instance.new("Part")
part.Size = regionSize
part.Anchored = true
part.CanCollide = false
part.Material = Enum.Material.Neon
part.BrickColor = BrickColor.new("Bright blue")
part.CFrame = regionCFrame
part.Transparency = 1 -- Set transparency to 1 (completely transparent)
part.Parent = workspace
game.Debris:AddItem(part, 0.1)
-- Check if any enemies are within the region
local foundEnemies = {}
for _, instance in ipairs(workspace:FindPartsInRegion3(region, player.Character, math.huge)) do
if instance.Name == "Hitbox" and instance.Parent:FindFirstChild("Humanoid") then
table.insert(foundEnemies, instance.Parent.Humanoid)
end
end
return foundEnemies
end
return {}
end
-- Check the region repeatedly during the animation
local connection
connection = game:GetService("RunService").RenderStepped:Connect(function()
if swingTrack.IsPlaying then
local enemiesHit = checkRegionForEnemies()
for _, humanoid in ipairs(enemiesHit) do
print("Enemy hit detected")
-- Hit the enemy
game.ReplicatedStorage.DamageEnemy:FireServer(humanoid, tool)
end
if #enemiesHit > 0 then
connection:Disconnect()
end
else
connection:Disconnect()
end
end)
end)
-- Add event listener to reset attack flag, reset walk speed, and advance animation index when animation ends
swingTrack.Stopped:Connect(function()
isAttacking = false
humanoid.WalkSpeed = originalWalkSpeed
currentAnimationIndex = currentAnimationIndex % #animations + 1 -- Move to the next animation in the sequence
if faceEnemyConnection then
faceEnemyConnection:Disconnect()
faceEnemyConnection = nil
end
end)
end
-- Handle running animation
runningConnection = humanoid.Running:Connect(function(speed)
if speed > 0 then
if not runTrack.IsPlaying then
if idleTrack.IsPlaying then
idleTrack:Stop()
end
runTrack:Play()
end
else
if runTrack.IsPlaying then
runTrack:Stop()
idleTrack:Play()
end
end
end)
-- Handle state change to manage jumping and landing
stateConnection = humanoid.StateChanged:Connect(function(_, newState)
handleStateChange(humanoid, newState)
end)
-- Check initial state and play appropriate animation
if humanoid.MoveDirection.Magnitude > 0 then
runTrack:Play()
else
idleTrack:Play()
end
end
end)
tool.Unequipped:Connect(function()
stopAllAnimations()
if runningConnection then
runningConnection:Disconnect()
runningConnection = nil
end
if stateConnection then
stateConnection:Disconnect()
stateConnection = nil
end
if faceEnemyConnection then
faceEnemyConnection:Disconnect()
faceEnemyConnection = nil
end
end)
local function onActivate()
if isAttacking then
return -- Do not allow another attack while one is in progress
end
isAttacking = true -- Set the flag to true when starting an attack
if player.Character and player.Character:FindFirstChild("Humanoid") then
local humanoid = player.Character.Humanoid
humanoid.WalkSpeed = 2 -- Set walk speed to 2 during attack
if #swingTracks > 0 then
local swingTrack = swingTracks[currentAnimationIndex]
if swingTrack and swingTrack.IsPlaying then
swingTrack:Stop()
end
if swingTrack then
swingTrack:Play()
local swingSound = Instance.new("Sound", tool.Handle)
swingSound.SoundId = "rbxassetid://11802492693"
swingSound:Play()
-- Face the closest enemy during attack
faceClosestEnemy() -- Face the enemy once at the start of the attack
faceEnemyConnection = game:GetService("RunService").RenderStepped:Connect(faceClosestEnemy)
end
end
end
end
tool.Activated:Connect(onActivate)
-- Find the blade sensor when the tool is equipped
tool.AncestryChanged:Connect(function(_, parent)
if parent == player.Backpack or parent == player.Character then
bladeSensor = tool:FindFirstChild("BladeSensor", true)
end
end)
-- Ensure tool works even when cloned from ServerStorage
tool.DescendantAdded:Connect(function(descendant)
if descendant:IsA("Tool") then
descendant.AncestryChanged:Connect(function(_, parent)
if parent == player.Backpack or parent == player.Character then
bladeSensor = descendant:FindFirstChild("BladeSensor", true)
end
end)
end
end)