How can i do this my tool?

Does anyone know how to make it so when a tool is a equipped the players idle and run animation are changed and when the player unequips the tool they go back to their normal animation?

You should search the devforum for existing solutions next time :slight_smile:

2 Likes

I tried out the scripts before posting this, they didnt’t work on my end i think its because its old

1 Like

Are you getting any red errors in console?

1 Like

yes i do get errors even when i made my own animation ids

1 Like

Could you please show what the errors say?

1 Like

i tested it again and found out its not an error, but the problem doesnt even show it just doesnt play the animation at all and doesnt say anything, i tried a print and the print worked while the animation didnt


Screenshot 2025-05-17 220227

1 Like

RunAnim was the old name of the Animation as of my knowledge, it’s currently named “run”

tool.Equipped:Connect(function()
	game.Players.LocalPlayer.Character.Animate.run.run.AnimationId = "http://www.roblox.com/asset/?id=507784897" --Default swimming animation
end)
tool.Unequipped:Connect(function()
	game.Players.LocalPlayer.Character.Animate.run.run.AnimationId = "http://www.roblox.com/asset/?id=507767714" --Default running animation
end)


i got this error when i tried it

Oh, I thought you were using R15 my apologies. The animation is named RunAnim like you’ve used before on R6.

Is the owner of the experience same with the owner of the animation?

its a group game, and im the owner of the group and i put the animation id under the group n

Changing the animation ID’s of the default animations isn’t enough, unfortunately. You’ll need to do something like this instead:

local Players = game:GetService("Players") -- This is the recommended way of getting a service
local RunService = game:GetService("RunService")

local tool = script.Parent

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait() -- There's a chance that this script will run before the player's...
-- ...character has loaded, so we'll need to do this to safely get the character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")


local connection = nil
local idle, run


local function CreateAnimationTrack(animationId, looped)
	assert(typeof(animationId) == "number", 'CreateAnimationTrack Error: "animationId" must be a number value!')
	assert(typeof(looped) == "boolean", 'CreateAnimationTrack Error: "looped" must be a boolean value!')

	local animation = Instance.new("Animation")
	animation.AnimationId = "rbxassetid://"..animationId

	local animationTrack = animator:LoadAnimation(animation)
	animationTrack.Looped = looped
	animationTrack.Priority = Enum.AnimationPriority.Action -- Make sure that the AnimationTrack's priority is higher than the one used...
	-- ...by the default script

	return animationTrack
end

local function OnPostSimulation()
	if humanoid.MoveDirection == Vector3.zero then -- If the player isn't moving
		if idle.IsPlaying then return end -- The idle animation is already playing, so no need to do anything

		run:Stop()
		idle:Play()
	else -- If the player is moving
		if run.IsPlaying then return end

		idle:Stop()
		run:Play()
	end
end

local function OnEquipped()
	if connection then return end -- Do not create a connection if one already exists!

	connection = RunService.PostSimulation:Connect(OnPostSimulation)
end

local function OnUnequipped()
	if connection then
		connection:Disconnect()
		connection = nil

		-- Revert back to the default animations once the tool is unequipped, by making sure that the animations have stopped
		if idle.IsPlaying then idle:Stop() end
		if run.IsPlaying then run:Stop() end
	end
end

-- I used the Swim and SwimIdle animations for testing
-- Don't forget to use the animation ID's of your animations instead!
idle = CreateAnimationTrack(913389285, true)
run = CreateAnimationTrack(913384386, true)

tool.Equipped:Connect(OnEquipped)
tool.Unequipped:Connect(OnUnequipped)
2 Likes

Well actually, it is, but only when the animate script refreshes the animation via a state change.
Changing the humanoid state to Landed on the client should do the trick.

The “best” solution would probably be to copy the animate script and make it listen to changed signals.

1 Like

This script should work (hopefully at least)

-- Services --
local Players = game:GetService("Players")

-- Constants --
local LOCALPLAYER = Players.LocalPlayer
local TOOL = script.Parent

-- Other variables --
local animate: BaseScript?, humanoid: Humanoid?

TOOL.Equipped:Connect(function()
	local character = LOCALPLAYER.Character
	if not character then
		return
	end

	animate = character:FindFirstChild("Animate")
	if not animate then
		return
	end

	animate.run.RunAnim.AnimationId = "rbxassetid://ANIMATIONID"
	animate.walk.WalkAnim.AnimationId = "rbxassetid://ANIMATIONID"

	humanoid = character:FindFirstChildWhichIsA("Humanoid")
	
	if humanoid then
		humanoid:ChangeState(Enum.HumanoidStateType.Landed)
	end
end)

TOOL.Unequipped:Connect(function()
	animate.run.RunAnim.AnimationId = "http://www.roblox.com/asset/?id=180426354"
	animate.walk.WalkAnim.AnimationId = "http://www.roblox.com/asset/?id=180426354"
	
	humanoid:ChangeState(Enum.HumanoidStateType.Landed)
end)