Animancer v8.0 Upgrade Guide

What happenned?

  • Animancer v8.0 has been released as a separate asset from the old version.
  • The regular price is still $90 USD.
    • Users who purchased the old version after this message was posted (2024-05-01) can upgrade for free.
    • Other users who purchased before that will receive a 50% discount to upgrade.
    • For the Unity Asset Store, these discounts are automatically applied.
    • For itch.io, the 50% upgrade discount is automatically applied. Unfortunately, they don't have a system for differentiating users based on purchase date so if you purchased after the free upgrade date you will need to request an upgrade from animancer@kybernetik.com.au using the email address you used to make the purchase on itch.
  • Future updates will be free unless another major version has significant features which I may decide to charge for again.

What if some users want to stay on the old version?

  • The old version has been deprecated so new users can no longer purchase it but existing users can still download it.
  • Animancer v7.4 was stable for over a year so it will remain usable in Unity 2019 to 2023.
    • It may work in newer versions, but will not be updated if there are issues.
    • It has no known critical issues but many minor ones (i.e. the Animancer v8.0 Fixes list) and will not receive any more updates.
  • Support will be limited:
    • The documentation has been updated for the latest version, but Wayback Machine still has the old version.
    • Questions about how to do do things in the old version will still be answered, though the answer may include upgrading if newer versions have features that would help.
    • Bug reports and anything complex enough to require sending me a project to look at will generally be rejected without investigation.

Why charge for this update as a separate asset?

There's really two questions in that:

Why release this update as a separate asset?

Unity doesn't have a way for me to warn users about breaking changes before they update so forcing everyone to manually get a new asset is the only viable way to avoid the hassle and negative reviews I've received in the past.

The main breaking changes include:

  • The minimum supported Unity version is now 2022.3.
  • Your Assembly Definitions will lose their references to Animancer unless you had "Use GUIDs" enabled.
  • Animancer Events have been reworked to no longer get automatically cleared whenever you play something, you're expected to configure the necessary events when a state is first played. This is a significant change which will require everyone using events to rethink their scripts.
  • A lot of serialized data has been changed and would be lost without the Serialized Data Migration tool which needs to be run manually and isn't 100% reliable.
  • The Custom Fade system has been completely replaced by Fade Groups.
  • Many APIs have been renamed.

Why charge existing users for this update?

  • This version has more significant new features than any previous one and the necessity to release it as a separate asset makes this an appropriate time to charge as many other assets do for major updates.
  • Developing and supporting Animancer costs me a lot of time and energy. I'd love to be able to give it away for free, but I can't justify spending most of my free time on it without earning some income from it.

How to Upgrade

Updating a project from an earlier version of Animancer to v8.0 is not recommended if you can avoid it since there are so many large changes, but if you decide to do so then please follow this process closely:

  1. Backup your project. Using a Version Control system such as Git is strongly recommended in general.
  2. Update to Unity 2022.3 or later (the minimum required by Animancer v8.0).
  3. Delete your old version of Animancer (it should be in Assets/Plugins/Animancer unless you moved it).
  4. Import the new version of Animancer (it will import into Packages/com.kybernetik.animancer).
  5. Fix all your Assembly Definitions that reference Animancer.
  6. Fix all your scripts that have compile errors due to Animancer's API changes.
  7. Run the Serialized Data Migrator.
  8. Read the Behaviour Changes section and edit your scripts accordingly.

Reading the full Change Log is also a good idea to understand any of the smaller changes that may affect your project.

Package Structure

Animancer has been moved from Assets/Plugins into the Packages folder so that other packages can reference it.

Old Package Structure New Package Structure

Note how the Samples folder is hidden by default. The Samples page explains how to import them.

Assembly Definitions

Moving into the Packages folder wouldn't cause any issues on its own, however assemblies in packages are recommended to follow the naming convention CompanyName.ProductName so Animancer's assemblies have been renamed to follow that standard (from Animancer... to Kybernetik.Animancer...).

If you have any Assembly Definitions which reference Animancer but don't have Use GUIDs enabled, they will lose that reference and you will need to re-assign it. Enabling Use GUIDs is generally recommended to avoid this issue in the future.

Old Assembly Reference New Assembly Reference

Note that some Editor-Only scripts have been split into Kybernetik.Animancer.Editor so you may need to reference it as well as (or instead of) the runtime Kybernetik.Animancer assembly.

API Changes

After fixing the references in all your Assembly Definitions, you might get compile errors due to changes in Animancer's APIs. This section explains those changes and how to fix them.

Renaming

Some changes involve simply renaming things:

Old Type New Type
AnimancerPlayable AnimancerGraph
AnimancerPlayable.LayerList AnimancerLayerList
AnimancerPlayable.StateDictionary AnimancerStateDictionary
IPlayableWrapper AnimancerNodeBase
AnimancerTransition Transition
AnimancerTransitionAssetBase TransitionAssetBase
AnimancerTransitionAsset
ClipTransitionAsset
ControllerTransitionAsset
Float1ControllerTransitionAsset
Float2ControllerTransitionAsset
Float3ControllerTransitionAsset
LinearMixerTransitionAsset
ManualMixerTransitionAsset
MixerTransition2DAsset
PlayableAssetTransitionAsset
All Transition Asset types have been consolidated into TransitionAsset which can contain any Transition Type thanks to the Polymorphic Drawer system.
Float1ControllerState
Float2ControllerState
Float3ControllerState
ControllerState with Parameter Binding.
Float1ControllerTransition
Float2ControllerTransition
Float3ControllerTransition
ControllerTransition with Parameter Binding.
ControllerState.DampedFloat
ControllerState.ParameterID
MixerParameterTween
SmoothedFloatParameter and SmoothedVector2Parameter which work with the new Parameter Binding system.
Old Member New Member
AnimancerComponent.Playable AnimancerComponent.Graph
AnimancerNodeBase.Root AnimancerNodeBase.Graph
AnimancerPlayable.KeepChildrenConnected AnimancerGraph.SetKeepChildrenConnected(bool)
AnimancerPlayable.PreUpdatableCount AnimancerGraph.PreUpdatables.Count
AnimancerPlayable.PostUpdatableCount AnimancerGraph.PostUpdatables.Count
AnimancerPlayable.DestroyGraph() AnimancerGraph.Destroy()
AnimancerState.SetRoot(AnimancerPlayable) AnimancerState.SetGraph(AnimancerGraph)
AnimancerState.Events See Persistent Owned Events

Transition Assets

The classes inheriting from AnimancerTransitionAsset for each specific transition type have been removed because TransitionAsset has a [SerializeReference] field which lets you pick any type of transition anyway so those classes were mostly superfluous clutter.

UnShared Transitions

The UnShared transition classes have been entirely removed since the new Persistent Owned Events system is much easier to understand and works in a wider variety of situations.

Any TransitionAssetType.UnShared field you had can simply be changed into a direct reference to a TransitionAsset.

  • Any interactions with the Events property of that field will need to be moved to the state after it's played as explained in the Persistent Owned Events section.
  • The Serialized Data Migration tool will try to fix the serialized data for former UnShared fields so they don't lose any asset references you have already assigned.

Fade Groups

The old CustomFade system has been replaced by a new FadeGroup system explained on the main Change Log page.

Graph Structure

The IPlayableWrapper interface has been reworked into the AnimancerNodeBase class.

Object Pools

  • ObjectPool and ObjectPool<T> used to be static classes with basic functionality that only worked with parameterless constructors.
  • ObjectPool has been removed.
  • ObjectPool<T> has been changed to a regular instance class which can be inherited to allow each type to clear or reset its objects appropriately when releaseing them to the pool and to assert that pooled objects have appropriate default values when acquiring them from the pool.
    • If an inherited pool class exists for a given type, you won't be able to use the base ObjectPool class for that type because doing so would skip the proper acquisition and release constraints applied by the inherited class.
  • Added standard pool types: ListPool, SetPool, PooledGUIContent, and StringBuilderPool.
    • For example, instead of the old ObjectPool.AcquireList<string>() you would now use ListPool<string>.Instance.Acquire().
    • This change requires a bit more code, but is safer because it's no longer possible to call ObjectPool<List<string>>.Release(list) which would not have automatically cleared the list like ObjectPool.Release(list).
  • FadeGroup, and CloneContext have their own nested Pool classes.

Indexed Lists

There are several systems in Animancer with lists that need to be able to add and remove items at any time and want to do so quickly without needing to search through the whole list to find an item to remove.

  • The old solution was Key.KeyedList.
  • That system has been changed into IndexedList.
  • The new system is more memory efficient, faster, and more flexible, but a bit less safe if used incorrectly.
  • It's unlikely that any users are directly using this system in their scripts, but feel free to ask for help if you can't figure out how to use the new system based on its API and comments.

Serialized Data Migration

The Read Me asset located in the root Animancer folder has a button to migrate old serialized data to the format required by Animancer v8.0:

It shows a warning to confirm that you have backed up your project:

This process fixes the serialized data in scenes, prefabs, and scriptable objects which would have been invalidated by the following changes:

  • The Assembly Name Change would cause the values of all [SerializeReference] fields referencing Animancer types to be lost because those references are based on the assembly name.
    • All Transition Assets would lose their values because they use [SerializeReference] fields.
    • All [SerializeReference] fields containing transitions in your scripts would also be lost.
    • Regular [SerializeField] values would be unaffected. They don't support polymorphism so the type can be inferred from the field instead of needing to include it in the serialized data.
  • The new Event Name system would cause all event names to be lost because the field no longer holds strings.
  • The new Event Callback system would cause all event callbacks to be lost because the field is now a [SerializeReference] instead of always a UnityEvent.

Behaviour Changes

This version contains some significant changes to the way Animancer works which you will need to deal with on a case by case basis:

  • The Animancer Events system has been changed to avoid issues with shared events and to not automatically clear events whenever something is played.
    • This will require you to rework most scripts that interact with Animancer Events.
  • The internal system which invokes Animancer Events has been changed.
    • This likely won't affect most users.
    • The old system invoked events during the internal Animation Update.
    • The new system invokes events during LateUpdate with a [DefaultExecutionOrder] of -30000 (minimum is -32000).
    • In Animate Physics mode, events will be invoked in a coroutine using WaitForFixedUpdate instead of LateUpdate.
    • This is mostly an internal change which greatly simplifies several things that were more complicated than necessary in order to delay operations that aren't allowed during the internal Animation Update.