Have you ever tried to load an animation made by someone else and been frustrated to find that LoadAnimation won’t let you do it? Have you ever had to re-upload someone else’s animations to get them working in your game? I sure have, and it’s an experience quite a few of us share.
Today I want to alleviate this burden for developers. I have rewritten LoadAnimation and the underlying animation system from scratch, without the limitation preventing developers from loading untrusted animations.
The intention is to allow developers to create portable systems that can be easily imported into any game without needing to re-upload KeyframeSequences. The module works as a drop-in replacement for LoadAnimation calls.
Examples
Normal LoadAnimation
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://182436842"
local Humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local Animator = Humanoid:FindFirstChildWhichIsA("Animator") or Instance.new("Animator",Humanoid)
Animator:LoadAnimation(Animation):Play() -- errors if animation isn't created by game owner
Custom LoadAnimation
local LoadAnimation = require(17382720234).LoadAnimation -- you can take a local copy if you don't like ID requires
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://182436842"
local Humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local Animator = Humanoid:FindFirstChildWhichIsA("Animator") or Instance.new("Animator",Humanoid)
LoadAnimation(Animator,Animation):Play() -- LoadAnimation can still error if there's server issues; consider a pcall!
-- you can call LoadAnimation on the client and it will replicate if the client owns the Animator, like normal LoadAnimation
Custom LoadAnimation on Client
-- !!! The module must be loaded on the server first or this will not work.
local LoadAnimtion = require(game:FindService("ReplicatedStorage"):FindFirstChild("ReplicatedAnimation")).LoadAnimation
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://182436842"
local Character = game:FindService("Players").LocalPlayer.Character
local Humanoid = Character:FindFirstChildWhichIsA("Humanoid")
local Animator = Humanoid:FindFirstChildWhichIsA("Animator")
LoadAnimation(Animator,Animation):Play() -- replicates to server automatically
Features
What this module can do:
- Automatic replication + StreamingEnabled compatible; no jitter
- Matches AnimationTrack API; drop-in replacement
- AnimationController support
What this module cannot do:
- LoadAnimation only works on Animators (calling it on Humanoids and AnimationControllers has been deprecated for a long time anyway)
- No CurveAnimation support (yet)
- Some AnimationTrack API members are still missing
- Fade-in/fade-out not working… soon™!
Notes
This system is inherently insecure. There is no animation “whitelist”, which means an exploiter could load and run any animation they want on an Animator that they have network ownership of. If you want, you can use the API exposed through the module to perform your own security checks (ReplicatedAnimation.Created
event).
I uploaded this as a MainModule so that you can load it via require(ID)
(see the example). This has the benefit of you receiving bug fixes automatically. If you don’t like this, you are welcome to create a local copy. Please make sure you are using the latest version before reporting an issue.
I have not extensively tested this system. There are almost certainly bugs. Please let me know if you find any and I’ll do my best to fix them. I don’t recommend using this in production yet, but you are welcome to do so if you feel daring.
Finally, please note that the code is a mess and could use some serious optimisation. This is intended for projects such as weapon systems that need portable animations. You should definitely use the default animation system if you can. You will likely run into performance issues if you try to run all of your game’s animations through this system. Please consider supporting the Public Animations feature request.
I hope you find this resource useful. Please leave any feedback below.
-Cinnamon