Animancer v7.4

Released 2023-01-26

When upgrading to a newer version of Animancer, you must delete any previous version from your project first.

See the Animancer v7.0 Upgrade Guide if you are upgrading from a version older than that.

Animancer v7.4.2

  • Added TimeSynchronizer. #250
  • Changed the state Is Playing toggle to a Play/Pause button.
  • Fixed the ReadMe auto-update check.
  • Fixed AnimancerLayer.GetOrCreateWeightlessState to not clone a state that has no parent.
  • Fixed IndexOutOfRangeException in GenerateSpriteAnimationsTool.

Animancer v7.4.1

  • Fixed compile errors on build caused by #ifs in the Strings class.

Animancer v7.4.0

Features

Attack of the Clones

FadeMode.FromStart now works with all state types.

  • Added AnimancerState.Clone to make a copy of any state.
  • Added OptionalWarning.CloneComplexState for awareness when cloning anything other than a ClipState.
  • Changed AnimancerLayer.GetOrCreateWeightlessState:
    • It now uses AnimancerState.Clone so it's no longer limited to only ClipStates.
    • Exceeding the AnimancerLayer.MaxCloneCount (default 3) will now simply return the lowest weight state.
    • Removed OptionalWarning.MaxStateDepth.

Simplified playing the same animation on multiple layers

The behaviour of the following code has changed:

1.    animancerComponent.Layers[0].Play(clip);// Play an animation on Layer 0.
2.    animancerComponent.Layers[1].Play(clip);// Play the same animation on Layer 1.
Line Old Behaviour New Behaviour
1 Create a state on Layer 0. Create a state on Layer 0.
2 Move the existing state to Layer 1. Clone the existing state to play on Layer 1, leaving the original on Layer 0.
If you wanted the new behaviour, you had to manually create a second state, give it a unique Key, and refer to it using that Key. If you want the old behaviour, you can use animancerComponent.States.TryGet to get the state then set its LayerIndex and Play it.
  • This makes it much easier to play the same animation on multiple layers, which is much more common than wanting to move a state between layers.
    • This change simplifies LayeredAnimationManager.PlayActionFullBody in the Dynamic Layers example a bit.

Simplified Mixer Initialization

Using Mixer Transitions is unchanged, but the process of creating Mixers in code has been streamlined.

All of the following examples produce (or used to produce) a mixer containing 3 child states:

  • idle at threshold 0.
  • walk at threshold 0.5.
  • run at threshold 1.
Old Code New Code

Several old initialization functions have been removed to reduce clutter.

var mixer = new LinearMixerState();
mixer.Initialize(idle, walk, run);

Saving that little bit of typing wasn't worth confusing users by having so many different ways of initializing things (though it could easily be brought back if requested).

Now you can use Collection Initializers to concisely create a mixer of any size.

var mixer = new LinearMixerState
{
    { idle, 0 },
    { walk, 0.5f },
    { run, 1 },
};

You could also omit the threshold numbers and call mixer.AssignLinearThresholds() afterwards.

If not using the above method which only supports 2 or 3 states, you used to need to specify the number of children upfront and explicitly specify the index of each child as you create it.

var mixer = new LinearMixerState();
mixer.Initialize(3);
mixer.CreateChild(0, idle, 0);
mixer.CreateChild(1, walk, 0.5f);
mixer.CreateChild(2, run, 1);
// Repeat for more children.

Now you can just treat mixers like a List and Add as many children as you want.

var mixer = new LinearMixerState();
mixer.Add(idle, 0);
mixer.Add(walk, 0.5f);
mixer.Add(run, 1);
// Repeat for more children.
  • Since you now add children one by one, the system will prevent any of them from being null.
    • This improves performance a bit by avoiding the need for mixers to null check their children throughout the system.
    • The downside is that it reduces the flexibility of the system slightly because you might have wanted to leave some child slots empty to fill later, but that seems like a very uncommon use case (and could still be achieved by implementing a simple dummy AnimancerState class).

Mixer Transition Inspector

Added a Two Line Mode toggle function in the Animation heading of Mixer Transitions which shows each animation on a separate line from its threshold/speed/sync since the animation names are often cut off by the limited space.

One Line Two Lines

Animancer Component Inspector

Old New
  • Replaced the Is Playing Graph toggle with a Play/Pause icon.
  • Replaced the Play/Pause buttons in the Transition Preview Window with icons.
  • Added a button to step forward one frame at a time.
  • Added Step Forward/Backward buttons to the Transition Preview Window.
  • The frame step interval defaults to Time.fixedDeltaTime and can be changed in AnimancerSettings.

Add Animation

Added a new Add Animation context menu function in the AnimancerComponent Inspector shows a field with which you can add animations manually. This can be used with the other Inspector Controls to quickly test animations without needing to set up scripts for them.

Animator Controller Integration

Added various members to ControllerState and HybridAnimancerComponent to make it easier to migrate from an Animator based setup:

  • parameterCount, parameters, and layerCount to match the naming conventions in Animator.
  • SetFloat overloads with damping parameters. This simply uses a dictionary to store the velocity values since the Playables API doesn't have damping built in.
  • Update as an extension method which calls Evaluate (not a regular method because we don't want Unity to call it every frame).
  • The Animator Controllers page goes into more detail.
  • Also changed HybridAnimancerComponent to default AnimancerPlayable.KeepChildrenConnected = true which avoids some odd behaviour issues.

Improvements

  • Added AnimancerState.TimeD, and NormalizedTimeD to allow access to the time value as a double (which is what the Playables API uses internally).
  • Added DirectionalClipTransition.
  • Added ExposedPropertyTable for Timeline's Exposed References system.
  • Added AnimancerSettings.HideEventCallbacks to hide the Callback fields of Animancer Events in the Inspector.
  • Added AnimancerEvent.Sequence.ContentsAreEqual.
  • Added ManualMixerStateSet and RemoveChild to more easily change and remove mixer children.
  • Added SimpleTimer for easily timing things.
  • Un-sealed AnimancerPlayable and added a generic Create method to allow you to use your own sub-class.
    • Changed AnimancerComponent.InitializePlayable to take an AnimancerPlayable instead of a PlayableGraph so you can create whatever subtype you want.
  • Improved the MouseDrag script in the IK Puppet example.
  • Improved the ReadMe system:
    • Separated AnimancerReadMe out of base ReadMe to allow it to be more easily shared between projects.
    • Added an automatic update check.

Debugging

  • Added assertions to prevent 2D Mixer child states from having identical thresholds.
  • Added more descriptive error messages for when calling AnimancerLayer.Play with a state that has another state as its parent (instead of null or a layer).
  • Added more descriptive error messages for when calling AnimancerState.SetRoot on a state that has a Parent with a different Root.
    • Added OptionalWarning.AnimatorDisabled with a check on startup and a warning in the Inspector.
  • Improved the OptionalWarning.LockedEvents warning to explain that it can be prevented by calling state.Events.SetShouldNotModifyReason(null); before making any modifications.

Changes

  • Merged the base MixerState into ManualMixerState because keeping them separate added unnecessary complexity.
  • Changed the Animancer.Lite.dll version mismatch warning to a dialogue window so you can't miss it.
  • Changed the Lean example to expose a Transform array in the Inspector so it can work with Generic Rigs as well rather than only Humanoids.
  • Changed the default AnimancerLayer.WeightlessThreshold from 0.01 to 0.1.
  • Changed AnimancerNode.Playable to public so you don't need to cast to IPlayableWrapper.
  • Changed AnimancerNode.IsPlayingAndNotEnding to public.
  • Changed AnimancerNode.ConstructorStackTrace to public.
  • Changed ClipState.ApplyAnimatorIK and ApplyFootIK to return false instead of throwing an exception if you get the value before the Playable is created.
  • Changed AnimatorUpdateMode.AnimatePhysics references to AnimatorUpdateMode.Fixed in Unity 2023 (it was renamed).
  • Removed ScriptingDefineSymbols and used the Animancer.asmdef to manage the UNITY_2D_SPRITE symbol instead.
  • Separated the RedirectRootMotion functionality from the Root Motion example script into seperate scripts in the Utilities folder and added a new documentation page for them.

Fixes

  • Fixed various warnings in Unity 2022.2.
  • Fixed NullReferenceException in AnimationClipEditor. #215
  • Fixed NullReferenceException in AnimancerNode.AppendDescription.
  • Fixed NullReferenceException in ManualMixerState.SynchronizeDirect with nested mixers.
  • Fixed NamedAnimancerComponent initialization to allow it to be added an an object without an Animator at runtime.
  • Fixed AnimancerNode.AppendIKDetails to not throw errors if the Playable isn't valid.
  • Fixed AnimancerState.SetRoot to not un-parent the state if its parent's root is also being set to the same value.
  • Fixed potential errors in AnimancerState.IsPlayingAndNotEnding if the state has been destroyed. #226
  • Fixed AnimancerEvent equality checks to properly handle NaNs.
  • Fixed LinearMixerTransition to apply its settings to the correct state.
  • Fixed tab navigation order of Inspector fields in Mixer Transitions.
  • Fixed multi-selecting Transition Assets causing events to lose their names under certain circumstances. #220
  • Fixed ManualMixerState.ApplySynchronizeChildren to not keep the mixer in the update list if it isn't playing. #242
  • Fixed the Pack Textures Tool to not give warnings if the 2D Sprite package isn't present.
  • Fixed Transition Inspector indentation issues in Unity 2022.2. #246
  • Fixed potential exception when removing animations from a Mixer Transition in the Inspector.