· 3 years ago · May 31, 2022, 01:00 PM
1---!strict
2
3local ExampleCode = [===[
4 -- Made by _Ben#2020 / 0x74_Dev / benthreadgold
5 -- EXAMPLE CODE BELOW
6
7 local AnimationController = require(game:GetService("ReplicatedStorage"):WaitForChild("AnimationController", 5));
8 local AnimationObject = AnimationController.new(<player>, <scope> optional but needed if you want to create multiple classes / objects on one instance!); -- Creates a new animation object / class
9 local TestAnimation = AnimationObject:Add({
10 ID = "rbxassetid://0", -- The animation ID
11 Name = "Test1", -- The name of your animation (can be anything but must be a string) this will be used for grabbing animations with the 'GetAnimation' (Function)
12 Type = "Walking" -- The type for your animation this is optional but lets say you used it... you could stop all animations with the same type using the 'StopAnimationType' (Function) useful for movement systems etc
13 });
14
15 TestAnimation:AddMarkerHit("Hit", function() -- The first parameter / arg is meant to be the name of your event within the animation so as soon as your animation hits that keyframe with the event it will fire and this function will listen for that and respond back to your function with it's data!
16 print("omg the hit event within my keyframe was fired!")
17 end)
18
19 TestAnimation:Finished(function() -- Adds your function into the animations finished queue, this will be called as soon as the animation finishes (does not get removed!)
20 print("Test animation finished playing!")
21 end)
22
23 TestAnimation:Play() -- Plays your animation
24 TestAnimation:Pause() -- Pauses the animation at it's current keyframe / position
25
26 task.delay(0.15, function()
27 TestAnimation:Resume() -- Unpauses the animation and continues from it's current position
28 end)
29
30 TestAnimation:Stop() -- Completely stops the animation and cannot be resumed you must replay it using the 'Play' (Function)
31
32 TestAnimation:Remove() -- Completely destroys the animation and it's contents and stops the animation (you must create a new animation after using this function!)
33
34 AnimationObject:Reload() -- Reloads all animations in this animation object, useful for when a player dies, prevents constant removing and adding new tables and instances, meaning you can just play the animation instantly without a problem!
35
36 for Index, Controller in ipairs(AnimationController.GetControllersForOperator(<player>)) do -- gets all the animation objects / controllers made by the player / instance provided in the first arg and returns them in an array!
37 Controller:Reload() -- Reload the animations within the controller / object!
38 end
39
40 local BeansController = AnimationController.GetController(<player>, <scope> optional) -- gets and returns the animation object / controller for that instance / player with the scope if it's included!
41
42 if BeansController ~= nil then
43 print("Found the beans controller!", BeansController)
44 end
45
46 local BowAnimationExist = AnimationObject:Exists("Shoot") -- Returns false if the animation name provided doesn't exist, if the animation name exists it will return true!
47
48 if BowAnimationExist == true then
49 local BowShootAnimation = AnimationObject:GetAnimation("Shoot") -- (First arg is the animation name!) Returns nil if the animation is not found else returns the animations object / class!
50
51 if BowShootAnimation ~= nil then
52 print("Found and got the bow shoot animation object!")
53 BowShootAnimation:Play() -- Play the bow shoot animation!
54 end
55
56 print("Yay the shooting animation for the bow exists!")
57 end
58
59 AnimationObject:StopAnimationType("Walking") -- Stops all animations with the 'Walking' Type, Type cannot be empty or nil else will return a warning... Animation type can be set when using the 'Add' (Function) see example above
60 AnimationObject:StopAll() -- Stops all playing animations within the object!
61
62 AnimationObject:Destroy() -- Completely destroys all animations within the object and destroys the object along with it (This renders all functions in the object useless and will cause a error, you must create a new object after using this function!)
63]===]
64
65local AnimationFunctions = {}
66local AnimationEndTrackFunctions = {}
67local AnimationController = {
68 LoadPosition = 0
69}
70AnimationController.__index = AnimationController
71AnimationFunctions.__index = AnimationFunctions
72AnimationEndTrackFunctions.__index = AnimationEndTrackFunctions
73
74local Controllers = getmetatable(newproxy(true))
75
76local function GetCharacter(Player : Instance)
77 local _S, _F = pcall(function()
78 Player = Player.Character
79 end)
80 return Player
81end
82
83function AnimationController.GetControllerWithScope(Operator : Instance, scope : string)
84 for _, ControllerData in pairs(Controllers) do
85 local ControllerOperator = type(ControllerData) == "table" and ControllerData.Operator
86
87 if ControllerOperator == Operator then
88 return ControllerData
89 end
90 end
91
92 return nil
93end
94
95function AnimationController.new(Operator : Instance, Options : any)
96 Options = type(Options) == "table" and Options or {}
97 Options.scope = type(Options.scope) == "string" and Options.scope or ""
98
99 local CurrentController = AnimationController.GetControllerWithScope(Operator, Options.scope)
100
101 if CurrentController ~= nil then return CurrentController end
102
103 local self = setmetatable({}, AnimationController)
104 self.Operator = Operator
105 self.Animations = {}
106 self.scope = Options.scope
107
108 Controllers[Operator] = self
109
110 return self
111end
112
113function AnimationController.GetControllersForOperator(Operator : Instance)
114 local ControllerResults = {}
115
116 for ControllerOperator, ControllerData in pairs(Controllers) do
117 if ControllerOperator == Operator then
118 table.insert(ControllerResults, ControllerData)
119 end
120 end
121
122 return ControllerResults
123end
124
125function AnimationController.ReloadAllControllers(Operator : Instance)
126 local Results = AnimationController.GetControllersForOperator(Operator)
127
128 if #Results > 0 then
129 for _, AnimationObject in ipairs(Results) do
130 AnimationObject:Reload()
131 end
132 end
133end
134
135function AnimationController.GetController(Operator : Instance, scope : any)
136 scope = type(scope) == "string" and scope or ""
137
138 return Operator ~= nil and AnimationController.GetControllerWithScope(Operator, scope) or nil
139end
140
141-----------------------------------------
142-- Animation functions (None Controller)
143function AnimationFunctions:AddMarkerHit(MarkerName : string, Func : any, ...)
144 -- Start here
145 local Controller = AnimationController.GetController(self.Operator, self.scope)
146
147 if Controller ~= nil then
148 self.Markers[MarkerName] = {Function = Func, Args = {...}}
149 else
150 return warn("Animation controller doesn't exist")
151 end
152
153 return self
154end
155
156function AnimationFunctions:Stopped(Func : any, ...)
157 local Controller = AnimationController.GetController(self.Operator, self.scope)
158
159 if Controller ~= nil then
160 if self.StoppedFunctions ~= nil then
161 self.StoppedFunctions[#self.StoppedFunctions + 1] = {Function = Func, Args = {...}}
162 end
163 else
164 return warn("Animation controller doesn't exist")
165 end
166
167 return self
168end
169
170function AnimationFunctions:Finished(Func : any, ...)
171 local Controller = AnimationController.GetController(self.Operator, self.scope)
172
173 if Controller ~= nil then
174 if self.FinishedQueue ~= nil then
175 self.FinishedQueue[#self.FinishedQueue + 1] = {Function = Func, Args = {...}}
176 end
177 else
178 return warn("Animation controller doesn't exist")
179 end
180
181 return self
182end
183
184function AnimationFunctions:Play()
185 local Controller = AnimationController.GetController(self.Operator, self.scope)
186
187 if Controller ~= nil then
188 if self.AnimationInstance ~= nil then
189 if not self.AnimationInstance.IsPlaying then
190 self:DestroySignals()
191
192 table.insert(self.Signals, self.AnimationInstance.Changed:Connect(function()
193 if not self.AnimationInstance.IsPlaying then
194 for _, FuncData in ipairs(self.FinishedQueue) do
195 if type(FuncData) == "table" then
196 if type(FuncData.Function) == "function" then
197 pcall(FuncData.Function, unpack(FuncData.Args))
198 end
199 end
200 end
201 end
202 end))
203
204 for Index, Value in pairs(self.Markers) do
205 Index = tostring(Index)
206
207 if type(Value) == "table" and self.Signals[Index] == nil then
208 self.Signals[Index] = self.AnimationInstance:GetMarkerReachedSignal(Index):Connect(function(...)
209 for MarkerName, _ in pairs(self.Markers) do
210 if tostring(MarkerName) == Index then
211 return Value.Function(unpack(Value.Args), ...)
212 end
213 end
214 end)
215 end
216 end
217
218 self.AnimationInstance:Play()
219 end
220 end
221 else
222 return warn("Animation controller doesn't exist")
223 end
224
225 return self
226end
227
228function AnimationFunctions:SetSpeed(NewSpeed : number)
229 local Controller = AnimationController.GetController(self.Operator, self.scope)
230 if Controller ~= nil then
231 if self.AnimationInstance ~= nil then
232 NewSpeed = type(NewSpeed) == "number" and NewSpeed or self.AnimationInstance.Speed
233
234 self.AnimationInstance:AdjustSpeed(NewSpeed)
235 end
236 else
237 return warn("Animation controller doesn't exist")
238 end
239 return self
240end
241
242function AnimationFunctions:GetOriginalSpeed()
243 local Controller = AnimationController.GetController(self.Operator, self.scope)
244 if Controller ~= nil then
245 if self.AnimationInstance ~= nil then
246 return self.NormalAnimationSpeed or 0
247 end
248 else
249 return 0, warn("Animation controller doesn't exist")
250 end
251 return 0
252end
253
254function AnimationFunctions:Stop()
255 local Controller = AnimationController.GetController(self.Operator, self.scope)
256 if Controller ~= nil then
257 self:DestroySignals()
258
259 if self.AnimationInstance ~= nil then
260 self.AnimationInstance:Stop()
261
262 for _, FuncData in ipairs(self.StoppedFunctions) do
263 if type(FuncData) == "table" then
264 if type(FuncData.Function) == "function" then
265 FuncData.Function(unpack(FuncData.Args))
266 end
267 end
268 end
269 end
270 else
271 return warn("Animation controller doesn't exist")
272 end
273 return self
274end
275
276function AnimationFunctions:Pause()
277 local Controller = AnimationController.GetController(self.Operator, self.scope)
278 if Controller ~= nil then
279 if self.OldAnimationSpeed == nil then
280 self.OldAnimationSpeed = self.AnimationInstance.Speed
281 end
282
283 self.AnimationInstance:AdjustSpeed(0)
284 else
285 return warn("Animation controller doesn't exist")
286 end
287 return self
288end
289
290function AnimationFunctions:Resume()
291 local Controller = AnimationController.GetController(self.Operator, self.scope)
292 if Controller ~= nil then
293 if self.OldAnimationSpeed ~= nil then
294 self.AnimationInstance:AdjustSpeed(self.OldAnimationSpeed)
295 self.OldAnimationSpeed = nil
296 end
297 else
298 return warn("Animation controller doesn't exist")
299 end
300 return self
301end
302
303function AnimationFunctions:Remove()
304 local Controller = AnimationController.GetController(self.Operator, self.scope)
305
306 if Controller ~= nil then
307 if self.AnimationName ~= nil then
308 self:DestroySignals()
309 self:Stop()
310
311 table.clear(self.FinishedQueue)
312 table.clear(self.StoppedFunctions)
313 table.clear(self.Signals)
314 table.clear(self.Markers)
315
316 for AnimationIndex, AnimationData_ in ipairs(Controller.Animations) do
317 if AnimationData_.Type == self.Type and AnimationData_.AnimationName == self.AnimationName then
318 table.remove(Controller.Animations, AnimationIndex)
319 end
320 end
321
322 table.clear(self)
323 end
324 else
325 return warn("Animation controller doesn't exist")
326 end
327
328 return Controller
329end
330
331function AnimationFunctions:DestroySignals()
332 if type(self.Signals) == "table" then
333 for I, V in pairs(self.Signals) do
334 if typeof(V) == "RBXScriptConnection" then
335 V:Disconnect()
336 end
337 end
338
339 table.clear(self.Signals)
340 end
341end
342-------------------------------------------
343-- Animation functions (Controller)
344function AnimationController:Exists(Name : string, Options : any)
345 local Controller = AnimationController.GetController(self.Operator, self.scope)
346
347 if Controller ~= nil then
348 local Animation = self:GetAnimation(Name, Options)
349
350 if Animation ~= nil then
351 return true
352 end
353 else
354 return false, warn("Animation controller doesn't exist")
355 end
356
357 return false
358end
359
360function AnimationController:GetAnimation(Name : string, Options : any)
361 Options = type(Options) == "table" and Options or {}
362 Options.Type = type(Options.Type) == "string" and Options.Type or ""
363
364 local Controller = AnimationController.GetController(self.Operator, self.scope)
365
366 if Controller ~= nil then
367 for _, Animation in ipairs(self.Animations) do
368 if Animation.AnimationName == Name then
369 if Options.Type ~= "" then
370 if Options.Type == Animation.Type then
371 return Animation
372 end
373 else
374 return Animation
375 end
376 end
377 end
378 else
379 return nil, warn("Animation controller doesn't exist")
380 end
381
382 return nil
383end
384
385function AnimationController:StopAll()
386 local Controller = AnimationController.GetController(self.Operator, self.scope)
387
388 if Controller ~= nil then
389 for _, Animation in ipairs(self.Animations) do
390 if Animation.AnimationInstance ~= nil then
391 Animation:DestroySignals()
392 Animation:Stop()
393 end
394 end
395 else
396 return warn("Animation controller doesn't exist")
397 end
398end
399
400function AnimationController:StopAnimationType(Type : string, Blacklist : any)
401 if Type == nil or #tostring(Type) <= 0 then return warn("<Type> cannot be empty nor nil!") end
402 local Controller = AnimationController.GetController(self.Operator, self.scope)
403 if Controller ~= nil then
404 Blacklist = type(Blacklist) == "table" and Blacklist or {}
405
406 for _, Animation in ipairs(self.Animations) do
407 if type(Animation) == "table" then
408 if Animation.Type == tostring(Type) then
409 if not table.find(Blacklist, Animation) then
410 Animation:DestroySignals()
411 Animation:Stop()
412 end
413 end
414 end
415 end
416 else
417 return warn("Animation controller doesn't exist")
418 end
419end
420
421function AnimationController:Reload()
422 local Controller = AnimationController.GetController(self.Operator, self.scope)
423 if Controller ~= nil then
424 local Character = GetCharacter(self.Operator)
425 local Humanoid = Character ~= nil and Character:FindFirstChild("Humanoid") or nil
426
427 if Humanoid ~= nil then
428 for _, Animation in ipairs(self.Animations) do
429 if type(Animation) == "table" then
430 Animation:Stop()
431 Animation:DestroySignals()
432
433 local ANI_OBJ = Instance.new("Animation", nil)
434 ANI_OBJ.AnimationId = Animation.AnimationId
435
436 local Loaded = Humanoid:LoadAnimation(ANI_OBJ)
437
438 rawset(Animation, "NormalAnimationSpeed", Loaded.Speed)
439 rawset(Animation, "AnimationInstance", Loaded)
440
441 ANI_OBJ:Destroy()
442 end
443 end
444 end
445 else
446 return warn("Animation controller doesn't exist")
447 end
448end
449
450function AnimationController:Destroy()
451 for _, Animation in ipairs(type(self.Animations) == "table" and self.Animations or {}) do
452 Animation:DestroySignals()
453 Animation:Remove()
454 end
455
456 table.clear(type(self.Animations) == "table" and self.Animations or {})
457 --Controllers[tostring(self.Operator) .. "+" .. self.scope] = nil -- Fix code here
458 table.clear(self)
459end
460
461function AnimationController:Add(AnimationData : table)
462 local Controller = AnimationController.GetController(self.Operator, self.scope)
463 if Controller ~= nil then
464 AnimationData = type(AnimationData) == "table" and AnimationData or {}
465 AnimationData.Type = type(AnimationData.Type) == "string" and AnimationData.Type or ""
466
467 if not self:Exists(AnimationData.Name or "", AnimationData) then
468 if self.Operator ~= nil and AnimationData.Name ~= nil then
469 local Character = GetCharacter(self.Operator)
470 local Humanoid = Character ~= nil and Character:FindFirstChild("Humanoid") or nil
471 local _self = setmetatable({}, AnimationFunctions)
472
473 _self.scope = self.scope
474 _self.Operator = self.Operator
475 _self.AnimationName = AnimationData.Name
476 _self.AnimationId = AnimationData.ID
477 _self.FinishedQueue = {}
478 _self.StoppedFunctions = {}
479 _self.Signals = {}
480 _self.Markers = {}
481 _self.Type = AnimationData.Type
482
483 if Humanoid ~= nil then
484 local ANI_OBJ = Instance.new("Animation", nil)
485 ANI_OBJ.AnimationId = AnimationData.ID
486
487 local Loaded = Humanoid:LoadAnimation(ANI_OBJ)
488
489 _self.NormalAnimationSpeed = Loaded.Speed
490
491 _self.AnimationInstance = Loaded
492
493 ANI_OBJ:Destroy()
494 end
495
496 table.insert(self.Animations, _self)
497
498 return _self
499 end
500 else
501 return self:GetAnimation(self.Animations, AnimationData)
502 end
503 else
504 return warn("Animation controller doesn't exist")
505 end
506end
507-----------------------------------------
508
509return AnimationController