Roblox Animation Issue: Custom Animations Not Playing Immediately

Hey there!

I am currently working on a sword combat system for my game and I need help with an issue I have. It more has to do with the animation system in Roblox.

Here is the local script:

local Services = {
	Players = game:GetService("Players");
	UserInputService = game:GetService("UserInputService");
	ReplicatedStorage = game:GetService("ReplicatedStorage");
}

local isEquipped = false

local Weapon

local Player = Services.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChild("Humanoid")

local AnimateScript = Character:WaitForChild("Animate")
local IdleAnimInstance
local WalkAnimInstance
local DefaultIdle
local DefaultWalk

IdleAnimInstance = AnimateScript:WaitForChild("idle"):WaitForChild("Animation1")
WalkAnimInstance = AnimateScript:WaitForChild("walk"):WaitForChild("WalkAnim")
DefaultIdle = IdleAnimInstance.AnimationId
DefaultWalk = WalkAnimInstance.AnimationId

Character.ChildAdded:Connect(function(Obj)
    if Obj:IsA("Tool") then
        local IsWeaponRE = Services.ReplicatedStorage.Remotes.IsWeapon:InvokeServer(Obj)
        if IsWeaponRE then
            isEquipped = true
            Weapon = Obj
            local WalkAnim = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "walk")
            local IdleAnim = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "idle")
            IdleAnimInstance.AnimationId = IdleAnim
			WalkAnimInstance.AnimationId = WalkAnim
        end
    end
end)

Character.ChildRemoved:Connect(function(Obj)
    if Obj:IsA("Tool") then
        local IsWeaponRE = Services.ReplicatedStorage.Remotes.IsWeapon:InvokeServer(Obj)
        if IsWeaponRE then
            isEquipped = false
            Weapon = nil
            	IdleAnimInstance.AnimationId = DefaultIdle
			WalkAnimInstance.AnimationId = DefaultWalk
        end
    end
end)

Services.UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 and isEquipped then
		Services.ReplicatedStorage.Remotes.Attack:InvokeServer(Character, Weapon)
	end
end)

Services.UserInputService.InputEnded	:Connect(function(input)

end)

Here’s the issue:

I’m experiencing an issue with the animation system in Roblox. When I equip or unequip a weapon while walking or idle, the custom animation doesn’t play immediately. Instead, the default animation continues to play until I stop and take a step or take a step and stop. This happens both when equipping and unequipping the weapon.

Any help is appreciated!

When you do this, you could get the animation too as return:
local IsWeaponRE = Services.ReplicatedStorage.Remotes.IsWeapon:InvokeServer(Obj)

So you dont have to do this to get the animation, you know less stress for server:

local WalkAnim = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "walk")
local IdleAnim = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "idle")

The issue you are having is probably because the old animation still running, even if you set a new animation ID to be handled by Animate script, Animate script “still playing” the previous animation. So you have to stop that animation. Or by iterating on the Current Animation Tracks and stop the one you want, or a hacky way that I cant remember, Humanoid State Landed or something… Its better if you just stop() the animation track of the animation you want to replace.

Stopping all animation tracks:

for _, ani in pairs(Humanoid:FindFirstChild("Animator"):GetPlayingAnimationTracks()) do
	ani:Stop()
end

But again, if I stop the default animations, shouldn’t I take a step to play the custom ones?

It didn’t work…

local Services = {
	Players = game:GetService("Players");
	UserInputService = game:GetService("UserInputService");
	ReplicatedStorage = game:GetService("ReplicatedStorage");
}

local isEquipped = false

local Weapon

local Player = Services.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")

local AnimateScript = Character:WaitForChild("Animate")
local DefaultWalkAnimId = AnimateScript:WaitForChild("walk"):WaitForChild("WalkAnim").AnimationId
local DefaultWalkAnimTrack = nil

local IdleAnimId
local IdleAnimInstance = nil
local IdleAnimTrack = nil

local WalkAnimId
local WalkAnimInstance = nil
local WalkAnimTrack = nil

Character.ChildAdded:Connect(function(Obj)
    if Obj:IsA("Tool") then
        local IsWeaponRE = Services.ReplicatedStorage.Remotes.IsWeapon:InvokeServer(Obj)
        if IsWeaponRE then
            isEquipped = true
            Weapon = Obj
			IdleAnimId = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "idle")
			WalkAnimId = Services.ReplicatedStorage.Remotes.GetWeaponAnim:InvokeServer(Obj, "walk")
			
			if IdleAnimInstance == nil then
				IdleAnimInstance = Instance.new("Animation")
				IdleAnimInstance.AnimationId = IdleAnimId
				
				IdleAnimTrack = Humanoid:LoadAnimation(IdleAnimInstance)
			elseif IdleAnimInstance ~= nil then
				-- Do nothing
			end
			
			if WalkAnimInstance == nil then
				WalkAnimInstance = Instance.new("Animation")
				WalkAnimInstance.AnimationId = WalkAnimId

				WalkAnimTrack = Humanoid:LoadAnimation(WalkAnimInstance)
			elseif WalkAnimInstance ~= nil then
				-- Do nothing
			end
			
			IdleAnimTrack:Play()
			
			for _, ani in pairs(Humanoid:FindFirstChild("Animator"):GetPlayingAnimationTracks()) do
				if ani.Name == "WalkAnim" then
					DefaultWalkAnimTrack = ani
					ani:Stop()
					ani = WalkAnimTrack
				end
			end
        end
    end
end)

Character.ChildRemoved:Connect(function(Obj)
    if Obj:IsA("Tool") then
        local IsWeaponRE = Services.ReplicatedStorage.Remotes.IsWeapon:InvokeServer(Obj)
        if IsWeaponRE then
            isEquipped = false
			Weapon = nil
			IdleAnimTrack:Stop()
			IdleAnimTrack = nil
			IdleAnimInstance = nil
			IdleAnimId = nil
			
			WalkAnimInstance = nil
			WalkAnimId = nil
			WalkAnimTrack = nil
			
			for _, ani in pairs(Humanoid:FindFirstChild("Animator"):GetPlayingAnimationTracks()) do
				if ani.Name == "WalkAnim" then
					ani:Stop()
					ani = DefaultWalkAnimTrack
				end
			end
        end
    end
end)

local isWalking = false
local keysPressed = {}

Services.UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 and isEquipped then
		Services.ReplicatedStorage.Remotes.Attack:InvokeServer(Character, Weapon)
	end
	
	if input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.S then
		keysPressed[input.KeyCode.Name] = true
		isWalking = true
	end
end)

Services.UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.S then
		keysPressed[input.KeyCode.Name] = nil
		if not next(keysPressed) then
			isWalking = false
		end
	end
end)

while wait() do
	if not isWalking and isEquipped then
		if IdleAnimTrack ~= nil then
			IdleAnimTrack:Play()
		end
	elseif isWalking and isEquipped then
		if IdleAnimTrack ~= nil then
			IdleAnimTrack:Stop()
		end
	end
end