Released 2020-01-28
Highlights
- The main public API has been entirely restructured:
- The
Play,CrossFade,CrossFadeFromStart, andTransitionmethods have all been unified asPlaywith fewer overall parameter combinations. - Layers are now treated as a proper collection. So instead of
animancer.LayerCount,animancer.GetLayer(...), oranimancer.SetLayerAdditive(...), you now useanimancer.Layers.Count,animancer.Layers[...], oranimancer.Layers.SetAdditive(...). - Same for states. So instead of
animancer.GetState(...)you now useanimancer.States[...]andanimancer.CurrentStateis nowanimancer.States.Current. - Serializables are now called Transitions (i.e. you now use
ClipTransitioninstead ofClipState.Serializable).
- The
- [Pro-Only] New Animancer Event system for general events without needing to use Unity's Animation Events:
- You can specify events per-state instead of per-clip.
- You can add events and set callback delegates directly in code without needing to hook up magic strings to public methods.
- The
AnimancerState.OnEndcallback has moved toAnimancerState.Events.OnEndand you can optionally specify a time for it instead of always being at the end of the clip.
- New Transition Preview Window allows you to preview your transitions on your character without entering Play Mode.
- Implemented Mixer Time Synchronization.
- New
PlayableAssetStateallows you to play Timeline assets in Animancer. - All transition types now have a corresponding Transition Asset type.
- Added support for Unity 2019.3 (most upgrades are fine, but that one broke a lot of things).
- Added Weapons example as well as instructions for downloading animations from Mixamo and configure their Import settings.
- Added a C# in Unity section to explain the fundamentals of programming in Unity for beginners. #7
Upgrade Guide
The main public API has been significantly restructured in several ways which will affect all users, so this section will help you fix the errors you get when upgrading a project from an earlier version.
Remember to always delete any older version of Animancer before upgrading.
Serialized Data
Some of the changes to serialized data structures will unfortunately cause certain values to be lost when upgrading so if you were using any of the following things you will need to set them again manually:
- The
AnimancerComponent.StopOnDisablebool was previously serialized by theAnimatorcomponent itself, but it has now been replaced by theAnimancerComponent.DisableActionenum which is serialized in theAnimancerComponentitself (and accessable via theActionOnDisableproperty).StopandPausecorrespond to the previoustrueandfalse, but there are now several other values too. ClipTransition.StartTime(formerlyClipState.Serializable.StartTime) is now always serialized as a normalized time value since the Inspector shows the value as both normalized time and seconds. So if you previously had the value set to seconds, it will now be incorrect.- Mixer Time Synchronization is now enabled by default for all mixers so they will give different results to before it was implemented (likely better results).
Playing and Fading
The AnimancerComponent.Play, CrossFade, CrossFadeFromStart, and Transition methods are now all called Play. The Playing Animations page explains their differences.
In v3.1, AnimancerComponent had several overloads each of Play/CrossFade/Transition which were made even more complicated by the presence of default parameters for fadeDuration and layerIndex:
// Old Methods from v3.1:
Play(AnimationClip clip, int layerIndex = 0)
Play(AnimancerState state)
Play(object key)
// Note: replaced "DefaultFadeDuration" with just "Default" to fit everything on one line.
CrossFade(AnimationClip clip, float fadeDuration = Default, int layerIndex = 0)
CrossFade(AnimancerState state, float fadeDuration = Default)
CrossFade(object key, float fadeDuration = Default)
CrossFadeFromStart(AnimationClip clip, float fadeDuration = Default, int layerIndex = 0)
CrossFadeFromStart(AnimancerState state, float fadeDuration = Default, int layerIndex = 0)
CrossFadeFromStart(object key, float fadeDuration = Default, int layerIndex = 0)
Transition(ITransition transition, int layerIndex = 0)
The various default parameters meant that those methods had a total of 22 parameter combinations, making them rather unwieldy and confusing for new users.
This has been improved in several ways by v4.0:
- All of those methods are now called
Play. - The Collections change allowed the
layerIndexparameter to be removed (soPlay(clip, 1)is nowLayers[1].Play(clip)). - The new
FadeModeenum controls how a fade actually works, which includes the oldCrossFadeFromStartfunctionality and the ability to use the specifiedfadeDurationas a portion of the clip length rather than raw seconds. See theFadeModeAPI documentation for the details of each value. - This takes it down to only 12 parameter combinations:
// New Methods in v4.0:
// Play.
Play(AnimationClip clip)
Play(AnimancerState state)
Play(object key)
// CrossFade and CrossFadeFromStart.
Play(AnimationClip clip, float fadeDuration, FadeMode mode = FadeMode.FixedSpeed)
Play(AnimancerState state, float fadeDuration, FadeMode mode = FadeMode.FixedSpeed)
Play(object key, float fadeDuration, FadeMode mode = FadeMode.FixedSpeed)
// Transition.
Play(ITransition transition)
// New method allows you to override the fade details of the transition.
Play(ITransition transition, float fadeDuration, FadeMode mode = FadeMode.FixedSpeed)
Unfortunately this means it is no longer possible to have a default value for the fadeDuration parameter because skipping that parameter would just use the instant Play(clip) method instead of Play(clip, defaultFadeDuration). The AnimancerPlayable.DefaultFadeDuration constant still exists though, since it is used in several places such as the default value to use for a ClipTransition. Also note that the value is now 0.25 seconds to match the default Mecanim transition settings (it used to be 0.3 as the default used by the Legacy animation system).
Collections
All Layer functionality in AnimancerComponent has been moved into the new Layers property.
| Old (v3.1) | New (v4.0) |
|---|---|
animancer.Play(clip, 1) |
animancer.Layers[1].Play(clip) |
animancer.LayerCount |
animancer.Layers.Count |
animancer.GetLayer(1) |
animancer.Layers[1] |
animancer.SetLayerAdditive(1, true) |
animancer.Layers.SetAdditive(1, true)animancer.Layers[1].IsAdditive = true |
animancer.SetLayerMask(1, mask) |
animancer.Layers.SetMask(mask)animancer.Layers[1].SetMask(mask) |
AnimancerPlayable.maxLayerCount = 8 |
AnimancerPlayable.LayerList.defaultCapacity = 8AnimancerPlayable.LayerList.SetMinDefaultCapacity(8) |
In earlier versions the AnimancerComponent class was the only one with access to its GetKey(AnimationClip) method, meaning that it could have a Play(AnimationClip) method where other classes (AnimancerPlayable and AnimancerLayer) could not because they would not be able to determine what key to look up the state with in the internal dictionary (usually the clip is its own key, but NamedAnimancerComponent uses the clip's name so you can call Play("Name")). But Animancer v4.0 gives the AnimancerPlayable a reference to its component, so now you can call animancer.Layers[1].Play(clip) as shown above. Also note that this changes the meaning of the default animancer.Play(clip) so that instead of playing the animation on layer 0 it will now leave it on whatever layer it is currently on.
All State functionality in AnimancerComponent has been moved into the new States property.
| Old (v3.1) | New (v4.0) |
|---|---|
animancer.CurrentState |
animancer.States.Current |
animancer.StateCount |
animancer.States.Count |
animancer.CreateState(clip) |
animancer.Layers[0].CreateState(clip) |
animancer.GetState(clip)animancer.GetState("Name") |
animancer.States[clip]animancer.States["Name"] |
animancer.GetOrCreateState(clip) |
animancer.States.GetOrCreate(clip) |
animancer.Dispose(clip) |
animancer.States.Destroy(clip) |
Renaming
| Old Name (v3.1) | New Name (v4.0) and Reason |
|---|---|
All Serializable classes such as ClipState.Serializable |
TransitionA more descriptive name. They encapsulate the fade duration, start time, etc. of an animation in much the same way as transitions in an Animator Controller. The fact that they are serializable is less significant. |
IAnimancerTransitionIAnimancerTransitionDetailed |
ITransitionITransitionDetailedThey are in the Animancer namespace anyway. |
FloatControllerStateVector2ControllerStateVector3ControllerState |
Float1ControllerStateFloat2ControllerStateFloat3ControllerStateThey each wrap a specific number of float parameters, even if they happen to also allow those parameters to be accessed as a Vector2 or Vector3. |
Most Dispose methods |
DestroyRemoved IDisposable from everything that does not follow regular disposal patterns. It makes no sense to put an AnimancerState in a using statement and if you declare a new ClipState locally, you do not need to dispose it because it will be cleaned up when the graph is destroyed. |
All of the AnimancerPlayable.StateDictionary.Destroy methods that take collections |
AnimancerPlayable.StateDictionary.DestroyAllTo avoid ambiguity. |
AnimancerNode.PortIndex |
AnimancerNode.IndexA simpler name since referring to "ports" was just confusing people anyway. |
AnimancerLayer.CurrentStateIDAnimancerPlayable.CurrentStateID |
AnimancerLayer.CommandCountAnimancerPlayable.CommandCountA more descriptive name. |
IEarlyUpdate |
IUpdatableNow contains both EarlyUpdate and LateUpdate methods. |
MixerState.AreWeightsDirty |
MixerState.WeightsAreDirtyBetter phrasing. |
Features
Improved Transition Inspector
As mentioned above, AnimancerState.Serializable and all its derived classes have been renamed to Transition (see Transitions for details). But that's not all, they have also received a major upgrade to their Inspector interface:
| Old (v3.1) | New (v4.0) |
|---|---|
[SerializeField]private ClipState.Serializable _Walk; |
[SerializeField]private ClipTransition _Walk; |
![]() |
![]() |
There are quite a few improvements here:
- The "eye" button in the top right opens a new window for previewing the transition.
- Rather than giving the
Start TimeaNormalizedtoggle to swap between normalized time and raw seconds, it now simply shows both values side by side so you can edit whichever one you want. This has been applied to the other fields as well. - All relevant fields now display an appropriate suffix to indicate the units ("x" indicates normalized time while "s" indicates raw seconds).
Speednow has a toggle to determine if it is actually applied (otherwise the state simply retains whatever speed it had previously).- The new Animancer Event system allows the
OnEndcallback to have a custom time instead of always being at the exact end of the animation, so that value is made available in the Inspector with a toggle to show aUnityEventthat lets you configure the callback as well.- Note that when the
End Timetoggle is disabled, the value will actually be calculated based on theSpeed. When playing forwards the animation will end atNormalizedTime == 1, but when playing backwards it will end atNormalizedTime == 0.
- Note that when the
- Down the bottom is a visual timeline display of the main parameters:
- The labels show key times (in seconds, rounded off).
- The blue highlighted area represents the fading in and out.
- The grey bar down the bottom represents the actual length of the animation.
- The button on the right adds an Animancer Event which will also be shown in this area.
There are also a few changes on the code side:
- Removed
StartTimeIsNormalizedand renamedStartTimetoNormalizedStartTime. It always saves the normalized time value regardless of which one you set in the Inspector. Speedcan now be set toNaNto prevent it from changing the existing value (this is what disabling the Inspector toggle does to any of the fields).
Transition Previews
The "eye" button in the top right of each Transition in the Inspector opens a window for previewing the transition so you can fine tune its details and see what your model looks like without needing to enter Play Mode.

Transition Assets
All transition types now have a corresponding Transition Asset (a ScriptableObject with a single field for that transition type):
AnimancerTransitionis now the non-generic base class for transition assets.- Added transition assets for all transition types using the naming convention that
XXXTransitionhas aXXXTransition(which will create aXXXStatewhen played). For example, aClipTransitionholds aClipTransition. - Any references to
AnimancerTransitionfrom previous versions are equivalent to the newClipTransition, however you may wish to leave fields as they are so that any transition asset can be assigned if you aren't doing anything specific toClipTransitions. Any previously created assets will be automatically changed to the new type. AnimancerTransitionno longer exposes the properties of theTransition(except for those required byITransition) so instead oftransitionAsset.Clipyou now need to usetransitionAsset.Transition.Clip. This greatly simplifies its implementation as well as the implementation of all derived classes and makes it clearer that modifications are being applied to an object which may be shared.AnimancerTransition.Transitionnow has a comment warning that thetransition.Statecan only hold one value even though multiple states could have been created on different objects from that same transition.
Animancer Events
Animancer has always supported Unity's inbuilt Animation Events, but they have several notable drawbacks which are avoided by the new event system:
- The Events page explains the differences between the two systems.
- Animancer Events are primarily configured in the Inspector as part of Transitions to make use of the new Transition Preview system:

- They can also be configured in code:
// MeleeAttack.cs:
[SerializeField] private ClipTransition _Animation;
protected virtual void Awake()
{
// Make sure it has the expected number of events.
Debug.Assert(_Animation.Events.Count == 2, "Expected 2 events for the hit start and end");
// AnimancerEvent.Sequence always sorts itself so we know the start will be before the end.
_Animation.Events.Set(0, OnHitStart);// Set the callback for event 0.
_Animation.Events.Set(1, OnHitEnd);// Set the callback for event 1.
_Animation.Events.OnEnd = Character.EnterIdleState;
}
public void Attack()
{
Character.Animancer.Play(_Animation);
}
- Every event sequence has a separate End Event which takes the place of the old
AnimancerState.OnEndcallback and allows a custom time to be specified instead of always occuring at the very end of the animation. - End Events are included in Animancer Lite, but the ability to set a custom end time and use other events is only available in the Unity Editor unless you purchase Animancer Pro.
- As with End Events prior to Animancer v4.0, all events are cleared (and returned to the
ObjectPool) whenever a new animation is played. See Clear Automatically for details. - By default, this system uses
UnityEvents to define the event callbacks in the Inspector. However, it can be modified to use any other similar type of events. In particular, changing it to use UltEvents only takes a few simple steps.
Mixer Time Synchronization
- Mixer States can now synchronise the times of their children.
- It's not quite as advanced as the proper Foot Phase Synchronization used in Blend Trees which analyses the strides the character makes so that it can better synchronise animations with non-uniform timings such as when walking with a limp or an animation that includes multiple walk cycles.
- But it does have one major advantage: you actually get to control it so you can choose which animations are synchronised.
- It's on by default and can be disabled for individual children using the
SynchroniseChildrenarray. - This advantage can be seen in the Linear Mixers example. Enabling synchronization on all animations gives the same result as the Blend Tree, meaning that the blending between Idle and Walk gives a much slower shuffle than it should. But disabling synchronization on the Idle gives a much better result because there's no need for consistency between the timing of those two animations.
MixerState.IsLoopingnow returns true if any child state is looping.

Timeline
- Added
PlayableAssetStatefor playingPlayableAssets. - Added an introduction sequence to the
Platformerexample. This allows the sequence of animations to be configured using the Timeline window and then played as if it were a single animation.


Changes
- Replaced
AnimancerComponent.StopOnDisablewithActionOnDisablewhich is aAnimancerComponent.DisableActionenum withStopandPausecorresponding to the previoustrueandfalseas well as several new values. AnimancerTransition.Stateis now the state most recently passed intoApply(backed by the un-castBaseState) so they can be more easily used on multiple objects.- Overrides of
CreateStateno longer need to manually set theState.
- Overrides of
- Changed
HybridAnimancerController.PlayControllerto return itsControllerState. ControllerTransitionnow uses itself as the key instead of the controller in case something else happens to use the same controller with a different set of parameters.AnimancerLayer.CreateStatenow properly sets theAnimancerState.Key.- Added a
Validateclass for all the validation methods and Lite restrictions.Validate.FadeDurationnow allows 0 in Animancer Lite.- All general validation is now conditional based on the
UNITY_ASSERTIONSsymbol (in the Unity Editor, Development Builds, and Animancer Lite).
- Changed
AnimancerState.IsPlayingAndNotEndingto not try to look ahead one frame because it was only using the delta time from the previous frame so it was unreliable at best and wouldn't even be using the right type of delta time forAnimatePhysicsorUnscaledTime. But it does now account for the new End Event time. - Changed the Inspector display of
"Dirty Early Nodes"to"Updatables". - Moved
AnimancerNode.IsPlayingtoAnimancerStatesince layers do not need it. - Added
AnimancerState.NewTimewhich only gets called when theTimeis actually changed and is virtual.- Added a minor optimisation in the setter to only cast the value to
doubleonce. - Moved time caching from
ClipStateto the baseAnimancerStateso it can be used by all states. - Added a non-NaN assertion to the
AnimancerState.Timesetter. ManualMixerStateoverridesNewTimeto access the weighted averageTimeof all child states.ControllerStateoverridesNewTimeto access theStateInfo.normalizedTime.
- Added a minor optimisation in the setter to only cast the value to
- Removed
AnimancerState.NormalizedSpeedbecause it was not really that useful and got in the way of auto-correct suggestingNormalizedTime. The getter was simplySpeed / Lengthand the setterSpeed = value * Length. - Refactored the system for checking if an
AnimationCliphas an Animation Event with a particular name:- Moved the static
ClipState.HasEventtoAnimancerUtilities. - Added an overload that takes an
IAnimationClipCollection. - Removed the abstract
AnimancerState.HasEvent. AnimationEventReceivernow usesAnimancerUtilities.HasEvent(IAnimationClipCollection, string)so that each state doesn't need to manually iterate through all its clips.
- Moved the static
- Changed
StateBehaviour.ResettoOnValidateso it always enforces its rule. - Replaced the custom transition context menus with the standard serialized property context menu:
- It now displays the size of the serialized Animancer Event arrays.
- Made several
AnimancerStatemembers virtual instead of abstract:AverageVelocity,ApplyAnimatorIK,ApplyFootIK. - Added Assembly Definitions for
Animancer.FSMandAnimancer.Examplesto make sure theFSMsystem is entirely separate. - Removed null checks from
AnimancerPlayable.Play(animator, playable, component)so it will now throw exceptions if the parameters are null. BoolPrefcan now take a custom key prefix.- Added prefixes to all prefs.
Improvements
AnimancerComponent.InitializePlayablewill now try usingGetComponentif it has noAnimatorreference and throw an exception if one still isn't found.NamedAnimancerComponentnow avoids initializing itsAnimancerPlayableinAwakeif it has no animations.- Improved the output setup of
AnimancerPlayable:- Removed the exception for initializing without an
Animator. - Renamed the static
Playmethods toSetOutputand made them non-static. - Calling
SetOutputmultiple times will now destroy the oldPlayableOutputso it does not cause errors in Unity 2019.3+ and you can change theAnimatorproperly.
- Removed the exception for initializing without an
- Improved
ITransition:- It now implements a
FadeModedirectly instead ofbool CrossFadeFromStart. Play(transition)no longer tries to calculate the fade out duration. If you want to do that, you need to callAnimancePlayable.GetFadeOutDurationand pass it intoPlay(transition, duration, mode).- Moved the main part of
AnimancerPlayable.GetFadeOutDurationtoAnimancerEvent, leaving behind only the part specific to Animation Events with the function name "End".
- It now implements a
ClipTransition.Applynow applies a default start time based on the speed if thestate.Weight == 0. Same forPlayableAssetStatetransitions.AnimancerState.NormalizedTimenow returns 0 ifLengthis 0.AnimancerState.Durationnow sets the speed to infinity if the value is set to 0.- The
AnimancerNode.SpeedandWeightsetters now assert that the value is not NaN. - Added
Restore Bind Posecontext menu function toAnimatorcomponents. - The "Threshold" header in the Mixer Inspector is now a dropdown menu which lists all the threshold calculation functions. #12
- Adding a
HybridAnimancerComponentto an object with anAnimatorControllerassigned to itsAnimatorwill now assign that controller to the animancer instead of only clearing it. - Removed unnecessary calls to
SetInputCountandSetInputWeightduringAnimancerPlayable.OnPlayableCreate. - Minor optimisation in
AnimancerNode.ApplyWeight. - Added Asset Labels to most assets.
- Added
IAnimationClipCollectionwhich takes anICollectioninstead of aListso it can useHashSets to efficiently avoid duplicates.- All
Transitions now implementIAnimationClipCollection. - Added various
Gathermethods toAnimancerUtilities. - Moved the reflection based clip gathering system from
AnimancerEditorUtilitiesinto a dedicatedAnimationGathererclass and improved its reliability. - It now finds the character's root object using the prefab root or by counting the number of
Animators below each parent. An object with moreAnimators is assumed to be the parent of multiple characters, so the previous object is the root. Once it finds the root, it gathers animations from the child components of that object. - Added
ICharacterRootfor components to manually specify which object is the root.
- All
- Added
AnimancerStateDictionary.Destroymethods for collections andIAnimationClipSource. - The
Find Animationscontext menu function forDirectionalAnimationSets now properly supports undo commands. - Added
AnimancerUtilities.Wrap01extension method as a more efficient implementation ofMathf.Repeat(value, 1). - Reorganised the Inspector context menus.
- Removed
AnimancerState.HasLength. All states must now return a validLength(even if it is 0).- Added
ManualMixerState.Lengthwhich is calculated as the weighted average of the lengths of each of its children.
- Added
- Added
ControllerState.StateInfoto return either the current or next state depending on whether a transition is active.LengthandIsLoopingnow use theStateInfo.- Removed
ControllerState.Drawer.DisplayStateInfo,DisplayTime,DisplayLength, andSetTimesince they are now unnecessary.
- Added
[<see cref="SerializeField"/>]tags to the start of comments for all properties that directly wrap serialized fields. StateMachine.CanSetStatenow returns true if the parameter isnullsince the other methods support nulls.- The
ReadMenow includes the Animancer Version in its name to better detect if the user did not delete a previous version before updating (since Unity's package importer will overwrite old files but not rename them).
Fixes
- Fixed various issues in Unity 2019.3:
- Fixed the preview icon to use a different texture since the old one seems to be missing.
- Fixed
AnimancerGUI.DoOptionalTimeField. - Fixed the event drawer foldout.
- Fixed Inspector Error on the
NamedAnimancerComponent. - Fixed import warnings from the Spider Bot model due to multiple objects having the same name.
- Added a workaround so the base
TransitionDrawerdoes not take proprity over its more specific children (only happens in a DLL).
- Added
DummyObjectDraweras a fallback custom Inspector for anyObject... which does nothing (the class literally just inherits fromUnityEditor.Editorand has no members). For some reason Unity executesPropertyDrawers differently in the default Inspector than it does in a custom Inspector (even an empty one) and that difference causes theTimeRulerto not display properly without a custom Inspector. Since it is set as a fallback, any other custom Inspector should automatically override it, but if not you can simply deleteAnimancer/Internal/Editor Utilities/Inspector/DummyObjectEditor.cs. - Fixed
FadeMode.FromStartto work properly with thefadeDurationset to 0. - Fading now accounts for the speed of the parent nodes.
- Fixed
ControllerState.GatherDefaultStatesto properly gather the state for layer 0. - Fixed transitions to use the correct label for the main property in Unity 2018.3+.
- Fixed
ManualMixerTransition.CreateStateto properly callInitializeto create its states. - Removed the functionality to update animations in Edit Mode from Unity 2018.3+ because Unity now does it automatically.
- Fixed the Edit Mode update loop to not throw exceptions when an object is destroyed.
- Calling
AnimancerState.SetParentwith an already occupied port will now leave the state properly disconnected as it fails. - Fixed
AnimancerPlayable.KeepChildrenConnected = trueto work properly. - Fixed the
AnimancerStateDrawerprogress bars to be properly visible in the Dark Theme and changed the colors to be a bit stronger overall. - The
AnimancerPlayablefinalizer will no longer destroy the graph automatically while in Play Mode since that would mean a runtime warning anyway. AnimancerState.Durationnow returnsPositiveInfinityfrom the getter ifSpeedis 0 and throws anArgumentExceptionis setting the value to 0.AnimancerState.RemainingDurationnow respects looping/not and custom end times.- Fixed the 2D mixer states to round children with
weight < 0.01fto 0. Otherwise they often get very small weights and still trigger Animation Events. PlayableGraphs created in Edit Mode are now destroyed properly if the target Animator is destroyed.- Added comments explaining that when
OnAnimatorIKis called the layer index parameter will always be zero (a limitation of the Playables API). - Replaced all usage of
EditorStyles.labelwithGUI.skin.labelsince they are slightly different in some Unity versions and the latter is the default used byGUI.Label. - Fixed the
End Event/Clearcontext menu function to be disabled when the time is not set. Ctrl + Clickon a state in the Inspector now unpauses the graph as well as fading to that state.- Fixed
Float3ControllerStateto show all of its parameters in the Inspector rather than only the first two.
Examples
- Added Weapons which uses the new instructions for downloading animations from Mixamo and configure their Import settings.
- Improved the
ReadMe:- It now lists all example scenes for easy navigation.
- Improved the Inspector layout and added descriptions of each of the support links.
- It now includes the Animancer Version in its name to better detect if the user did not delete a previous version before updating (since Unity's package importer will overwrite old files but not rename them).
- Renamed
Simple Playingto Quick Play. - Added
Hybrid Basicsto demonstrate theHybridAnimancerComponentin a simple situation without the complexity of a full state machine inHybrid Mini Game. - Improved
Sequence Coroutine:- It now uses the new custom end time system rather than needing a
ClipTransitionsubclass with its ownPlayDurationfield. - Added assertions for reliability.
- It now uses the new custom end time system rather than needing a
- Improved
Speed and TimeandDirectional Blending:- They now use a shared
SpiderBotbase class and demonstrate polymorphism. SpiderBotAdvancednow follows the mouse cursor so it can truly move in any direction rather than being limited to 8 directions with WASD.- Cleaned up the animation names to match the same convention as others.
- They now use a shared
- Improved
RootMotion:- It now overrides
Transition.Applyto set the root motion flag so the caller doesn't need to do it. - It now has some extra fields to specify another object to apply the root motion to.
- It now overrides
Linear Blendingnow uses Transition Assets.- Directional Basics now uses a serialized field so its initial facing direction can be set in Edit Mode and it now has a dedicated Play method which takes a
DirectionalAnimationSetinstead of callingGetClipin each location it wants to play something. - Renamed the "Animation Events" group to Events (since they now demonstrate Animancer Events as well).
- Renamed "Simple and End Events" to Golf Events and updated it to demonstrate regularAnimation Events, a
SimpleEventReceiver, Animancer Events defined in the Inspector, and Animancer Events with their times se in the Inspector and callbacks set in code. - Renamed "Other Events" to Footstep Events and reordered it to come before "Golf Events".
- It now includes Animancer Events and much more detail about how to set everything up.
Brain Transplantsnow enables and disables the brains in code when swapping them instead of using theUnityEvents on the UI Buttons. #10- Improved
Platformer:- Added an introduction sequence using Timeline.
- Jumping now uses a specific target height rather than an arbitrary amount of force.
- It now allows the player to jump higher by holding the button longer.
- Reviving the character now plays the death animation backwards.
- Improved the Inverse Kinematics examples:
- Changed
StartingPositionstoTransformResetterand it now resets rotations as well. - Improved
RaycastFootIKto account for the foot rotation when calculating the raycast diration.
- Changed
Hybrid Mini Gamenow has the character walk into and out of the mini game rather than teleporting.- Improved 3D Game Kit:
- It is now based on the 3D Game Kit Lite since the full version is a massive pain to download and import. #11
- It now shows which system (Animancer or Mecanim) is active and lets you swap between them with keyboard controls instead of UI Buttons.
- It now uses custom end times as part of each transition rather than End Animation Events or separate end time fields.
- The root object is now separate from the model with
RootMotionRedirectpassing on the root motion. AirborneStateandLandingStatenow use Mixers instead of Blend Trees since they are more convenient to use and can give the same result now that time synchronization has been implemented.- Added
FlinchStateandDieState. - Attacks can how kill enemies and destroy objects and do not use a custom transition class.
- Removed the copy of
RandomAudioPlayerand usedUnityEvents to access the existing script. - Removed the copy of
AttackTrailand usedUnityEvents to access the existingTimeEffectscript.
- Added
[DefaultExecutionOrder]attributes to allCharacterexamples as well as comments inAwaketo reinforce its importance.
Internal
- Added 150+ unit tests using the Unity Test Framework. The tests are not planned for release so they will not directly matter to users, but they will help reduce the possibility of bugs making it to release.
- Changed
AnimancerNode.Stopfromabstracttovirtualso it can setWeight = 0by default since bothAnimancerLayerandAnimancerStatedid so. - Moved the functionality to constantly repaint in Edit Mode from the manual update loop to
AnimancerPlayableEditor.RequiresConstantRepaint. - Split
AnimancerPlayableEditorintoBaseAnimancerComponentEditorandAnimancerPlayableDrawerto the preview window can draw itsAnimancerPlayablewithout actually having anAnimancerComponent. - Moved
FastComparerout ofAnimancerPlayable. - Changed
AnimancerLayer.DestroyStatesandManualMixerState.DestroyChildrento iterate in reverse order. - Moved
AnimancerEditorUtilities.GUIStylesout toAnimancerGUIand moved all GUI utilities there.- Renamed
GetLayoutRecttoLayoutSingleLineRect. - Added
paddingparameter toStealFromLeftandStealFromRight.
- Renamed
- Changed parameter references in comments to use the `grave accent` instead of 'single quotes'.
- Added
ConversionCacheto replace various other caching systems throughout Animancer. - Added
TemporarySettingsfor storing information between assembly reloads without needing to save it when Unity closes.- Currently it is used to store details about which Animancer Events are selected in the Inspector.
- Added
ITransitionDetailed : ITransitionto expose additional details for previewing.
- Added
KeyandKey.KeyedList:- Changed
AnimancerNodeto inherit fromKeyand replaced the dirty node update list with a keyed list which greatly cleans up that part of the system. - Changed
IEarlyUpdateintoIUpdatablewhich implementsIKeyHolderand replaced its list with a keyed list as well. - Removed the
needsMoreUpdatesparameter fromIUpdatable.Updatesince they can be immediately removed at any time byAnimancerPlayable.CancelUpdate.
- Changed
- Added a simple
ObjectPoolsystem to allow easy reuse of objects. If you want a more powerful general purpose system, check out Weaver. - Refactored the
AppendDescriptionsystem in the core classes to be cleaner and produce better descriptions. - Added
Serializationclass which contains various utilities relating to serialization:Serialization.PropertyAccessorallows access to the underlying object of aSerializedProperty.Serialization.ObjectReferenceacts as a stronger serializable reference to aUnityEngine.Object. A simpleObjectfield can lose its value under certain circumstances even if the referenced object still exists, for example when entering Play Mode.Serialization.PropertyReferenceis a serializable reference to aSerializedProperty.
- Moved the custom GUI for the
Start TimeandSpeedfields to the baseTransitionDrawer. - All calls to
EditorGUI.Foldoutnow setEditorGUIUtility.hierarchyMode = trueto ensure that the arrow gets the correct indentation.

