Animator default values can change through the animations itself

I had a lot of trouble with my decision to use the animator for ui, a lot of unexpected strange things happened. Today I finally took the time to find out why: The default values are defined every time the animator is enabled, so when the runtime controller is created. This does make sense from the design decisions the unity team made. The problem now is, when you disable the animator, it does not write those default values back into the animator. So the values from the active animation at the time of deactivation define the new default values.
Here is a simple video to show this behavior (the bottom text is visible by default, but once the gameobject was disabled while the text is disabled the default value will become disabled as well).

Does this bother anyone else or am I the only one who thinks that is not logical (with the knowledge that all states in the animator are resetted when disabled and even the runtime controller is created from scratch every time the animator is enabled).
Is there any way to set the default values for the game object when the animator is disabled? That would be my expected behavior solution.

5 Likes

This is beyond my knowledge - but the logical reason given to do this is to free up the resources. I think this is one of the reasons given to similar questions asked before.
Cant you capture the values upon or just prior to disabling and apply those values upon reenabling - via script?

I didn’t find any interface to get the default values that have to be stored somewhere. As for freeing resources. I’m totally with you, not everybody probably needs that feature, so it would be annoying to create an overhead for them. My suggestion is to not store the values while being disabled, but to apply the values right before the object is disabled, the time the information is discarded.

Anyways, I got a response from unity, that they were able to reproduce the problem and sent it to their developers. Let’s see what they think :slight_smile:

2 Likes

I think this can only be accomplished via code. Sorry to send you astray. Good to know Unity Devs are looking at it. I remember mecanim_dev explaining the reason for this - or something very similar.

1 Like

I’m more than comfortable with code. When I wrote interface I meant public interfaces from the unity API, so the one’s from here: https://docs.unity3d.com/ScriptReference/RuntimeAnimatorController.html
Hm, I did google but didn’t find anything. @Mecanim-Dev did you write about the decision already? What are your thoughts on the topic?

I’m not sure about which topic you are talking about.

For the problem you got, it look like a bug because the animator must write back the default values when it get disabled otherwise the behaviour would be undeterministic.

Our QA seem to have repro your issue so your bug should be on his way to our bug list.

2 Likes

Ah cool! That’s good news. I thought that it maybe was your intention to not write the values back once the animator is disabled.Because I thought that I was asking so cautious, because I know that it is not easy to change something a lot of people have adapted to. Anyways, thanks for your update, looking forward to any progress that will come up :slight_smile:

2 Likes

Hi, is there any news about this problem? It’s terrible bug I don’t understand how people do pooling of animated objects, like enemies if this bug exists

1 Like

I run to this problem, but when deactivating object (not animator) that has simple animation (with Anima2D bones) and animation is let’s say in half of the animation progress,
the values that the object had at the time of deactivating, are writen as defaults.

When you activate object again, deafault values are the ones that were set by animation at the time of deactivating.

Anything new about this issue?

2 Likes

Hey there,

I got a quite extensive response:

So it is by design and you and trick it by for example switching to another state (not empty) right before disabling the go.

10 Likes

Too bad that there is not simply a property like Animator.AutoWriteDefaultValuesOnDisable.

Doing it manually require specific code everywhere you disable your game object, so any generic code or third party code that does that is forbidden. And its a real pain to maintain.

Doing it from method OnDisable of a component aside Animator requires your component to be ordered before the Animator component (your OnDisable must be called before Animator’s OnDisable because it would clear stored values before you would try to write them back).

2 Likes

I’m running into a similar issue.

is there a way for me to “override” the default values by code? you said “doing it manually requires specific code” how do you manage to do it?

1 Like

I ran into the same issue, I find it odd that it’s so overlooked by the team…

Jepp same here :slight_smile:

Same here, I wish there was Animator.AutoWriteDefaultValuesOnDisable.

I ran into this issue,

animator.keepAnimatorControllerStateOnDisable = true;
animator.WriteDefaultValues();

short recap with 2 solutions, 1 is auto, 2 is manual.

1 Like

Same problem. I want checkbox WriteDefaults to be False by default

Also see: Write Defaults Confusion / Bug for extra workarounds

I haven’t seen anyone post this anywhere, so in case this helps anyone:

Recently the company I’m at updated Unity from 2021.3.16f1 to 2022.3.26f1.
This ended up breaking a lot of the visuals in our games where gameobjects with animator components were disabled / enabled. The first time the objects were used, everything worked properly, but any subsequent time, the visuals were not set to their default values.

I came across this: Unity - Scripting API: Animator.writeDefaultValuesOnDisable
Which seems to have been introduced in 2022.3?

Essentially the Animator component has the Animator.writeDefaultValuesOnDisable property set to false by default. Enabling this fixed all our issues.
This property was not in previous versions of Unity, and having it set to false is the opposite of how the Animator component worked before.

You can see this property in the Inspector if you switch the Inspector to Debug mode.