Skip to content

A library that adds blending to the start and end of Figura animations for smoother transitions.

License

Notifications You must be signed in to change notification settings

GrandpaScout/GSAnimBlend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

❰GSAnimBlend❱ Animation Blending

This library adds blending to the start and end of Figura animations to create smoother transitions.

 

Installation

To install this library:

  • Download this repository by pressing the big <> Code button and clicking Download ZIP.
  • Open the .zip file it gives you and open the script folder
  • Pick the version of this library you want to use, open it, and put the GSAnimBlend.lua file in your avatar.

 

Simple Usage

To use the basic features of this library, simply require it.

require("GSAnimBlend")

Once you have required the library, simply use the :setBlendTime() method to change how long the blending is on an animation. This method expects one or two times in ticks. (1/20ths of a second.)
The default value is 0 so you have to use this method if you want an animation to blend.

animations.MyModel.MyAnimation:setBlendTime(5)     -- Blending in/out set to the same time
animations.MyModel.MyAnimation:setBlendTime(5, 10) -- Blending in/out set to different times.

You can also change how blending happens with the :setBlendCurve() method.

animations.MyModel.MyAnimation:setBlendCurve("linear")
animations.MyModel.MyAnimation:setBlendCurve("easeInSine")
animations.MyModel.MyAnimation:setBlendCurve("easeOutBack")
animations.MyModel.MyAnimation:setBlendCurve("easeInOutCubic")
animations.MyModel.MyAnimation:setBlendCurve("smoothstep")

 

Advanced Usage

To use more advanced features of the library, require it to a variable.

local GSBlend = require("GSAnimBlend")

 

Blending Curves

Blending curves allow you to change the "velocity" of a blend by using different easings.

Blending curves are defined by a function that takes in the blending progress of a blend as a number 0-1 and outputs a modified blending progress of that blend as any finite number. While the output number can be any finite number, it is recommended to return 0 when the input is 0 and 1 when the input is 1 to keep things smooth.

GSAnimBlend stores all of its premade blending curves in GSBlend.curve.

By default, all animations use the linear curve as described by this function:

local function linear(x)
  return x
end

An example curve that blends in, out, then back in again.

local function wave(x)
  return (math.cos(x * math.pi * 3) - 1) / -2
end

 

Blending Callbacks

Blending callbacks allow you to change what happens while an animtion is blending.
The default blending callback simply applies the blend weights of the blend to the blending animation and nothing else.

GSAnimBlend stores all of its premade blending curves in GSBlend.callback.

By default, all animations will use this blending callback:

local animBlend = GSBlend.oldF.blend

local function base(state, data)
  animBlend(state.anim, math.lerp(state.from, state.to, state.progress))
end

Blending callbacks need access to the default Figura implementations of Animation methods to work properly, which GSAnimBlend provides at GSBlend.oldF.

Tip

You can explore GSAnimBlend's library table with Figura's built in repl command.

/figura run GSBlend = require("GSAnimBlend")
/figura run printTable(GSBlend)
/figura run printTable(GSBlend.oldF)

state is an object that contains information that is immediately useful to blending callbacks. It is updated every frame before the blending callback is run.
While this object is not read-only, it is not recommended to change anything in the state unless you know what you are doing.

interface CallbackState {
  anim: Animation     // The animation that is blending.
  time: number        // How long the blend has been running.
  max: number         // The max time this blend will run for.
  progress: number    // The modified progress as a percentage. (See Blending Curves.)
  rawProgress: number // The progress as a raw percentage.
  from: number        // The starting blend weight.
  to: number          // The ending blend weight.
  starting: boolean   // Whether this blend is starting or stopping the animation.
  done: boolean       // If this is true, the blend is finished, do cleanup.
}

data is an object that contains more internal information about the animation itself such as its current blending curve or its current overrall blending state.

interface AnimData {
  blendTimeIn: number    // How long a blend-in lasts.
  blendTimeOut: number   // How long a blend-out lasts.
  blend: number          // The faked blend weight of this animation.
  blendSane: number      // The preferred blend weight of this animation.
  length: number | false // The length of this animation. False if length isn't finite.
  triggerId: number      // The trigger id of this animation. Used internally.
  startFunc?: function   // The instruction keyframe that was at 0.0s.
  endFunc?: function     // The instruction keyframe that was at the end of the animation.
  startSource?: string   // The source of the keyframe that was at 0.0s.
  endSource?: string     // The source of the keyframe that was at the end of the animation.
  callback?: function    // The blending callback this animation uses if any.
  curve?: function       // The blending curve this animation uses if any.
  state?: BlendState     // The current/last overrall blending state.
}

interface BlendState {
  time: number         // How long this blend has been going for.
  max: number | false  // The max time of this blend. If false, uses one of blendTimeIn/Out.
  from: number | false // The blend weight to blend in from. If false, uses blendSane.
  to: number | false   // The blend weight to blend in to. If false, uses blendSane.
  callback: function   // The blending callback this blend will use.
  curve: function      // The blending curve this blend will use.
  callbackState: CallbackState // The callback state to send to the blending callback.
  paused: boolean      // Whether this blend has been paused by :pause().
  starting: boolean    // Whether this blend is starting or stopping the animation.
  delay: number        // How long to wait before starting this blend.
}

An example callback that produces flame particles around the player when the blend is more than halfway done.

local animBlend = GSBlend.oldF.blend

local function flame(state, data)
  if state.rawProgress > 0.5 then
    particles:newParticle(
      "flame",
      player:getPos():add(math.random() * 2 - 1, math.random() * 2, math.random() * 2 - 1)
    )
  end

  animBlend(state.anim, math.lerp(state.from, state.to, state.progress))
end

 

Callback Generators

Some of the functions in GSBlend.callback and GSBlend.curve start with gen. These are generators and are not meant to be used as blending callbacks themselves, instead returning functions that are meant to be used as callbacks.

As an example, the generator GSBlend.callback.genBlendVanilla takes a list of parts that follow vanilla parts (such as parts named Head or LeftArm) and makes a blending callback that smoothly transitions between the vanilla rotations and the animation rotations instead of overwriting the vanilla rotations immediately.

About

A library that adds blending to the start and end of Figura animations for smoother transitions.

Topics

Resources

License

Stars

Watchers

Forks

Languages