Animancer v3.0

Released 2019-05-27

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

Upgrade Guide

You must delete any old version of Animancer before importing a new one because Unity's package importer doesn't handle deleting or moving files.

It is also recommended that you use the latest possible Unity version. See the Unity Versions section for details.

All of the Major Features and Changes are listed below.

The features included in Animancer Lite have been changed slightly:

  • AnimancerComponent.CrossFade is now allowed, but only with the default 0.3 second fade duration.
  • AnimancerState.Time and Speed can no longer be set in Lite runtime builds (except Time = 0).
  • Added once-off log message when a Pro-Only feature is used in an Animancer Lite build.

Quite a few things have been renamed to be shorter and/or better reflect their purpose:

Old Name New Name
AnimancerController
LegacyAnimancerController
SimpleEventAnimancerController
IAnimancer
AnimancerComponent
NamedAnimancerComponent
EventfulAnimancerComponent
IAnimancerComponent
AnimationMixer
LinearAnimationMixer
CartesianAnimationMixer
DirectionalAnimationMixer
MixerState
LinearMixerState
CartesianMixerState
DirectionalMixerState
AnimatorControllerState
FloatParameterControllerState
Vector2ParameterControllerState
Vector3ParameterControllerState
ControllerState
FloatControllerState
Vector2ControllerState
Vector3ControllerState
AnimancerExtensions AnimancerUtilities
AnimancerStateInspector AnimancerStateDrawer
AnimancerController.CrossFadeNew AnimancerComponent.CrossFadeFromStart
AnimancerController.StopAll AnimancerComponent.Stop
AnimancerPlayable.StopGraph
AnimancerPlayable.PlayGraph
AnimancerPlayable.PauseGraph
AnimancerPlayable.UnpauseGraph
AnimancerPlayable.DisconnectAnimationsOnStop AnimancerPlayable.KeepPlayablesConnected (meaning is reversed)
AnimancerState.MainAsset AnimancerState.MainObject
ClipState.ApplyPlayableIK ClipState.ApplyAnimatorIK

Major Features

  • Replaced the 3 rudimentary demos with 22 proper Example Scenes that have highly detailed tutorial explanations.
  • Massively improved the documentation in general with lots of code examples and animated gifs.
  • Added AnimancerState.Serializable classes which make it easy to group additional details with each AnimationClip (such as Speed and Start Time), as well as set up Mixers and Controller States in the Inspector.
  • Added proper support for playing animations in Edit Mode. See the Doors example for a demonstration.
  • Improved performance, especially in situations when lots of animations are inactive.
  • Improved the API for managing IK defaults and added an ExposedCurve class which extracts a curve from an AnimationClip so you can access it at runtime. The inability to access curves directly was the main reason Inverse Kinematics was not listed as supported in previous versions.
  • Improved the Finite State Machine system.
    • It now has a base class which allows you to reference states directly instead of using a keyed dictionary.
  • Added support for Animation Events called "End" which invoke the AnimancerState.OnEnd callback so that animations can pretend they are ending early, usually to begin fading out as the animation approaches its end.
  • Greatly improved various aspects of the Inspector.
  • Added AnimancerComponent.StopOnDisable to control whether all animations are stopped by OnDisable. Also exposed it in the Inspector.
  • Implemented the IAnimationClipSource interface introduced in Unity 2018.3 throughout the system:
    • Added IAnimancerClipSource for classes to indicate that they can provide animations to an AnimancerComponent for IAnimationClipSource in Unity 2018.3. The actual implementation is done using reflection in AnimancerEditorUtilities.
    • This allows custom components using Animancer to provide AnimationClips to the Animation window without needing an AnimatorController.

Minor Features

  • Added SoloAnimation component for playing a single animation on startup in the simplest way possible.
  • Added AnimationEvent parameter to EventfulAnimancerComponent and added an optional EventSource property to exclude events from other clips.
  • [Pro-Only] Added ManualMixerState which gives full manual control over the child weights instead of trying to calculate them automatically based on a parameter.
  • Added OrbitControls component to allow standard camera movement in the example scenes.
  • Added PixelPerfectPositioning component for the sprite examples.
  • Added DirectionalAnimationSet and DirectionalAnimationSet8 for the sprite examples.
  • Added NamedAnimancerComponent.DefaultAnimation for convenience.
  • Added BoolPref to wrap an EditorPrefs bool.
  • Added the ability to set AnimancerState.LayerIndex to swap between layers.
  • Added a Toggle Legacy context menu function to AnimationClips.
  • Added AnimancerState.IsActive to check if it is playing and fading in.
  • Added default IK properties and properties that set the IK flags of all states at once to AnimancerLayer. Added context menu functions to set them.
  • Added Editor-Only finalisers to ensure that the PlayableGraph is disposed so animations can be played properly in Edit Mode.
  • Added automatic update system for AnimancerPlayables that are created in Edit Mode.
  • Added AnimancerComponent.CurrentEndEvent and CalculateFadeOutDuration to easily access the remaining duration during an early "End" event.

Changes

  • Renamed lots of things - see the Upgrade Guide.
  • Moved documentation website to kybernetikgames.github.io/animancer.
  • Changed ICanFade into AnimancerNode as a common base class for states and layers.
    • Reworked the whole node hierarchy system.
    • All nodes now have a direct reference to the root AnimancerPlayable which must be provided in the constructor so they can always access its dictionary and graph even without a parent.
  • Play methods no longer reset the AnimancerState.Time to 0. You can easily do so after the call if necessary, but you generally just want the animation to continue playing.
  • Organised common functions into EditorUtilities.
    • Added EditorUtils.GetNarrowText to include or remove spaces from Inspector labels based on whether the Inspector is wide enough to space the room.
  • Removed AnimancerState.Pause and Resume methods.
  • Moved CrossFadeFromStart functionality into AnimancerLayer.
  • [Pro-Only] Rearranced MixerState.UpdateTime to update itself last like with UpdatePlayable.
  • Moved the State Machine system out of Examples to its own folder and into the Animancer.FSM namespace.
  • Added virtual AnimancerState.Length and moved the loading bar style time display into the base AnimancerStateDrawer for any state that has a length.
  • Changed IK get/set methods to properties.
  • Moved all ScriptableObjects to the Assets/Create/Animancer sub-menu.
  • Replaced AnimancerComponent.AddState with AnimancerState.Key.
  • Stopped exposing Playables publically and made them internal so they can be used internally without copying.
  • Changed AnimancerTransition to just be a wrapper around a ClipState.Serializable.
  • Moved the component type swap from AnimancerComponent.Reset into AnimancerEditorUtils.IfMultiComponentThenChangeType.
  • Merged the Play, CrossFade, and CrossFadeFromStart overloads that use ITransition into a single Transition method that chooses which method to use based on the transition itself.
  • Moved the main logic for playing ITransitions into AnimancerPlayable.
  • Changed AnimancerPlayable.DefaultFadeDuration to 0.3 since that's what the Legacy Animation system uses.
  • Added [DefaultExecutionOrder(-5000)] to AnimancerComponent.
  • Added the ability to directly set the AnimancerState.Clip (and the ControllerState.Controller).
    • Merged AnimancerComponent.ForceSetClip into GetOrCreateState with an optional parameter and changed it to set the clip without destroying the state (it still destroys the internal Playable, just not the AnimancerState object so any existing references to it will remain valid).

Improvements

  • Added internal lists for states that need to be updated so the entire graph doesn't need to be traversed every update. This gives a negligible performance improvement with a small graph, but scales better with lots of inactive states.
  • Improved the AnimancerState.OnEnd callback:
    • Removed the 'event' keyword.
    • They now trigger every frame while a non-looping animation is past its length.
    • AnimancerState.Stop now clears the callback so that states stopped by Play will have it cleared just like states that fade out from a CrossFade.
  • Added AnimancerPlayable.IsValid so the AnimancerComponent can recreate it if it was disposed.
  • Added DestroyStates to AnimancerPlayable and AnimancerLayer.
  • Split NestedAnimatorEditor out of AnimancerPlayableEditor:
    • Improved all fields to work as the do in the regular Animator Inspector (particularly at runtime).
    • Fixed NestedAnimatorEditor to show the prefab override status correctly.
    • The nested Animator fields are no longer hidden while the regular Animator Inspector is expanded. Also improved their tooltips.
  • Improved many comments with code examples such as AnimancerState.OnEnd and AnimancerState.Time.
    • Improved comments describing exceptions in validation methods.
    • Added <exception> tags to all methods that throw exceptions.
    • Replaced <code> tags in comments with <c> where they are intended to occupy a single line only (for the API Documentation.
  • Added an assembly definition file to speed up compilation in Unity 2017.3+.
    • Renamed Animancer.dll to Animancer.Lite.dll to resolve naming conflict with the Animancer assembly definition.
  • Added more detail to the "Playable is not initialised" message in the Inspector.
  • Added #pragmas to disable the "field will always have its default value" warnings in the example scripts.
  • Improved the layout of the WelcomeWindow.
  • Improved layer fading.
    • Layers now start on 0 weight and automatically get set to 1 when they play an animation so that extra layers can be initialised and left idle without needing to set the weight to 0.
    • Calling CrossFade with the layer at 0 weight will fade the layer in and Play the animation immediately.
    • Calling CrossFade on the base layer will immediately set its weight to 1 since it can't blend effectively with anything else anyway.
    • Starting a layer fade now clears the OnEnd callback of all its states.
  • Added AnimancerPlayable.maxLayerCount (Editor-Only).
  • Fixed CrossFade to call OnStartFade on all states when it continues a faster fade, not only the target state.
  • Added the ability for AnimancerComponentEditors to override the GUI for specific properties.
  • Added NamedAnimancerComponentEditor:
    • Draws the default animation as a separate field from the rest of the array for convenience.
    • Draws the Animations array as a reorderable list.
    • Highlights animations that appear multiple times in the array.
    • Improved tooltips.
  • Added AnimationType enum which is used to compare the Animator to the AnimationClip to determine if the clip is suitable so a warning can be shown in the Inspector if necessary.
  • Added PlayableGraph name for the Playable Graph Visualiser.
  • Added methods for tracking non critical issues (such as non-essential reflection attempts that fail) and changed the Log Description of States menu function to log them as well.
  • [Pro-Only] Split AnimancerLayer.Info out into Editor.AnimancerLayerEditor.
  • Destroying layers now uses PlayableGraph.DestroySubgraph for better efficiency.
  • ClipState now dirties its time at the end of each update (instead of the start) since the playable is updated immediately afterwards.
  • Removed AnimancerPlayable.OnAnimancerChanged to save the performance when the Inspector isn't shown.
  • Added AnimancerState.NormalizedSpeed.
  • AnimancerComponent now checks that its Playable is valid rather than only null checking it.
  • Added a custom Inspector for AnimancerTransitions which explains that they are assets so changes won't be undone when leaving Play Mode.
  • Added GetState and TryGetState ovelroads which take an AnimationClip and use GetKey.
  • Added DelegateState and InputBuffer to the Animancer.FSM system.
  • Split StateMachine.TrySetState so that it now immediately returns true if the specified state is already the current state while TryResetState does not.
  • ClipState now looks one frame ahead when checking its OnEnd callback to line up with Mecanim sequencing a bit better.
  • Changed ClipState to use the frame ID to determine when the time is dirty instead of flagging it every frame.
  • Merged AnimancerState.PortIndex and AnimancerLayer.LayerIndex into AnimancerNode.PortIndex.
  • Improved validation when connecting states to a MixerState.
  • AnimancerPlayable.KeepPlayablesConnected is now false by default.
  • Added IAnimationMixer.KeepWeightlessPlayablesConnected so mixers can prevent their children from being disconencted.
  • Removed the list of spare ports in each layer. Destroying a state now swaps the last state into its place so there are no gaps. This means that iterating through the states doesn't require any null checks.
  • Cleaned up enumerators for yield instructions and foreach loops.
  • Standardised GetComponentInHierarchy in AnimancerUtilities.
  • Improved layout of ControllerState.Drawer.
  • [Pro-Only] Added ParametizedAnimancerStateDrawer to standardise the drawing of parameters in MixerStates and ControllerStates.
  • [Pro-Only] Added AnimancerLayer.CurrentStateID to count the number of times the CurrentState is changed.
  • Removed the virtual keyword from AnimancerComponent.Play and CrossFade.
  • Reworked SimpleEventAnimancerComponent:
    • It now uses the CurrentStateID to determine whether the registered event is still valid so it doesn't need to clear the event all the time.
    • Renamed it to replace the base EventfulAnimancerComponent.
  • Added standard Animation Event receivers to AnimancerComponent for Play and related methods.
  • [Pro-Only] Added ControllerState.Parameter struct to wrap name/hash pairs.
  • Added IHasKey base interface for ITransition.
    • Added GetState(IHasKey) and related methods.

Inspector Improvements

  • Improved the AnimancerComponent Inspector details displayed in Play Mode.
    • Improved the weight display to round everything to 1 decimal place in the main view and only show the full number in the expanded details. It also uses Italics to indicate when a value is being rounded and fades the colour proportional to the value.
    • Added a foldout to the layer Inspector with all their details (weight, fade, additive, mask).
    • Setting a layer mask now uses its name as the layer name if none was set yet.
    • Fixed errors for 0 length clips (such as a single keyframe Idle).
    • The time highlight box now stays full for states with 0 length instead of staying empty.
    • When the PlayableGraph is not playing, the Inspector will now show a toggle to play it.
    • You can now Ctrl + Click on a state in the Inspector to CrossFade to it.
    • [Pro-Only] ControllerState now shows its time in the same way as ClipState.
    • [Pro-Only] Added Inspector controls for Parameter Controller States.
    • String keys are now shown with quotation marks.
  • Improved warnings in the AnimancerComponent Inspector:
    • Improved the warning when an AnimatorController is assigned and turned it into a button linking to the documentation.
    • Improved the warnings for update modes and layer weight and turned them into buttons that link to the documentation.
    • Added a warning when no layers are at weight 1.
    • Added a warning when no Animator is assigned. You can click it to automatically search for one nearby.
    • Added a warning when an animation has an "End" event but no OnEnd callback is registered.
  • Added Drag and Drop support to the AnimancerComponent Inspector to create a ClipState from an AnimationClip or several from an IAnimationClipSource. Animations that already have states won't create new ones.
  • Added Drag and Drop support to the NamedAnimancerComponent Inspector to add an AnimationClip to the Animations list.
  • Improved the NamedAnimancerComponent Inspector:
    • It now uses a ReorderableList to display the Animations list.
    • It now removes null elements from the Animations list.
    • It now hides the Play Automatically and Animations fields in play mode.
  • Added and improved menu context menu functions:
    • Improved the state Inspector context menu layout and added context menu functions for Play and CrossFade.
    • Added context menu functions to the layer Inspector.
    • Added documentation links to all context menus.
    • Replaced PortIndex in context menu details with the state's hierarchy path.
    • Improved Inspector context menu handling. The base layer can now show its menu even when it's not showing the header because it's the only layer.
    • Added AnimancerComponent context menu functions to Pause/Unpause the graph, which will freeze/unfreeze all animations on that object.
    • Added a layer context menu function to open the Playable Graph Visualiser if it exists in the project.
    • Added context menu functions to change the way states are displayed in the Inspector and changed the default to sort by name and not split active/inactive into separate lists.
    • Replaced "Add Layer" context menu function with "Initialise" when the AnimancerPlayable isn't initialised so it doesn't create two layers at once.
    • Added a context menu toggle for AnimancerPlayable.KeepPlayablesConnected and fixed it to properly set the weight of reconnected states.

Fixes

  • Fixed the obfuscated DLLs in Animancer Lite to not cause exceptions in Unity 2018.3 (the exceptions were harmless and didn't affect functionality at all, but were very annoying).
  • AnimancerLayer.CrossFade now makes sure to call ClearOnEndEvent even if it only continues an existing fade.
  • Fixed AnimancerLayer and AnimancerPlayable.IsPlaying to return false when there are no layers or states respectively.
  • Fixed auto-collapse of the Animator component to be executed when an AnimancerComponent is first added.
  • Moved AnimancerLayer.Dispose into AnimancerPlayable.LayerCount (when reducing the value) since it otherwise leaves the layer list in an invalid state.
  • Fixed AnimancerState.OnEnd invocation with negative speed to occur when time is below 0.
  • Fixed NamedAnimancerComponent to properly unpause the graph when re-enabling.
  • Fixed reconnecting a state to the graph to leave the weight alone if it wasn't dirty.
  • Setting AnimancerPlayable.KeepPlayablesConnected now changes all connections to properly reflect its new value.
  • Fixed AnimancerState.MoveNext to support properly work with negative speeds.
  • [Pro-Only] Added exception to ControllerState constructor if the controller is null.
  • Fixed AnimancerPlayable.GetOrCreateState to properly change the layer index.
  • Fixed a bug in the Inspector when undoing an AnimancerComponent type change.