Animancer v7.0

Released 2021-07-29

Upgrade Guide

See the Animancer v6.0 Upgrade Guide if you are upgrading from a version older than that, then follow the Upgrade Process explained below to upgrade to this version.

Major Changes

  • Support for Unity 2018.4 has been dropped. The minimum supported version is now 2019.4 (though it might still work on earlier 2019 versions).
  • All Transition Scripts have been moved and renamed (see the Renaming table).
  • Transition Assets now use [SerializeReference] fields. Unfortunately, this means that all Transition Assets will lose their data when upgrading from an earlier version of Animancer.

Click here for more information about these changes and why they were necessary:

Why drop support for Unity 2018?

  • The [SerializeReference] system was only introduced in Unity 2019. Continuing to support 2018 would be possible using Platform Dependent Compilation, but would significantly complicate certain sections of code as well as the testing and releasse process of Animancer as a whole (much moreso than simply adding another supported version would).
  • Animancer v7.0 is already being specifically tested in 3 other versions of Unity:
    • 2019.4 (LTS)
    • 2020.3 (LTS)
    • 2021.1 (Latest Stable)
  • Unity 2018.4 is currently still listed in Unity Hub, but it has already exceeded its 2 year LTS lifespan so new projects should not be started with it. Existing projects will either need to stay on an older version of Animancer or update to a newer version of Unity first.

What benefits have the change brought?

Why were the Transition Scripts moved?

  • [SerializeReference] fields store the full type and assembly name of the value they are assigned.
  • Previously, those classes were compiled into Animancer.Lite.dll for Animancer Lite while Animancer Pro included them as regular scripts.
  • That meant upgrading from Lite to Pro would change the assembly name, causing all [SerializeReference] fields to both lose their data and log errors about it in the console, which is unacceptable. The upgrade process from Lite to Pro must be as seamless as possible.
  • So all Transition Scripts have been moved to the Utilities/Transitions folder and their source code is now included in Animancer Lite.

Why were the Transition Scripts renamed?

  • Since they are now in a different assembly from the State classes, the Transition classes can no longer be nested inside them.
  • With ClipState.Transition no longer being inside ClipState it obviously can't just be called Transition so the logical choice is ClipTransition.
  • Unfortunately, ClipTransition was previously the Transition Asset type, so it also had to be renamed to ClipTransitionAsset.
  • All transition types follow the same naming convention, which is listed in the Renaming table.

Upgrade Process

It is recommended to avoid updating Animancer in the middle of the project unless absolutely necessary. More-so for this version than usual because steps #5 and #6 in particular could take a long time.

  1. See the Animancer v6.0 Upgrade Guide if you are upgrading from a version older than that.
  2. Backup your project.
  3. Update your project to Unity 2019.4 or newer.
  4. Delete your previous version of Animancer (located at Assets/Plugins/Animancer by default). This will cause compile errors in any of your scripts that reference Animancer.
  5. Go through your scripts and change the names of Animancer classes according to the Renaming table.

6. If you have any Transition Assets, you can manually edit them with a text editor to prevent them from losing their data. Click here for an explanation of how to do that.

The issue is that the [SerializeField] stores its data in a slightly different format to [SerializeReference] and Unity doesn't support conversion between them. However, the format is relatively simple so you can open any Transition Asset files with any text editor and make the following change. This can be much easier with a file comparison tool in a version control system.

The old format looks like this:

  _Transition:
    _FadeDuration: 0.25
    // ... Other fields in the transition.

And the new format looks like this:

  _Transition:// The actual field
    id: 0// The index of the reference
  references:// The list of all references
    version: 1
    00000000:// The id: 0 refers to this reference
      type: {class: ClipTransition, ns: Animancer, asm: Animancer}// The assigned type
      data:// The actual data all looks the same
        _FadeDuration: 0.25
        // ... Other fields in the transition.

So there are 3 changes to make:

  1. Replace the _Transition: line with:
  _Transition:
    id: 0
  references:
    version: 1
    00000000:
      type: {class: ClipTransition, ns: Animancer, asm: Animancer}
      data:
        _FadeDuration: 0.25
  1. Replace that ClipTransition with the appropriate type for the asset (e.g. if the asset is a LinearMixerTransitionAsset then the type will need to be LinearMixerTransition).
  2. Add 4 spaces to the start of every line after that (starting with the _FadeDuration:) because the indentation is important.

  1. Download and import the new version of Animancer.
  2. If you still have any compile errors, use Ctrl + F to search this page for any relevant changes.

Renaming

Make sure you rename Transition Assets first (ClipTransition to ClipTransitionAsset) before doing any regular Transitions (ClipState.Transition to ClipTransition) to avoid confusion.

Old Name New Name
ClipTransition
ControllerTransition
Float1ControllerTransition
Float2ControllerTransition
Float3ControllerTransition
LinearMixerTransition
ManualMixerTransition
MixerTransition2D
PlayableAssetTransition
ClipTransitionAsset
ControllerTransitionAsset
Float1ControllerTransitionAsset
Float2ControllerTransitionAsset
Float3ControllerTransitionAsset
LinearMixerTransitionAsset
ManualMixerTransitionAsset
MixerTransition2DAsset
PlayableAssetTransitionAsset
ClipState.Transition
ControllerState.Transition
Float1ControllerState.Transition
Float2ControllerState.Transition
Float3ControllerState.Transition
LinearMixerState.Transition
ManualMixerState.Transition
MixerState.Transition2D
PlayableAssetState.Transition
ClipTransition
ControllerTransition
Float1ControllerTransition
Float2ControllerTransition
Float3ControllerTransition
LinearMixerTransition
ManualMixerTransition
MixerTransition2D
PlayableAssetTransition

Everything in the Examples with Creature in its name has been renamed to Character.

Various other things have been renamed but they are generally minor and/or internal so much less likely to be referenced by user code. If you get such errors after importing the new version of Animancer, simply use Ctrl + F to search this page.

Major Features

Platformer

Removed the old Platformer example and created a much more extensive Platformer Game Kit which has much better character physics, wall jumping, moving platforms, a hit box system, various enemies with different behaviours, and more. It's free and works with Animancer Lite, though it does use some Pro-Only features (explained here).

Old Platformer Example New Platformer Game Kit

Time Fields

Improved the way Transition Time Fields are drawn in the Inspector:

  • Added a Frame field so they now show their value as Normalized, Seconds, and Frames.
  • Standardised the implementation in a base Units Attribute with [AnimationTime] and [AnimationSpeed]subclasses.
  • Used the same implementation for the Normalized/Pixel fields in the Sprite Editor.
  • Added options in AnimancerSettings to choose which fields are shown.
  • These fields now show Approximations if there is not enough room to show the full value. For example, 1.111111 could instead show 1.111~.
  • You can now Middle Click any of these fields to set them to their Default Value (or a secondary default if they were already at the primary value).
  • Improved the tooltips on all Transition Fields.

Units Attributes

The Units Attributes can be used on float fields to give them a suffix indicating what kind of units they represent.

They allow the value to be displayed in multiple units at the same time:

You can Middle Click to reset the field to its [DefaultValue]:

And you can specify a Validate.Value rule to limit the allowed values:

Weight Fields

Improved the way abbreviated weight labels are displayed in the AnimancerComponent Inspector. In particular, small values near 0 which aren't exactly 0 will show as ~0 instead of 0.0. The same applies to values near 1. #131

UnShared Transition Assets

Added UnShared classes to solve issues with the State and Events on shared Transition Asset. #112

Serialized References

Added Polymorphic Drawer system to allow the type of a [SerializeReference] field to be selected. These are used by Transitions, but you can also use them in your own code to avoid needing to write custom drawers.

Changed Transition Assets to use a [SerializeReference] for their Transition field so that child types can be used without requiring their own Transition Asset and UnShared classes.

Also added ITransition interfaces for each state type. For example:

Improved Transition Event Inspector

Improved the way Transitions display events in the Inspector:

  • Selecting and deselecting them now animates their visibility rather than suddenly changing the fields that are shown.
  • Holding Ctrl while dragging an event now snaps its time to the nearest multiple of the animation's frame rate.

Preview Time Buttons

When the Transition Preview Window is open, all time fields show a button on the right:

  • Left Click it to make the preview show that time.
  • Right Click it to set the field to use the current preview time.

This applies to event times too, which helps massively with getting the values aligned precisely where you want them.

Custom Preview GUI

Added ITransitionGUI which can be implemented by transitions to modify their preview scene (to do things like drawing hit boxes in the preview).

The video below shows the hit box editing system in the new Platformer Game Kit:

Animation Clip Inspector

Added a custom Animation Clip Inspector to improve the way AnimationClips are displayed in the Inspector:

Unity Default Animancer

There are also a few features specific to Sprite animations:

  • Shows the Sprite and details of each frame in the animation.
  • Automatically initializes the preview so you don't need to manually drag and drop an object with an Animator and SpriteRenderer into the preview area.
Unity Default Animancer

Runtime Events Display

  • Added Events display to the Live Inspector for states that have Animancer Events.
  • Added Runtime Events display to Transitions that have initialized their AnimancerEvent.Sequence.

Examples

  • Added Transitions example.
  • Added Event Utilities example.
  • Added Units Attributes to the example scripts where appropriate.
  • Removed the Sequence Coroutine example since it was really long, spent lots of time explaining coroutines (there are plenty of other tutorials for that), and wasted time explaining several different approaches which are all worse than simply using a ClipTransitionSequence.
  • Removed the Walk and Run example since Linear Blending does the same job better.
  • Removed the PixelPerfectPositioning script since Unity's 2D Pixel Perfect package is better (now that they have inbuilt Time Synchronization).
  • Renamed the More Brains example to Brain Transplants.
  • Renamed everything with Creature in its name to Character.
  • Changed the Linear Blending example to use the new UnShared Transition Asset system.
  • Changed the Brains example LocomotionState to use a Linear Mixer instead of manually synchronizing the Walk and Run animations.
  • Changed all [DefaultExecutionOrder] attributes to use constants so they can directly reference each other's values if they are related.
  • Improved the Layers script to allow the running state to be toggled without interrupting the action.
  • Fixed the Humanoid-GolfSwingReady animation to have 0 length (somehow it was 0.000000059604645 seconds long).
  • Fixed the Door example script to be usable in prefabs.
  • Fixed the Hybrid Basics example to disable OptionalWarning.NativeControllerHumanoid.

Minor Features

  • Added DontAllowFade for easily detecting accidental fades on Sprite based characters (often due to the default Fade Duration on transitions).
  • Added AnimancerUtilities.EditModeSampleAnimation to replace the pauseImmediately parameter from EditModePlay.
    • Changed the SoloAnimation component to automatically apply the first frame of its animation in Edit Mode.
    • Added an Apply In Edit Mode field to prevent it from doing that if you don't want it to.
  • Added wrapper methods in ControllerState for all the methods you would normally access on its Playable (so you can call state.Play(...) instead of state.Playable.Play(...)).
  • The CustomFade system can now be applied to layers rather than only states.
  • Added ExitEvent system. #117
  • Added AnimancerPlayable.UpdatableCount and GetUpdatable.
  • Added AnimancerUtilities.Assert which throws an exception (unlike Debug.Assert) and used it where appropriate.
  • Added AnimancerState.MoveTime which sets the Time and applies any Root Motion and Animation Events (but not Animancer Events) between the old and new time. #120
  • Added support for Animancer Events on states in Mixers.
  • Changed AnimancerPlayable.DefaultFadeDuration to a property instead of a constant so it can be modified externally.
    • Animancer Lite only allows it to be set to 0 or 0.25.
    • Restructured various places it was used that require constants (attributes and default parameters).
    • Added [DefaultFadeValue] for the FadeDuration field in Transitions.
  • Added TimelineGUI.Current property to access the current drawer context.
  • Added IPlayableWrapper.NormalizeChildWeights extension method.
  • Added ClipTransitionSequence.EndEvent to easily access the end event of the last transition in the sequence.
  • Added support for inheritance in [SerializeReference] fields to the Serialization system.
    • Made Serialization.PropertyAccessor.Field and FieldType private and added GetField and GetFieldElementType methods so that it can support [SerializeReference] fields where inheritance might prevent the FieldInfo from being accessible just based on the field type.
    • Fixed Serialization.PropertyAccessor.ResetValue to run the constructor of the field's current type so that it can reset [SerializeReference] fields to the defaults of the current type instead of null.
  • Added AnimancerEditorUtilities.GetNameCS for displaying user-friendly type names.
  • Improved Transition Preview Window:
    • While playing, the preview time indicator in the TimelineGUI is now properly updated.
    • Fixed time scrubbing for negative speeds.
    • Modifying any Time Field in a Transition's Inspector now sets the preview to that time (if the modified Transition is the one being previewed).
    • Modifying any field in a Transition now updates the preview to show the change.
    • Added TemporarySettings.PreviewModels so it can remember scene objects used for previews as long as they still exist.
    • It now shows a warning when the selected model has no Animator component.
    • Added Preview Context Menu Function to AnimationClip assets so they can be previewed directly without needing a Transition.
  • Improved [EventNames] attribute to allow it to be placed on the transition class itself. For example, every ProjectileAttackTransition in the Platformer Game Kit should have a "Fire" event, so putting the attribute on that class avoids the need to put it on every ProjectileAttackTransition field.

Changes

  • Changed the default NormalizedStartTime for Transitions to be 0 (start at beginning) instead of NaN (continue from current time).
  • Reworked IUpdatable:
    • Merged EarlyUpdate and LateUpdate into Update.
    • Removed OnDestroy since it was only used by AnimancerState.EventDispatcher. Destroying the graph while events are in use will simply allow the dispatcher to be garbage collected instead of going out of its way to ensure that they always get object-pooled. Destroying the graph will generally only happen when the object is destroyed, so there is going to already be a bunch of garbage collection anyway.
    • The time it gets called is chosen by using either AnimancerPlayable.RequirePreUpdate or RequirePostUpdate.
    • AnimancerNode now implements IUpdatable so it can use the same loop as custom objects instead of needing separate loops.
    • AnimancerState.EventDispatcher now stores the previous time at the end of its (post) Update instead of doing it in PreUpdate (which was why both methods used to be separate).
  • Renamed TimeRuler to TimelineGUI.
  • Renamed AnimancerEvent.Sequence.Serializable.Sequence to Events.
  • Moved AnimancerState.EffectiveWeight to AnimancerNode.
  • Moved IKeyedListItem into Key and renamed it to IListItem.
  • Moved AnimationBindings.IsChangingPlayMode into AnimancerEditorUtilities since it's also used by the Transition Preview Window.
  • Moved unnecessary ITransitionDetailed members out to separate interfaces:
    • IHasEvents: Events, SerializedEvents.
    • IMotion: AverageAngularSpeed, AverageVelocity. Removed these from AnimancerState and only implemented them in ClipState and MixerState.
    • Removed BaseState and MainObject.
  • Changed the DirectionalAnimationSet methods like SetLeft, SetRight, etc. to use regular property setters but include an assertion that AllowSetClips must have been called beforehand to avoid accidentally modifying the set (since they are assets and will retain any such changes after leaving Play Mode).
  • Removed various methods in AnimancerEditorUtilities which are no longer being used: ShouldAllowReference, Invoke, RegisterNonCriticalIssue, RegisterNonCriticalMissingType, RegisterNonCriticalMissingMember, AppendNonCriticalIssues.
  • Removed AnimancerEvent.Sequence.RemoveAll since it is unlikely to be useful (it was the same as Clear without removing the end event).
  • Removed GUIElementWidth since it wasn't used much and didn't offer much benefit.
  • Removed AnimancerEditorUtilities.GetCachedResult and replaced it with manual caching.
  • Made ConversionCache Editor-Only.
  • Removed usage of the new() generic constraint where possible because it is actually quite inefficient.
    • Removed AnimancerUtilities.NewIfNull. Unfortunately, Unity doesn't yet support the ??= operator.
  • Removed AnimancerPlayable.StateDictionary.Create<T> and AnimancerLayer.CreateState<T> since they didn't do much more than new T() anyway.
  • Removed maxChildDepth parameters from AnimancerNode.GetDescription and AppendDescription methods since they were basically pointless.
  • Replaced AnimancerGUI.TempContent with ObjectPool.Disposable.AcquireContent.
  • Optimized the usage of AnimancerPlayable.LayerList._Layers so it doesn't need to be null-checked. This also means that to set the starting Capacity you should set the AnimancerPlayable.LayerList.DefaultCapacity before the LayerList gets created so that it doesn't create an array in the constructor then disard it as garbage when allocating a new one for the new capacity.
  • Reduced the interface and generic constraints on AnimancerTransition.
  • Cleaned up the ObjectPool system:
    • Standardised methods so all categories (object, list, set) have T Acquire(), void Acquire(out T), Release(T), and Release(ref T) methods.
    • Renamed ObjectPool<T>.SetMinCount to IncreaseCountTo.
    • Added ObjectPool<T>.IncreaseCapacityTo.
    • Moved ObjectPool.GetCachedResult to AnimancerEditorUtilities.
    • Changed ObjectPool.Disposable into a struct to avoid the need for a LazyStack.
  • Changed AnimancerState.EventDispatcher to be public.
    • Removed AnimancerState.EventPoolCapacity, EventPoolCount, and SetMinEventPoolCount since ObjectPool<AnimancerState.EventDispatcher> can now be accessed directly.
  • Refactored AnimancerEditorUtilities.GetComponentInHierarchy:
    • Moved it to AnimancerUtilities.
    • Renamed it to GetComponentInParentOrChildren.
    • Changed it into a GameObject Extension Method.

Improvements

  • Improved the way Inspector field widths in Mixer Transitions adjust to large windows. #90
  • Replaced empty array creation with Array.Empty.
  • Improved enumerator implementations:
  • Reworked ReadMe to be inheritable (so the Platformer Game Kit can use the same structure).
  • Added AnimancerUtilities.IsNullOrEmpty and SetLength for arrays.
  • Added IsValid properties for Mixer Transitions.
  • Added IPlayableWrapper.Weight.
  • Added IWrapper for Transition Assets and UnShared references to use the details of their transition without re-declaring all the members and restricting the allowed generic arguments.
  • Added a specific NullReferenceException to AnimancerTransition.Events if the SerialilzedEvents is null.
  • Added AnimancerEditorUtilities.ToStringCached for reducing garbage when converting floats to strings.
  • Added AnimationGatherer.logExceptions to control whether exceptions during gathering should be logged (default is to ignore them). This replaces the old system which kept all exceptions in a list so that the Transition Preview Window could display them.
  • Replaced most GUI.enabled access with EditorGUI.DisabledScope.
  • OptionalWarning:
    • Added Validate.PermanentlyDisabledWarnings which can be accessed manually in the Settings panel of the Animancer Tools Window or the Inspector of the AnimancerSettings asset.
    • Improved the warning message for OptionalWarning.DuplicateEvent.
    • Added OptionalWarning.UselessEvent for detecting empty events.
    • Added OptionalWarning.NativeControllerHumanoid for when an Animator's Controller field is assigned on a Humanoid Rig and NativeControllerHybrid for when an Animator's Controller field is assigned while also using a HybridAnimancerComponent.
  • Improved the formatting of AnimancerEvent.ToString and AppendDetails.
  • Improved the formatting of AnimancerEvent.Sequence.DeepToString.
  • Removed the AnimancerSettings creation message since it wasn't very useful and could easily distract new users.
  • Improved AnimancerEvent.Sequence:

FSM

  • Improved the Finite State Machine documentation.
  • Improved the StateChange and KeyChange system:
    • Extremely minor performance optimizations.
    • Added StateChange<TState>.StateMachine for accessing the StateMachine that the change is occurring in.
    • Added IKeyedStateMachine<TKey> for accessing keyed state machines without their state type. Specifically, this allows KeyChange<TKey> to hold the StateMachine without needing a TState parameter.
    • Improved the error message given when the incorrect type of change is accessed to make it clearer what needs to be fixed and give a link to the documentation.
    • The change structs now implement IDisposable so they can be used in simple using statements instead of needing a call to Begin followed by a try/finally block which manually calls End. This makes the usage in the StateMachine classes much neater.
  • Optimized StateMachine<TKey, TState>.TrySetState to not allocate any garbage (it used to box the keys to call object.Equals).
  • Added StateMachine<T>.WithDefault to simplify the common pattern of initializing it in an Idle state and caching a ForceIdleState delegate for events to use.
    • This removes the need for a [DefaultExecutionOrder] attribute on the various Character classes in the examples.
    • It also allows for easy implementation of an optional starting state separate from the default state such as in the Platformer Game Kit where the starting state is Introduction but the default state that others return back to is still the usual Idle.
  • Added StateMachine<TState> methods which take an IList<TState> to call CanSetState, TrySetState, or TryResetState on each of them until one succeeds.
  • Added Animancer.FSM.ReverseComparer.
  • Changed StateSelector to inherit from SortedList<float, TState> and use the ReverseComparer.
    • A state change can be attempted by passing the StateSelector.Values into any of the StateMachine methods that take an IList.
    • It no longer allows multiple states to have the same priority.
    • Its implementation is now much simpler.
  • Reworked the InputBuffer classes:
    • Replaced TrySetState with Buffer which just sets the state but doesn't try to enter it since that is handled by Update at the end of the frame.
    • The StateMachine can now be changed after the constructor.
    • Renamed BufferedState to State.
    • Renamed BufferedKey to Key.
    • Renamed IsBufferActive to IsActive.
    • Removed UseUnscaledTime since you can just pass Time.unscaledDeltaTime into Update if you want to use it.
    • Removed CheckBuffer since you can just call Update(0).
  • Changed DelegateState to use public virtual implementations of IState members instead of explicit implementations.

Fixes

  • [Lite-Only] Added FixProjectDefinition to prevent the C# project files generated by Unity 2020+ from referencing the Runtime-Only Lite DLLs.
  • Fixed setting the AnimancerState.Time before its Playable is created to properly assign it when it does get created.
  • Fixed PlayableAssetState to not cause exceptions in Unity 2021.1 due to its Playable duration not being set.
  • Fixed AnimancerPlayable.KeepChildrenConnected to properly apply to the AnimancerPlayable.PostUpdate.
  • Fixed ArgumentOutOfRangeException in EventSequenceDrawer when dragging the end event if there were no other events and it was previously at its default value.
  • Fixed NullReferenceException caused by accessing AnimancerGUI during a static constructor since it tried to access EditorStyles.miniButton.
  • Fixed SpriteEditor to properly display newly applied values.
  • Fixed PlayableAssetTransition.FadeMode to always use FixedSpeed because FromStart is only supported for ClipStates.
  • Fixed EventNamesAttribute to consider the type of each value in the property chain.
  • Fixed AnimancerEvent.GetFadeOutDuration to properly account for speed.
  • Fixed AnimancerEvent.Sequence.SetName to allocate the full Capacity when expanding the array.
  • Fixed AnimancerEvent.Sequence.Add and Remove to properly manage the Names array.
  • Fixed AnimancerEvent.Sequence.Remove to correctly clear the name when removing the last event.
  • Fixed AnimancerEvent.Sequence.SetCallback to give an error message when attempting to set it to null to explain that AnimancerEvent.DummyCallback can be used instead.
  • Fixed AnimancerEvent.Sequence.Serializable to always ensure its event data is sorted even when not set by the GUI.
  • Fixed AnimancerEvent.Sequence.Serializable.Events to not be cleared continuously when viewed in the Inspector and to be properly updated when making modifications.
  • Fixed adding persistent calls to an AnimancerEvent to properly assign its Invoke method to the runtime sequence in place of AnimancerEvent.Dummy.
  • Fixed SerializableEventSequenceDrawer so that modifying event names properly modifies the runtime sequence.
  • Fixed potential NullReferenceException in AnimancerEvent.Sequence.Insert.
  • Fixed potential NullReferenceException in AnimancerPlayable.GetKey.
  • Fixed AnimancerPlayable.SetOutput to throw an exception if the specified Animator component is null or if it's a prefab.
  • Fixed AnimancerUtilities.EditModePlay to do nothing if the target is a prefab.
  • Fixed ManualMixerTransition.Apply to call Apply on any child states created by transitions.
  • Fixed the LinearMixerState threshold calculation function Evenly Spaced to give usable thresholds if the first and last have the same value.
  • Fixed ControllerState.ValidateHasParameter to skip Animator Controllers loaded from Asset Bundles because they don't contain the editor-only data needed to perform the validation. #123
  • Fixed EventSequenceDrawer.DoTimeGUI to not cause End Time fields to set the preview time when they are deselected.
  • Fixed various issues in TimelineGUI:
    • Fixed fade display to properly account for speed and display correctly when Speed is NaN.
    • Fixed it to correctly show loop increments of the current preview time.
    • Fixed it to not show preview loop time indicators if they would be too close together to be useful.
  • Fixed various issues in the Transition Preview Window:
    • Fixed the Icon to be appropriate for the Unity Editor's Dark Theme.
    • Fixed TransitionPreviewWindow.Animations.PlayOther to not attempt to assign infinity values to the AnimancerState.NormalizedTime.
    • Fixed model selection to not cause an exception if there are missing models.
    • Fixed model selection to not accept a best match model unless at least half of the bindings match.
  • Fixed TransitionDrawer and TransitionPreviewWindow to support [SerializeReference] fields.
  • Fixed Transitions to allow Inspector Gadgets Nested Object Inspectors for their main asset (the AnimationClip for a ClipTransition, the AnimatorController for a ControllerTransition, etc.).
  • Fixed dragging Animancer Events in Unity 2019.4+ to keep the correct event selected when they get sorted (because they need to be ordered by time).
  • Fixed fade duration not being affected by Time.timeScale in Unity 2021. #129
  • Fixed SoloAnimation to only play when enabled rather than in Awake.
  • Fixed several bugs in Key.KeyedList and improved comments.
  • Fixed AnimancerSettings to not be lost when upgrading from Animancer Lite to Pro.
  • Fixed AnimancerToolsWindow.PackTextures to not throw an exception if any of the textures in the list are null.
  • Fixed AnimancerToolsWindow.SpriteModifierPanel to work for SpriteImportMode.Single.
  • Fixed ClipTransitionSequence to account for the full sequence in IsValue, IsLooping, MaximumDuration, AverageAngularSpeed, AverageVelocity, and GatherAnimationClips.
  • Fixed ClipTransitionSequence to allow for the possibility that the first transition's End Event could be set and reassign that callback to the last transition instead.
  • Fixed ClipTransitionSequence to properly initialize its end events in case the runtime sequence gets initialized multiple times.
  • Fixed TransitionDrawer to only target ITransitionDetailed rather than ITransition since it needs the extra details.
  • Fixed TransitionPreviewWindow auto-close to not cause GUI errors.
  • Fixed Validate.AssertPlayable to destroy an invalid node.
  • Fixed potential NullReferenceException in Serialization.PropertyReference.
  • Fixed BoolPref to properly load its value if it gets shown in a menu before being accessed.