I am trying to play an Idle animation with a tool through a normal script (not a local one) but I don’t know how or if you can do this.
However, it will always say ‘Attempt to index nil with Character’
I do not know any ways to do this, can someone help?
Here is the code
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do wait() end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local Idle = humanoid:LoadAnimation(script.Idle)
Idle.Looped = true
local equipped
script.Parent.Equipped:Connect(function(Player)
equipped = true
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end)
Hi, LocalPlayer does not exist on server scripts because they cannot access data that is relevant to a client. To get around this, you can do
local tool = script.Parent
local character = tool.Parent
local player = game.Players:GetPlayerFromCharacter(character) -- however, it seems that this variable is not being used currently
local humanoid = character:WaitForChild("Humanoid")
local Idle = humanoid:LoadAnimation(script.Idle)
Idle.Looped = true
local equipped
tool.Equipped:Connect(function(Player)
equipped = true
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end)
Ah my bad. I don’t think equipped connections work on server scripts. You will have to put your code into a local script and then send a server event to the server script. It would probably be easier to just run this whole script on a local script anyways, and then fire data to the server only when it is necessary
this involves two scripts and a remote event, but I think this is the easiest way to accomplish what you want.
-- in a local script:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AnimationEvent = game:GetService("") -- add a RemoteEvent into ReplicatedStorage and then enter its name into the quations
local localPlayer = Players.LocalPlayer
local character = Player.Character or Player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local Idle = humanoid:LoadAnimation(script.Idle)
Idle.Looped = true
local equipped
script.Parent.Equipped:Connect(function(Player)
equipped = true
AnimationEvent:FireServer()
end)
-- in a server script
AnimationEvent.OnServerEvent:Connect(function(Player)
local character = Player.Character
if character then
local humanoid = character:WaitForChild("Humanoid")
local Idle = humanoid:LoadAnimation(script.Idle)
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end
end)
Here’s the issue though:
The Character variable isn’t a Character. It’s possibly the players Backpack, or something else entirely.
You just need to do this:
local tool = script.Parent
local Character,Humanoid
local Idle
tool.Equipped:Connect(function()
-- tool.Parent only equals Player.Character when Equipped.
-- We do not need the Player object, since the Animation is all we are concerned with.
if Character and Character ~= tool.Parent then
Character = nil
Humanoid = nil
Idle:Destroy()
-- This cleans up old instances and clears variables if the tool is, for example, dropped to another person.
end
-- If we do not have an Idle Animation or a Character then we need to create Idle and set the Character.
if not Idle or not Character then
Character = tool.Parent
Humanoid = Character:FindFirstChildOfClass("Humanoid") -- Humanoid could always be renamed, unlikely but possible.
if Humanoid then -- Did we find a humanoid?
Idle = Humanoid:WaitForChild("Animator"):LoadAnimation(script.Idle) -- Load animation through the Humanoid's Animator. See why below.
Idle.Looped = true -- Set looped.
end
end
-- Do we have an Idle AnimationTrack?
if Idle then
-- If so, set the Priority and Play it.
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end
end)
tool.Unequipped:Connect(function()
-- Do we have an active Idle AnimationTrack?
if Idle then
-- If so, stop the animation.
Idle:Stop()
end
end)
Setting .Looped in a script is unlikely to work. Instead, set the animation to Looping in the Animation Editor before you export it for use.
Unfortunately this is the only reasonable way to go about this since AnimationTrack.Looped is quite iffy when modified by a script.
Edit to clarify:
The reason behind this is because the AnimationTrack does not take into account .Looped until it has loaded, and when it finishes loading, it sets the properties back to their exported values, so if you exported the animation with Looping disabled, it will set .Looped to false after roughly 6 seconds (Avg. load time)
Also, if you do not wish to export a new version of your Idle with Looping enabled, here’s a simple fix for it:
local tool = script.Parent
local Character,Humanoid
local Idle
local IdleLoop
tool.Equipped:Connect(function()
-- tool.Parent only equals Player.Character when Equipped.
-- We do not need the Player object, since the Animation is all we are concerned with.
if Character and Character ~= tool.Parent then
Character = nil
Humanoid = nil
Idle:Destroy()
if IdleLoop then
IdleLoop:Disconnect()
end
-- This cleans up old instances and clears variables if the tool is, for example, dropped to another person.
end
-- If we do not have an Idle Animation or a Character then we need to create Idle and set the Character.
if not Idle or not Character then
Character = tool.Parent
Humanoid = Character:FindFirstChildOfClass("Humanoid") -- Humanoid could always be renamed, unlikely but possible.
if Humanoid then -- Did we find a humanoid?
Idle = Humanoid:WaitForChild("Animator"):LoadAnimation(script.Idle) -- Load animation through the Humanoid's Animator. See why below.
-- Alternative to setting .Looped
IdleLoop = Idle.Stopped:Connect(function()
if tool.Parent == Character then
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end
end)
end
end
-- Do we have an Idle AnimationTrack?
if Idle then
-- If so, set the Priority and Play it.
Idle.Priority = Enum.AnimationPriority.Movement
Idle:Play()
end
end)
tool.Unequipped:Connect(function()
-- Do we have an active Idle AnimationTrack?
if Idle then
-- If so, stop the animation.
Idle:Stop()
end
end)