My wand animation feels to infinitely loop for no reasons

You can write your topic however you want, but you need to answer these questions:

  1. **What i want to achieve in my work is:

A working ability when required and called from the Wand that will make the character roll using an R6 animation with a force allowing the player to dash and avoid few attacks.

  1. What is the issue? Include screenshots / videos if possible!

First Ability Activation:

Second Ability Activation:

  1. My attempt to solve this problem was:
    Added a animation.Looped = false
    Putting Animation Priority to Action4

So, the problem after all the recommended attempt i found in develeper forum or such other socials like youtube or anything that might solve the problem, it is still going i will put all the scripts below.

Wand Server Script:

local ragdoll = require(game.ServerScriptService.Ragdoll)
local kb = require(game.ServerScriptService.KnockBack)
local ab = require(game.ServerScriptService.Ability)

local db = {}
local debounce = false 
local abdebounce = false
local connection:RBXScriptConnection

local function abilitycooldown()
	local player = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
	game.ReplicatedStorage.RemoteEvents.FireReload:FireClient(player,5,ab.GetAbility(player))
	for t= 5,0,-1 do
		task.wait(1)
	end	
	abdebounce = false
end

local function onRemoteEventFired(player,instance)
	if player.Character ~= script.Parent.Parent then return end
	if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health < 1 then return end

	if not debounce then
		if instance == "Slap" then
			debounce = true

			local function hiteffect()
				-- Reconnect the Touched event
				local anim = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Swing)
				anim:Play()

				local character = script.Parent.Parent

				local hitbox = Instance.new("Part",character)
				hitbox.Transparency = 1
				hitbox.CanCollide = false
				hitbox.Position = character["HumanoidRootPart"].Position
				hitbox.Parent = character["HumanoidRootPart"]
				hitbox.Size = Vector3.new(10,10,10)
				hitbox.Massless = true

				local weld = Instance.new("Weld",character["Right Arm"])
				weld.Part0 = character['Right Arm']
				weld.Part1 = hitbox

				-- Hitbox part

				connection = hitbox.Touched:Connect(function(hit)
					local playerh = game.Players:GetPlayerFromCharacter(hit.Parent)
					
					if playerh then
						if player.Team ~= nil and playerh.Team == player.Team then return end
					end
					
					if table.find(db, hit.Parent) then return end
					local hum = hit.Parent:FindFirstChild("Humanoid")

					script.Parent.Handle.hit:Emit(10)

					if hum then
						script.Parent.Handle.Affected:Play()
						hum:TakeDamage(7)
						table.insert(db, hit.Parent)
						connection:Disconnect()
						kb.Start(hit.Parent, (hit.Parent.HumanoidRootPart.Position - hitbox.Position).Unit * Vector3.new(300, 0, 300) + Vector3.new(0, 300))
						ragdoll.Start(hit.Parent)
						weld:Destroy()
						hitbox:Destroy()
						task.wait(3)
						table.remove(db, table.find(db, hit.Parent))
						ragdoll.Stop(hit.Parent)
					end
				end)

				anim.Ended:Wait()
				if weld then
					weld:Destroy()
				end
				if hitbox then
					hitbox:Destroy()
				end
			end

			script.Parent.Handle.Magic:Play()
			task.wait(1)
			task.spawn(hiteffect)

			-- Wait for 1 second before allowing the next trigger
			task.wait(1)
			debounce = false
		end

		if instance == "Ability" and abdebounce == false then
			abdebounce = true
			ab.Execute(game.Players:GetPlayerFromCharacter(script.Parent.Parent))
			task.spawn(abilitycooldown)
		end
	else
		-- Disconnect the Touched event during debounce
		if connection then
			connection:Disconnect()
		end
	end
end

script.Parent.Interacted.OnServerEvent:Connect(onRemoteEventFired)

Ability Module Script:

local ragdoll = require(game.ServerScriptService.Ragdoll)
local kb = require(game.ServerScriptService.KnockBack)

local availableAbilities = {
	["Wand"] = "Roll",
	["Train"] = "Summon Train",
	["Rocky"] = "The Rock",
	["Picnic"] = "Picnic Table",
	["ZNation"] = "Random Direction",
	["Station"] = "Summon Train",
	["Classic"] = "Classic Day",
}

local Ability = {}

local function playaudio(character,audio)
	if character:FindFirstChild("HumanoidRootPart") then
		local sound:Sound = Instance.new("Sound")
		sound.Parent = character.HumanoidRootPart
		sound.SoundId = "rbxassetid://"..audio
		sound:Play()
		sound.Ended:Wait()
		sound:Destroy()
	end
end

function Ability.GetAbility(player)
	if player then
		for _,item in pairs(player.Character:GetDescendants()) do
			if availableAbilities[item.Name] then
				return availableAbilities[item.Name]
			end
		end
	end
end

function Ability.Execute(player)
	local Ability = Ability.GetAbility(player)

	if Ability then
		local character = player.Character
		local hrp = character:waitForChild("HumanoidRootPart")

		if Ability == "Roll" then
		
			local anim = player.Character.Humanoid:LoadAnimation(game.ServerStorage.Roll_R6) 
			anim.Looped = false
			character.Humanoid.Jump = true 
			anim:Play() 
			
			local att = Instance.new("Attachment",hrp)
			local lv = Instance.new("LinearVelocity",att)
			lv.MaxForce = 3000
			lv.VectorVelocity = hrp.CFrame.LookVector * 100
			lv.Attachment0 = att
		   
		    anim.Ended:Wait()
			lv:Destroy()
			att:Destroy()

			task.wait(0.5)
		end
return
	end
end
return Ability

I don’t think the Touched event is being properly managed…


local ragdoll = require(game.ServerScriptService.Ragdoll)
local kb = require(game.ServerScriptService.KnockBack)
local ab = require(game.ServerScriptService.Ability)

local db = {}
local debounce = false 
local abdebounce = false
local connection: RBXScriptConnection

local function abilitycooldown()
    local player = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
    game.ReplicatedStorage.RemoteEvents.FireReload:FireClient(player, 5, ab.GetAbility(player))
    for t = 5, 0, -1 do
        task.wait(1)
    end    
    abdebounce = false
end

local function onRemoteEventFired(player, instance)
    if player.Character ~= script.Parent.Parent then return end
    if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health < 1 then return end

    if not debounce then
        if instance == "Slap" then
            debounce = true

            local function hiteffect()
                -- Reconnect the Touched event
                local anim = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Swing)
                anim:Play()

                local character = script.Parent.Parent

                local hitbox = Instance.new("Part", character)
                hitbox.Transparency = 1
                hitbox.CanCollide = false
                hitbox.Position = character["HumanoidRootPart"].Position
                hitbox.Parent = character["HumanoidRootPart"]
                hitbox.Size = Vector3.new(10, 10, 10)
                hitbox.Massless = true

                local weld = Instance.new("Weld", character["Right Arm"])
                weld.Part0 = character['Right Arm']
                weld.Part1 = hitbox

                -- Hitbox part
                connection = hitbox.Touched:Connect(function(hit)
                    local playerh = game.Players:GetPlayerFromCharacter(hit.Parent)
                    
                    if playerh then
                        if player.Team ~= nil and playerh.Team == player.Team then return end
                    end
                    
                    if table.find(db, hit.Parent) then return end
                    local hum = hit.Parent:FindFirstChild("Humanoid")

                    script.Parent.Handle.hit:Emit(10)

                    if hum then
                        script.Parent.Handle.Affected:Play()
                        hum:TakeDamage(7)
                        table.insert(db, hit.Parent)
                        connection:Disconnect()  -- Disconnect the event here
                        kb.Start(hit.Parent, (hit.Parent.HumanoidRootPart.Position - hitbox.Position).Unit * Vector3.new(300, 0, 300) + Vector3.new(0, 300))
                        ragdoll.Start(hit.Parent)
                        weld:Destroy()
                        hitbox:Destroy()
                        task.wait(3)
                        table.remove(db, table.find(db, hit.Parent))
                        ragdoll.Stop(hit.Parent)
                    end
                end)

                -- Wait until the animation ends
                anim.Ended:Wait()

                -- Ensure cleanup after the animation ends
                if connection then
                    connection:Disconnect()
                end
                if weld then
                    weld:Destroy()
                end
                if hitbox then
                    hitbox:Destroy()
                end
                anim:Stop()  -- Ensure the animation stops
            end

            script.Parent.Handle.Magic:Play()
            task.wait(1)
            task.spawn(hiteffect)

            -- Wait for 1 second before allowing the next trigger
            task.wait(1)
            debounce = false
        end

        if instance == "Ability" and abdebounce == false then
            abdebounce = true
            ab.Execute(game.Players:GetPlayerFromCharacter(script.Parent.Parent))
            task.spawn(abilitycooldown)
        end
    else
        -- Disconnect the Touched event during debounce
        if connection then
            connection:Disconnect()
        end
    end
end

script.Parent.Interacted.OnServerEvent:Connect(onRemoteEventFired)

Sadly the loop is still happening

Hm,

Try this, I’ve ensured the Looped property is set to false, The LoadAnimation method doesn’t automatically set this property.

If this doesn’t work, I’m at a loss, I do not see any other fixes.

local ragdoll = require(game.ServerScriptService.Ragdoll)
local kb = require(game.ServerScriptService.KnockBack)
local ab = require(game.ServerScriptService.Ability)

local db = {}
local debounce = false 
local abdebounce = false
local connection:RBXScriptConnection

local function abilitycooldown()
	local player = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
	game.ReplicatedStorage.RemoteEvents.FireReload:FireClient(player,5,ab.GetAbility(player))
	for t = 5, 0, -1 do
		task.wait(1)
	end	
	abdebounce = false
end

local function onRemoteEventFired(player, instance)
	if player.Character ~= script.Parent.Parent then return end
	if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health < 1 then return end

	if not debounce then
		if instance == "Slap" then
			debounce = true

			local function hiteffect()
				-- Load and play the animation
				local anim = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Swing)
				anim.Looped = false -- Ensure the animation doesn't loop
				anim:Play()

				local character = script.Parent.Parent

				local hitbox = Instance.new("Part", character)
				hitbox.Transparency = 1
				hitbox.CanCollide = false
				hitbox.Position = character["HumanoidRootPart"].Position
				hitbox.Parent = character["HumanoidRootPart"]
				hitbox.Size = Vector3.new(10, 10, 10)
				hitbox.Massless = true

				local weld = Instance.new("Weld", character["Right Arm"])
				weld.Part0 = character["Right Arm"]
				weld.Part1 = hitbox

				-- Hitbox part

				connection = hitbox.Touched:Connect(function(hit)
					local playerh = game.Players:GetPlayerFromCharacter(hit.Parent)
					
					if playerh then
						if player.Team ~= nil and playerh.Team == player.Team then return end
					end
					
					if table.find(db, hit.Parent) then return end
					local hum = hit.Parent:FindFirstChild("Humanoid")

					script.Parent.Handle.hit:Emit(10)

					if hum then
						script.Parent.Handle.Affected:Play()
						hum:TakeDamage(7)
						table.insert(db, hit.Parent)
						connection:Disconnect()
						kb.Start(hit.Parent, (hit.Parent.HumanoidRootPart.Position - hitbox.Position).Unit * Vector3.new(300, 0, 300) + Vector3.new(0, 300))
						ragdoll.Start(hit.Parent)
						weld:Destroy()
						hitbox:Destroy()
						task.wait(3)
						table.remove(db, table.find(db, hit.Parent))
						ragdoll.Stop(hit.Parent)
					end
				end)

				anim.Ended:Wait()
				if weld then
					weld:Destroy()
				end
				if hitbox then
					hitbox:Destroy()
				end
			end

			script.Parent.Handle.Magic:Play()
			task.wait(1)
			task.spawn(hiteffect)

			-- Wait for 1 second before allowing the next trigger
			task.wait(1)
			debounce = false
		end

		if instance == "Ability" and abdebounce == false then
			abdebounce = true
			ab.Execute(game.Players:GetPlayerFromCharacter(script.Parent.Parent))
			task.spawn(abilitycooldown)
		end
	else
		-- Disconnect the Touched event during debounce
		if connection then
			connection:Disconnect()
		end
	end
end

script.Parent.Interacted.OnServerEvent:Connect(onRemoteEventFired)

Ability are handeled in the ability module not the wand server script i thought it would be a clean way. also Looped is false in the Ability script with is weird.

Consider stopping the animation when needed by anim:Stop()

anim.Ended:Wait()
anim:Stop()?

If suppose the animation is looped, the ended event wont fire.

Doesn’t stop, its a bit weird. i noticed Jump = true is being ignored too.

Humanoid.Jump is a read only property, use Himanoid:Jump()

Setting humanoid.Jump to be true does make it jump, and humanoid:Jump() isnt real

???, But Humanoid.Jump isnt Readonly?

No… it isnt…

Also where did you get humanoid:Jump() from??

humanoid:Jump() doesn’t exist i alredy made that mistake before.

It says READ PARALLEL, Meaning It is readonly and can be read parallely.

No, Read parallel means you can read it with multi threading at the same time, hence the PARALLEL

FloorMaterial on the other hand is Read Only

Note this method is supposed to work but for some reason is ignored in my script

also looks like it work only on server side which explain player doesnt jump in a module since maybe the modulescript got a client side with is weird since its called from server.