I’d like to improve this code line wise, performance too if there happens to be any.
I’m not exactly sure how to optimize this as my scripts usually don’t pass 200 lines, I also don’t mess with animation things often.
Code:
local Animate = { }
-- services --
local Player = game:GetService("Players").LocalPlayer
-- consts --
local Settings = {
AnimationInterval = .1,
}
local settings = Settings
local Data = shared.Animations
if Data == nil then
repeat
task.wait()
Data = shared.Animations
until Data ~= nil
end
if shared.AnimationDefault == nil then
shared.AnimationDefault = Data
end
--
local Character = Player.Character
if Character == nil then
repeat
task.wait()
Character = Player.Character
until Character ~= nil
end
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:FindFirstChildOfClass("Animator")
local New = { }
local function CycleTable(name, tbl)
New[name] = { }
local Main = New[name]
for k, Obj in pairs(tbl) do
if typeof(Obj) == "table" then
CycleTable(Obj)
elseif Obj.ClassName == "Animation" then
local Animation = Obj
Obj:Destroy()
repeat
task.wait()
Animation = Animator:LoadAnimation(Animation)
until Animation:IsA("AnimationTrack")
Main[k] = Animation
end
end
end
for k, Obj in pairs(Data) do
if typeof(Obj) == "table" then
CycleTable(k, Obj)
end
end
Data = New
--
if not shared.Weapon then
repeat
task.wait()
until shared.Weapon
end
--
local Equipped = shared.Equipped
local Sprinting = shared.Sprinting
-- variables --
local Jumping = false
local JumpDebounce = false
local ActiveAnimation = ""
local LastAnimation = ""
local Whitelist = {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"Dequip",
"Equip",
"Block",
"Stance",
}
-- functions --
local function Cycle1(Data, Force)
for k, animation in pairs(Data) do
if Player.Character == nil then
return
end
local humanoid = Player.Character:FindFirstChild("Humanoid")
if humanoid then
if humanoid.Health == 0 or humanoid:GetState() == Enum.HumanoidStateType.Dead then
return
end
end
if table.find(Whitelist, k) and not Force then
continue
end
if typeof(animation) == "table" then
Cycle1(animation)
continue
end
if animation ~= nil then
animation:Stop( settings.animationInterval )
end
end
end
function Animate.EndCustoms (Force)
for k, animation in pairs(Data) do
if Player.Character == nil then
return
end
local humanoid = Player.Character:FindFirstChild("Humanoid")
if humanoid then
if humanoid.Health == 0 or humanoid:GetState() == Enum.HumanoidStateType.Dead then
return
end
end
if table.find(Whitelist, k) and not Force then
continue
end
if typeof(animation) == "table" then
Cycle1(animation)
continue
end
if animation ~= nil then
animation:Stop( settings.animationInterval )
end
end
end
function Animate.LoadAnimation (AnimationID : number)
local humanoid = if Player.Character ~= nil then Player.Character:WaitForChild("Humanoid") else nil
local Animator = if humanoid then humanoid:WaitForChild "Animator" else nil
if Animator then
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://"..AnimationID
local Finished = Animator:LoadAnimation(Animation)
Animation:Destroy()
return Finished
else
return nil
end
end
--[[
TODO: Detect when sword is equipped, remove default idle and play that one instead.
]]
local function ReturnAnimation(Weapon, Anim)
local Animation = nil
if Data[Weapon.Name] then
if Anim == "Attack" then
Animation = Data[Weapon.Name][tostring(shared.Combo.Value)]
else
Animation = Data[Weapon.Name][Anim]
end
end
if not Animation then
Animation = Data["Default"][Anim]
end
return Animation
end
Animate.GetAnimation = ReturnAnimation
function Animate.Update (ws)
local Character = Player.Character
if not Character then return end
local Weapon = shared.Weapon.Value
if Weapon == nil then return end
if not Jumping then
if ws >= .1 and not Sprinting.Value and ActiveAnimation ~= "Walk" then
ActiveAnimation = "Walk"
LastAnimation = ActiveAnimation
Animate.EndCustoms( )
Data.Default.Walk:Play( settings.AnimationInterval )
return
end
if ws < .1 and ActiveAnimation ~= "Idle" then
ActiveAnimation = "Idle"
LastAnimation = ActiveAnimation
Animate.EndCustoms( )
local anim
if shared.Equipped.Value then
anim = Animate.GetAnimation(shared.Weapon.Value, "Idle")
else
anim = Data.Default.Idle
end
anim:Play( settings.AnimationInterval )
return
end
if ws >= .1 and Sprinting.Value and ActiveAnimation ~= "Sprint" then
ActiveAnimation = "Sprint"
LastAnimation = ActiveAnimation
Animate.EndCustoms( )
Data.Default.Sprint:Play( settings.AnimationInterval )
return
end
end
end
function Animate.Jump (jumping)
local Character = Player.Character
if not Character then return end
local Humanoid = Character:WaitForChild("Humanoid")
if not JumpDebounce then
if jumping then
JumpDebounce = false
Jumping = true
ActiveAnimation = "Jump"
Animate.EndCustoms( )
Data.Default.Jump:Play( settings.AnimationInterval )
task.wait( .480 )
JumpDebounce = false
Data.Default.Land:Play( settings.AnimationInterval )
task.wait( Data.Default.Land.Length )
Jumping = false
Data.Default.Jump:Stop( settings.AnimationInterval )
if Humanoid.MoveDirection.Magnitude > 0 then
Animate.Update(1)
else
Animate.Update(0)
end
end
end
end
function Animate.Reload()
Data = shared.AnimationDefault
--
local Character = Player.Character
if Character == nil then
repeat
task.wait()
Character = Player.Character
until Character ~= nil
end
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:FindFirstChildOfClass("Animator")
local New = { }
local function CycleTable(name, tbl)
New[name] = { }
local Main = New[name]
for k, Obj in pairs(tbl) do
if typeof(Obj) == "table" then
CycleTable(Obj)
elseif Obj.ClassName == "Animation" then
local Animation = Obj
Obj:Destroy()
repeat
task.wait()
Animation = Animator:LoadAnimation(Animation)
until Animation:IsA("AnimationTrack")
Main[k] = Animation
end
end
end
for k, Obj in pairs(Data) do
if typeof(Obj) == "table" then
CycleTable(k, Obj)
end
end
Data = New
Data.Default.Idle:Play()
end
-- extra --
if not shared.AnimateExecuted then
shared.AnimateExecuted = true
shared.Equipped:GetPropertyChangedSignal("Value"):Connect(function ()
if ActiveAnimation == "Idle" then
ActiveAnimation = ""
Animate.Update(0)
end
end)
end
return Animate
Please let me know how I can improve, thank you for reading this!