Write Defaults Confusion / Bug

From my experience in Unity 2020.1.15f1, this bug is still here.

@Mecanim-Dev Any update on the bug report or bug itself?

1 Like

Yet another surpize…

I’ve been trying to animate some Text Mesh Pro (TMP) settings and simply want to control the attributes after the animation finishes. That is, it (the Animator) transitions into another animation which doesn’t use those attributes. I was hoping to use Write Defaults flag so then I could use code (normal MonoBehaviour) to modify those attributes.

1 Like

In unity 2019 Lts:

private void Awake
{
GetComponent().keepAnimatorControllerStateOnDisable = true;
}

keeps original default values.

1 Like

Write defaults still don’t work in 2020.1.10f1 or am i doing something wrong?

Using keepAnimatorControllerStateOnDisable with an entry state with no animation and Write Defaults set to true seems to be able to prevent this issue in recent Unity versions (previously, we would make other animations forcibly reset these changes if necessary). However, it is rather strange that this setting is exposed in the inspector in Debug Mode only ( Animator.keepAnimatorControllerStateOnDisable should be shown in inspector ). Is there some risk involved with using it that means it isn’t usually intended to be set by animators in the way that the base Write Defaults is?

had a similar issue… fixed it by turning WD on then off again while in playmode… fixed it instantly. why does unity do this to me…

Unity 2019.4.31f1

I tried a few of the suggested solutions/workarounds. Note that I’m using an Animator with a single int parameter “AnimationID” which leads to various states with their own animations. I’m also using an animator override controller and not all animations are overridden, leaving many states playing the base animations, which are mostly empty (hence the importance of writing defaults).

A. Setting Animator.keepAnimatorControllerStateOnDisable = true on Awake (or in Inspector in Debug mode, as it’s not visible in Normal mode) didn’t work for me (Unity 2022) (I kept having the bad defaults stored from animation played at deactivation time).

B. CrossFade didn’t work for me in:

    anim.CrossFade("Default State", 0f);
    anim.Update(0f);
    anim.Update(0f);
    gameObject.SetActive(false);

However, since I’m working with parameters instead, I replaced CrossFade with code setting my default parameter value:

// Animator-specific values
private static readonly int AnimationIdHash = Animator.StringToHash("AnimationID");
public const int DefaultAnimationID = 0;
// In method that deactivates game object
    m_Animator.SetInteger(AnimationIdHash, DefaultAnimationID);
    anim.Update(0f);
    anim.Update(0f);
    gameObject.SetActive(false);

and it worked. As they say, the two Updates were needed, and a single Update(0.1f) was not enough.

However, as Sycobob said, even if Unity dev team prefers to clear animator defaults when disabled for memory reasons, having an option to keep the defaults in memory seems a reasonable compromise. I’m not sure what Animator.keepAnimatorControllerStateOnDisable is really intended for (it seems to be about preserving the last animator state, but from experience Animator.enabled = false as always paused animations preserving states, so I’m not sure what it’s about, and it’s not exposed in Inspector Normal mode, but we could have an Animator.keepAnimationDefaultsOnDisable exposed in Inspector Normal mode with a tooltip explaining it will keep the original defaults since first Awake/OnEnable, and should be used in combination with Animation asset Write Defaults to revert all modified properties to their Entry values.

I personally think this should be default, but if you insist on memory performance and want to preserve old behavior for compatibility with existing projects, then an option should be enough. People stumbling on this issue will find this thread, then find the new property’s name once you’ve implemented it, and can even define an Animator Preset to always set it to true in their projects.

2 Likes

It seems to me this was implemented recently and even backported to older Unity versions.
Animator.writeDefaultValuesOnDisable is new property which is serialized!

Thank you! :slight_smile:

3 Likes

Although I’m not sure to fully follow what it does when enabled or not.
Basically, by default when enabling/disabling a GO everything resets. If I enable this, do I have “no consequences” when enabling/disabling GO with an animator. So I can disable an object rendering and enable it without loosing it states/parameteres/initial DefaultValues at all ?

I now have an opposite problem. If I disable WriteDefaults flag in state A, and have other state B which animate some property. What property is reseted to default in state A ((.
Seems like that flag works as it is always true. Unity 2021.3.14f1

Hello !

I have had the same issue as well. Interstingly, I’ve used Unity 2021.3.17 for several months and never had an issue with these default values when disabling / renabling again.
But then I had to switch to a newer version of Unity (2021.3.32 currently), and the issues appeared …
After a lot of investigations, it seems that what I found as “normal” was actually considered a “bug” running from 2021.3.16 to 2021.3.20. It was “fixed” in 2021.3.20 ( Editor: Fixed a regression that changed the default behaviour of animators on disabled. (UUM-27229) ) and now I had to redo tons of animations, adding “default” keyframes all over the place, which is both time consuming and very hard to debug. I recently opened a thread before discovering this one, with no answer, hoping I would get more luch here.

I’m not sure I fully grasped all workarounds descibed in this thread, but short questions :

  • Is this now supposed to be fixed for good ?
  • If so, how is “Write default” really supposed to work ?

Hey there. I know this is a very old thread, but I’ve been struggling with some similar animation state issues lately and I thought I’d lay out my findings to help others, as this is one of the primary google results when searching for help with Write Defaults.

I’m using Unity 2021.3.25f1.

“Write Defaults” = “Restore original values when exiting the animation state”

Or perhaps more simply: “Restore whatever the values were before this animation played”

This is the most common use case for animations that are not persistent, not cumulative, and should reset when the animation is done.

However!

If you disable the animator mid-animation, that does NOT count as exiting the animation state. It will retain whatever the current values are mid-animation. If you then enable the animator again, those mid-animation values are now considered the “defaults” or “original values” as I’ve described above. Those are the values that will be restored when exiting the animation state moving forward.

The solution to this is to enable a hidden property called “WriteDefaultsOnDisable”. This can be found on the animator component, when the inspector is in debug mode, or you can set it via code. When this property is set to true, then when the animator becomes disabled it will force the animator to restore the original values right away (or at least keep them intact), thus preserving the correct “default” values. Then when you enable the animator later, it will have the same defaults as the first time you ran it.

This is what I did to resolve my animation issues regarding disabling/enabling animators due to a procedural animation that temporarily overrides the animator, as well as a pooling system that could suddenly disable an animating object.

So all my animation states are set to “WriteDefaults = true” and my animators are set to “WriteDefaultsOnDisable = true”. Obviously you would tailor this based on the nature of your animations, and hopefully with this info you can understand how these properties affect the behavior.

Another potentially useful hidden property is “KeepAnimatorStateOnDisable” which when set to true will preserve the current animator state, and state of animated objects when the animator is disabled, which I have not tested but I presume would act like a pause/play functionality when disabling/enabling the animator. I’m not sure how it would interact with “WriteDefaultsOnDisable”, hopefully with both properties enabled, it would properly retain the correct original defaults, and also restore the in-progress animator state when re-enabled.

Hope that helps.

2 Likes

This works for me, thanks!