KeyframeSequance to Animation v4

Style now attempts to replicate AnimationTrack style
This module is letting you to play KeyframeAnimations in runtime dirrectly

Clear some confusions :question:

  • Yes it still supports EasingStyle
  • Yes its now supporting Skinned Mesh (Bone) animations aswell
  • Yes aswell supports R6 and R15
  • UNREPLICATABLE! You have to make own system to transport data and build class.

Bonefits :chart_with_upwards_trend:

  • Instead of mindlessly going from frame to frame this one is trying to simulate a animation timeline and is dynamic to timeline aswell as more user friendly
  • Have autofill for creating an animation class
  • Have speed multiplier that can be not only positive but also a negative for reversing animation
  • Have somewhat working animation blending
  • Have a sync system that would sync animation if you set its play in middle of timeline for example
  • have a public demo (yes real) it took me sometime to make
  • all other bonefits from previous module
  • Maybe better code?
  • Split into smaller components for readability
  • Plays both Motor6D and Bone (Skinned mesh) animations

Downsides :chart_with_downwards_trend:

  • bad optimization?
    Either for my bad scripting or for it being Luau compare to roblox animator using C++ we have that we have

Demo showcase :play_or_pause_button:

PublicDemo v2.3.rbxl (619.0 KB)

Note: all animations (exept for sitting one :]) are not my and i got them randomly either from toolbox or Roblox Cartoon Animation pack

Module :arrow_down_small:

image

Module :scroll:

API :star:

module.CreateModuleGroup(): ModuleScript
-- Module that can be passed into Group Parameter for Animation class
module.AutoGetMotor6D(Object:Model,Motor6DorBone:"Motor6D"|"Bone"): {}
-- Not important unless you want to manually pass it?
module.KeyFrameSequanceToTable(KeyFrameSequance:KeyframeSequence): {}
-- Not important it converts KeyFrameSequance into table that is used by module for animation.
module.new(Motor6DTable:Model|{},KeyFrameSequance:KeyframeSequence|{},AnimationGroup:ModuleScript?,Settings:SettingsType,Motor6DorBone:Motor6DorBones):AnimType
-- Animation Class itself
--[[
Parameters:
Motor6DTable -- Either Rig you making animation for or result of module.AutoGetMotor6D
KeyFrameSequance -- Either Keyframe sequance dirrectly or result of module.KeyFrameSequanceToTable

Optional Parameters [[
AnimationGroup -- result of module.CreateModuleGroup recomended if you want animations to not interupt each other put them in one group
]]
Settings: {} -- [[Custom Type where you can pass settings while creating animation]]
Motor6DorBone:"Motor6D"|"Bone"|nil
]]

Methods for animation :heavy_division_sign:

module:StopFading() -- stops fading and removes all data in class assosiated with it
module:Cancel(DontResetMotor6D:boolean):YourAnimationHere.Settings.CurrentlyAt -- if DontResetMotor6D true does not reset motor6D to original position
method fully stops animation and deletes its thread
module:Freeze():YourAnimationHere.Settings.CurrentlyAt -- does not stop animation thread but prevents it from playing if that makes sense
module:UnFreeze() -- opposite of module:Freeze() (resumes thread)
module:Destroy() -- you already know what this method does...
module:Stop(FadeTime:number) --similar to module:Freeze() but it triggers fading time if passed in while :Play() or passed in :Stop() itself DOES NOT DELETES THREAD
module:AdjustWeight:(weight: number,fadeTime: number)
module:Play(FadeTime:number,Weight:number,TimeStamp:number,Speed:number)
TimeStamp will trigger Settings["UpsyncThePlaying"] if possible
FadeTime will trigger if animation is not on loop
Plays animation itself

Events :zap:


Regular:

  • :zap:Ended - FULL STOP OF AN ANIMATION
  • :zap:Stopped - Animation Stopped but meight fade,use Ended if you want FULL STOP OF AN ANIMATION
  • :zap:DidLoop: true|false - animation with .Looped enabled commited a loop
    If animation is reversed then false otherwise true

.Event

  • self.Event:Connect(function(SygnalType: “MarkerSignal” | “KeyframeMarker”, Name: “string” ,Value: “string” | nil)

end)

  • KeyframeMarker will fire only for KeyframeMarker instances in timeline (User defined animation events) and will return Name of it and Value
  • MarkerSignal is an animation status related and NEVER RETURNS VALUE PARAMETER

Events for MarkerSignal

  • Canceled fires after method :Cancel() being applied
  • Frozen fires after method :Freeze() being applied
  • UnFrozen fires after method :UnFreeze() being applied
  • Play fires after method :Play() being applied

Settings :hammer:

  • self.Looped: boolean

  • self.TimePosition: number

  • self.IsPlaying: boolean

  • self.Speed: number

  • self.Weight: number

  • self.WeightCurrent: number

  • self.WeightTarget: number

  • self.Priority: Enum.AnimationPriority

  • self.Name: string

  • self.Animation: {}

  • self.Motor6D: {}

  • self.Settings: {
    [“StartsAt”]:number;
    [“CanTransformMotor6D”]:boolean|nil;–Don’t touch
    [“Animate”]:“Animate”|“First”|“Last”|nil
    [“UpsyncThePlaying”]:“Default”|“Ramp”|“SpeedUp”|nil;
    }

  • self.Length: number

  • self.Group: {}

Known issues

Module is not perfect but you can improve it :grinning:
Animation blending is very poorly made and i will be super happy if anyone will fix it and will post on devforum

6 Likes

Test place now using new movement system.
Animation delaying between loops is fixed aswell
New format for module

GetFinalPositionOfJointTime function is very crappy made if anyone takes this module seriously you need to update it.It is the main reason why module meight lag and well… will lag aswell it meight be the reason why blending breaks

1 Like

Wow, cool! Definitely like for the work done!!

[By the way, I also updated my module)]
(Animator plus | Custom, optimized animator - Resources / Community Resources - Developer Forum | Roblox)

I did a little analysis and here’s what I can say - first of all, low readability, in my opinion. Maybe it’s only because I don’t accept long scripts. It is not necessary to take it objectively, it is only a “subjective opinion”
next is the typing. Maybe I’m blind, but I didn’t find her, and that’s important. At the very least, if I were you, I would do a more thorough typing. And anyway, why does it say “-> nil” and not “-> ()” as in the animator from roblox?

Next, not a quibble, but just advice. Add --!optimization 2

Also add --!nocheck if you are not going to become the main typing rider, otherwise roblox thinks that something is wrong in your module:


Another quibble - in my opinion, using HTTPService for a unique ID is unnecessary.
image

The principle of unified responsibility has been violated
I think you should break the huge function :Play() into subfunctions

In this comment, I wrote only criticism, although of course there are also a lot of things to praise. Perhaps I missed a lot, because I literally “ran through” the code with my eyes. Don’t take this as unjustified criticism.

Another quibble - in my opinion, using HTTPService for a unique ID is unnecessary.
Bro where i should get unique id then? :joy:
I think you should break the huge function :Play() into subfunctions
What the point?

Yes, even through os.clock, lol, in any case, I think using HTTPService is unnecessary, if I were you, I wouldn’t use it. What is the point of splitting :Play() into sub functions? Well, firstly, readability, and secondly, the existence of SOLID.

so you dont understood code and judging it? wow :skull:

1 Like

Lol, what. What makes you think I didn’t figure out the code? Because I told you that the code is unreadable? You’re funny.

The problem with the “fat interface” in object-oriented programming (OOP) is that the interface (or abstract class) contains too many methods that can logically relate to different areas of responsibility.

Principles

The principle of KISS in programming is to choose the easiest way to complete a task. This principle recommends avoiding unnecessary complexity and striving for simplicity at all levels of development.

OCP (Open/Closed Principle — The principle of openness/closeness): It is difficult to extend the script without changing the existing code. Take a look at your code. It seems to me that if I add a couple of extra functions, in order for them to work, I will need to add separate logic to each existing self function

The dependency inversion principle (DIP) is a principle of object-oriented programming, the essence of which is that classes should depend on abstractions, not on specific details. For example, the CallEvent function. Yes, there’s no way to fix it, because you didn’t adhere to OTHER SOLID PRINCIPLES!

SRP (Single Responsibility Principle — The principle of sole responsibility). I won’t even comment on it.

Functions like TableLen can be optimized. Using the # operator is more efficient than iterating through a table. I hope you knew that, it’s really a shame.
image

image

1 Like

code is so bad becouse i were scripting it in between 0:00 to 3:00 hours at night xd so i didnt knew myself what am i doing plus its an unserious low effort project.I see you have passion towards creating animator on roblox for some reason well goodluck.
i dont remember why i made TableLen function even as far as i know for some reason table didnt returned ammount of arguments at all so i had to use that.
Well remember i were scripting it in half sleepy state :sweat_smile:

1 Like

I am very glad that you did not “run over” me in response, I understood you, I completely agree, when you are sleepy, you get porridge instead of a script. Anyway, the main thing is that the script works, lol.

And yes, I do not give up the words I wrote earlier, there are a lot of lines and complex logic in your code, this is a very difficult job, and even taking into account all the disadvantages, I think that you have written good code

1 Like