OOP NPC Animate Module
This post is to host a download for a module of mine to help with NPC animation that goes along with a tutorial series I'm working on. The download can be found below for those who need it.
Note that this module is intended for usage alongside the BLU Framework. It likely wont work as intended without moderate modification otherwise.
Series Link
Documentation
Click here to expand documentation
Introduction
This open source module is built to run with my framework, known as the BLU framework.
The purpose of this module is to create one central system for animations of any R6 or R15 humanoid. This can be used for player characters, but it can also be used for animating NPCs as well, as long as they have either the R6 or R15 body types.
Key Features
- Ability to use the same animation script for both player characters and NPC characters.
- Ability to create custom animation packs stored in sub-modules to modify the default animations.
- Ability to add new animation types (i.e. a "land" animation, or a "sprint" animation) on top of the default animations/state types.
- Ability to layer animation packs on top of one another for a variety of effects. For example, you might layer animation pack 1 with higher priority than animation pack 2, and thus, when searching for a specific animation to play, this module will first look to animation pack 1. If pack 1 has the animation in question, it will play it, otherwise it will look to pack 2, and play it there instead.
Animation Packs
Animation packs exist as modules stored as descendants of this module (Animate). Their location actually doesn't matter, thanks to how the BLU framework removes the need to specify path (but instead just requires modules by their names), so you can feel free to organize animation pack modules however you please.
Reference the "AnimationPack_Default" for how your animation packs should be set up. There are a few default animations included in animation packs (as seen in AnimationPack_Default), but you can also add your own animations, which can be accessed and utilized using the methods of the Animate module.
Animation Pack Names
All animation packs within the Animate module must start with the string "AnimationPack_". After that, you're welcome to put whatever additional strings you want, separating key terms by underscores. For example, if you had several classes of melee with different animations (maybe boxing, taekwondo, capoeira, etc.), you could name your animation packs like so:
- "AnimationPack_Melee_Boxing"
- "AnimationPack_Melee_Taekwondo"
- And so forth.
Referencing Animation Packs
Example animatePath arguments:
- "Default" -- references "AnimationPack_Default"
- "Melee.Boxing" -- references "AnimationPack_Melee_Boxing"
Animation Layers
So each Animate object can have a series of "layers" of animations. By default, the Animate object is initialized with a "base layer" that cannot be changed or removed and is stored separately from the other layers. When loading a new layer with Animate:LoadLayer(), this base layer is used as a check to make sure any animations on the new layer have names/keys that match the animations on the base layer.
When the Animate module tries to play a particular animation, such as the running animation or the jumping animation, respectively at their appropriate playing times, it will reference the highest layer that it can find those animations at. See Animate:GetAnimations() for more information about this process
The primary benefit of this is seen in the static Animate.SwitchAnimate() method, which utilizes the AnimationPacks. You can specify an AnimationPack to "switch" to, which effectively adds a new animation layer to that Animate object, returning a function that can be called at any point to remove that layer. This effectively overrides any animations that are present in the new AnimationPack over any animations in AnimationPack_Default, and then when you run the "unLoad" function, it will remove that layer, returning back to the AnimationPack_Default animations.
Another major benefit to this strategy is that you can layer multiple animation packs on top of one another. Say you equip your boxing stance, and so you layer on AnimationPack_Melee_Boxing. Then, with boxing equipped, you then equip your lightning abilities, and so you layer on AnimationPack_Abilities_Lightning to change animations according to that. Now you can effectively unequip the boxing stance and be left with the lightning animations, unequip the lightning ability and be left with the boxing stance, or unequip both and be left with the default animations.
Animate Properties
Animate.Player
This property is set to the player associated with the character model provided in Animate.new(), if there is one. Otherwise, it remains nil.
Animate.Character
This property is set to the character model associated with the Animate instance.
Animate.Janitor
This property is set to a new instance of my Janitor module, used to clean up loose memory and data in Animate:Destroy().
Animate.BaseAnimations
This is a table, structured as {[string]: AnimationTrack}, used internally to store the base animations, below all additional animation layers. These animations default to what is in the AnimationPack_Default module. See "Animation Layers" and "Animation Packs" sections for more information.
Animate.AnimationLayers
This is a table of all of the currently active animation layers on the Animate object. See the "Animation Layers" section for more information. It exists in the format of an array of dictionaries structured as {[string]: AnimationTrack}. Values at higher indices represent higher layer animations that will have higher priority over the lower ones when playing.
Animate.OverlayAnimations
This is a table that is used internally, primarily for the Animate.PlayAnimation() method. It is used to temporarily make a particular animation have a higher AnimationTrack.Priority property, and then to lower that priority back down to Enum.AnimationPriority.Core after the animation completes.
Static Methods
These are the functions that are intended to be ran on the module itself, rather than an instance of the class this module produces.
Animate:__CharacterAdded(char: Model, hum: Humanoid, root: BasePart)
This is a method only intended for use internally with the BLU Framework (see 'introduction'). Commenting out this entire method will disable automatically replacing the default "Animate" script for players with this system.
Animate:__CharacterDied(char: Model)
This is a method only intended for use internally with the BLU Framework (see 'introduction'). If you choose to comment out the :__CharacterAdded() method, you may want to comment this one out as well.
Animate.SwitchAnimate(char: Model, animatePath: string): () -> ()
Use this method to switch between different animation packs by specifying the path string to the path in question. See 'Animation Packs' for more information.
Animate.PlayAnimation(char: Model, animName: string, ...)
This method uses the :GetAnimations() method on the character models "Animate" instance to get the highest-level animation of the particular name animName. It then plays that animation, providing the tuple (...) as the arguments into AnimationTrack:Play(). This function returns the AnimationTrack object that it plays.
Animate.GetAnimationTrack(char: Model, animName: string)
This method uses the Animate:GetAnimations() method to get the highest-level AnimationTrack object for the provided animName. It then returns this AnimationTrack.
Animate.new(char: Model)
The instantiation function of the Animate module. It creates and returns a new Animate instance for the character model provided. The Animate module keeps in memory a map of character models to Animate objects, using the Animate.AllAnimates table. After instantiating an Animate object, it also runs the Animate:StartStateTracking() method, which begins tracking states to play animations automatically.
Object Methods
Animate:LoadLayer(animations: {[string]: string}, layerName: string?)
This function takes in a dictionary of animation names paired with animation IDs to add a new "layer" to the Animate object. Reference "Animation Layers" above.
Animate:LoadAnimations(animations: {[string]: string}?, insertTable: {[string]: AnimationTrack}?, janitor: {}?, namePrefix: string?)
This is a method that is primarily used internally, but can be used manually as well. It is ran upon instantiating a new Animate object to load the default animations into the Animate.BaseAnimations property. You can additionally load animations into other tables as well.
Animate:ClearLayers()
This method clears all current animation layers. Reference "Animation Layers" above for more details.
Animate:GetAnimations(): ({[string]: AnimationTrack})
This method looks through all animation layers (from last to first) in the Animate object and fills up a new table of animations, following the format in this methods return value. If there is a base animation key that was not found in a higher layer, the module adds that base animation to the return table as well. Overall, this method returns a table of all of the highest-level animations currently on the Animate object.
Animate:StartStateTracking()
This is a function that is run one time upon instantiating a new Animate object, and is only intended for use internally.
Animate:UpdateState()
This is another method intended only for internal use. It's used to update the current state of the character model, adjusting the currently playing animations as appropriate using Animate:ChangeAnimation().
Animate:ChangeAnimation(newAnim: string, ...)
This method is intended only for internal use. It is ran internally to change the currently playing animation based on this module's state tracking methods.
Animate:Destroy()
Rather self explanatory. This method removes all data and internal references to the animate object, as well as destroying all animation-related instances, such as Animation and AnimationTrack instances. Use this method when you are done using an Animate object (such as if an NPC with the Animate instance associated dies) and wish to clear it from the memory.
Download
Animate.rbxm (5.0 KB)