Search Unity

Animator locking animated value even when current state has no curves/keys for that value

Discussion in 'Animation' started by stregillus, Nov 10, 2016.

  1. stregillus

    stregillus

    Joined:
    Oct 9, 2016
    Posts:
    10
    I'm learning Mechanim and I've run into one thing that I really don't understand.

    I have a value on a monobehaviour that I have animated. That value is only animated in ONE animation state in my state machine. In all other states, that value is not added as a property.

    However, even when I am NOT in that state, the value seems to be constantly set to whatever it was at the start of the game. I cannot modify it in the inspector during runtime. Any attempts to update the value in a script get overwritten by the animator.

    If I disable the Animator component, the problem stops and I can modify the value. If I remove the value from the ONE state that touches it, the problem stops and I can modify the value. I've tried removing "Write Defaults" on all states as well, but that had no effect.

    Is this how Mechanim works? It just locks any and all variables that it ever animates in any state? Even when the current state isn't animating that value? This seems insane to me. Can somebody tell me that I'm crazy here and that there is a workaround?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    This is the expected behaviour.

    If you want to override an animated value from script you need to use MonoBehaviour.LateUpdate()
     
  3. stregillus

    stregillus

    Joined:
    Oct 9, 2016
    Posts:
    10
    I'm sorry but this seems incredibly counter-intuitive... like to a "are you serious?" degree.

    I would expect an animation that is playing to only play out the curves that are in that animation. Why would I ever WANT a value that I have not animated to be locked by the animator? I thought the entire strength of the animator was that you could "animate any value", but if animating a value locks you out of using that value in other places, what's the point?

    So now I have to have 2 values that are essentially doing the same thing, one that I script, and one that I animate.

    Unity should really consider the (completely sane) idea that only the curves in the current animation should change values. If I wanted a value locked during an animation, I would add it to that animation clip. This current system is incredibly limiting.
     
  4. MildlyAnnoyed

    MildlyAnnoyed

    Joined:
    Jan 12, 2017
    Posts:
    7
    I'm commenting here because I've been fighting the same issue as described in OP, and I almost posted a bug-report on this behaviour.

    I looked around in the documentation on Animation Reference and all it's subpages.
    https://docs.unity3d.com/Manual/comp-AnimationGroup.html

    I'll admit that I only read through this once, so if the information is in there somewhere I've missed it. But as far as I can tell, this behaviour has not been described in the documentation and just like stregillus says, I found this behaviour extremely unintuitive, it was certainly not expected behaviour from my point of view.

    To me, it would be expected that values gets locked/set by the active playing animation clip, but not when referenced in a non-active animation clip. Even if there's no transition to the clip that manipulates (lets say) a transforms rotation, the Animator will lock the rotation property entirely as long as the Animator component is enabled. I'll agree that having a clip in your animation hierarchy that has no transitions to it is not good practise, and should generally be avoided, but in this case it illustrates very well how unintuitive this behaviour is. I'd expect an animation clip that has no transitions to it to have no influence on anything whatsoever. And to be honest I'd expect the same for an animation clip that is not playing, namely no influence on anything.

    I guess that I'll have to accept if this is really intended behaviour, but calling it "expected" is somewhat arrogant imho. I'd suggest adding some information about this in the documentation (unless it's already there and I just so happened to not find it - if that's the case I apologise and then this is a case of me not reading the documentation properly).

    I ran into this problem when I was building a system where I wanted to allow for instantiating an object introduced onto the screen with an animation. I want to be able to support both scripted animations (for ease of use of the system when prototyping), but I also want to support using the Animator system so that we can set up prettier transitions for actual productions.

    Finally, I've not tried the suggested solution of overriding the values in LateUpdate(), however I'd like to suggest an alternative for anybody else running into this issue. I'm planning on approaching this so that the Animator component will be disabled at all times unless an objected is instantiated with a request to use the Animator. In this case I'll enable the Animator and disable it again once the requested animation has been played. If whatever setup you are working on allows for enabling and disabling the Animator component, I'd argue that this is a nicer solution than overriding values in LateUpdate().
     
  5. Persegan

    Persegan

    Joined:
    Feb 12, 2015
    Posts:
    14
    Ran into this problem a bit earlier, I have to agree with stregillus: This behavior is completely counter intuitive and limiting. Here's hoping it gets changed in the future.
     
  6. Andrey-Postelzhuk

    Andrey-Postelzhuk

    Joined:
    Nov 26, 2013
    Posts:
    75
    @Mecanim-Dev Please add description of this excepted behaviour to the documentation. You will save thousands of hours for developers. It looks like a magic now.
     
    Last edited: Apr 5, 2017
    AldeRoberge, io-games, nbaris and 7 others like this.
  7. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    Wow. This actually destroys (to a large extent) any good workflow between artists creating animations and game designers scripting interactions ... at least for my company. I won't pretend to understand it ... hopefully there's an actual good reason for this under the hood that justifies it.

    Just needed an animation that moves a camera around and shifts two game objects (characters), and the designers still be able to activate/deactivate them through script during an animator state that does not even affect the characters ... sheesh. Never thought that would be beyond Unity. Was delegating to multiple people not a part of the equation during this decision? And no, putting a SetActive() in LateUpdate is out of the question for this (if I understood that correctly) ... making non-programmers jump through hoops is not something we're about to do. Actually going to have to make sure we activate and deactivate the animator now any time we have to move the characters to frame a proper camera shot ... heh.

    Is this something that is necessary to not break a whole bunch of stuff (in which case I guess the absurdity of this use-case is just outweighed), or was this planned as some imagined universal use-case?

    I'm fully cognizant that Unity is a *massive* system, and there may very well be a completely justified reason for this ... if there is, then some use-cases are simply casualties and my thanks for getting the entire system up and running ;). As of now though, I cannot for the life of me figure out what that would be. Just give a toggle at least to turn this behavior off ... it would most definitely not break anything for any one of the multiple games our company is making.
     
    Last edited: Apr 20, 2017
  8. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    @DGordon

    I'm not sure I understand, what is your issue?
    Do you have an issue with the fact that you can only override an animated value in LateUpdate or you can't override an animated value once the clip has finish to play?
     
  9. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    Sorry. Was a little too angsty there. Just finished implementing a workflow and then saw that was going to cause some issues ... may have done things differently if I had realized this.

    The issue is not being able to activate/deactivate gameobjects nested within an animator's hierarchy even though they aren't touched by the animation. This would go for any properties that aren't being touched as well ... but at the moment, the issue was SetActive(). That would be "you can only override an animated value in LateUpdate". But I would qualify that as "only override a value that isn't even touched by the animation in LateUpdate".

    I was setting up a workflow between two different roles -- one an artist for the animations, and the other a designer (for game logic). The animation is moving a camera and some 2D characters (to get them properly framed by the camera when you speak to them) and the logic occasionally needs to turn on and off some of the characters. I'm trying to keep each role's system as simple as possible here with as few possibilities of accidentally breaking someone else's stuff ... hence why I'm not so happy with this discovery.

    It works fine so long as I activate and deactivate the animator at the right times. It just cluttered things up and opened the door to some accidental bugs. Of course, it could be I misunderstood this whole thread, as well as what's happening here ... and if so, my apologies.
     
    Last edited: Apr 20, 2017
    spider853 likes this.
  10. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    I'm actually pretty confused right now. Sometimes it is letting me activate/deactivate a gameobject which is a child of the animator, and other times it is not. I can't tell what the difference is. I also have two different gameobjects under the same animator ... one of them I can move the position of, the other is locked. The animation in the animator is completely empty.

    Exactly how are properties locked on gameobjects under an animator's hierarchy? Does it depend on other animations in the animator (even if it isn't the current state)? Does it care if the child has an animator on itself as well (although the two objects I am using both have their own animators yet behave differently)? Where should I go to understand this better? I'm a little nervous building on top of something I clearly just don't understand. If you need specific information or if I'm just being unclear I can try isolating the issue ... I wouldn't send the project at this point since its pretty large.

    Sorry again for the uproar. Just confused and didn't expect to spend time on this now ... wasn't an excuse for venting though.

    [Root animator]

    [This gameobject cannot be disabled OR moved]

    [This gameobject cannot be disabled but CAN be moved]

    [This is the animation ... its blank and is the current state in the animator. I only put in that position while trying to fix/understand this]
     
    Last edited: Apr 20, 2017
  11. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Each AnimationClip have a set of bindings which define:
    • the animated property name(localposition, localrotation, localscale, etc..)
    • the component type where this animated property can be found(Transform, MonoBehaviour, Material, Camera, etc ..)
    • the transform path, where this gameobject is in the hierarchy
    see AnimationClip.SetCurve for more detail
    https://docs.unity3d.com/ScriptReference/AnimationClip.SetCurve.html

    When the animator is enabled we do build a super set of bindings by iterating over all animation clip in your controller and combining all bindings. This super set define all the animated property for your controller. At the same moment we do take a snapshot of all those properties as the default values.
    On each frame that the animator is updated all those properties are written by the animator, properties not animated in the current state are written with the default values, the animated one are written with the value from the curve.

    Some people like it some people hate it, it depends on your needs.
    We are working on a solution that will give you more flexibility but it not yet available.

    That been said, having 3 animator in the same hierarchy can be problematic if their bindings overlap, you may get undeterministic behaviour depeding on the order of activation, the last one to be activated will override the others one as it will be the last one to be evaluated by the engine.

    I would not recommend to anyone to put more than one animator per hierarchy as it add a level of complexity to manage.

    I don't know which version you are using but take a look at this video about Unity timeline in 2017.1, it does pretty much what you want
     
  12. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    Okay, after misunderstanding just about everything I possibly could, short answer if anyone else ever has this issue:

    (a) don't touch a property in any animation in an animator if you want to change it through script without LateUpdate.

    (b) Write Defaults may be of use.
     
    Last edited: Apr 21, 2017
  13. MildlyAnnoyed

    MildlyAnnoyed

    Joined:
    Jan 12, 2017
    Posts:
    7
    I see that there's been some activity in this thread since I last posted.

    My previous comment has not really been addressed, and that may be due to me not directly formulating a question, so I'll try again here and try to be a bit more direct.

    The so called expected behaviour regarding how Animators lock down values. Is that documented anywhere? In my opinion this should be stated loud and clear in the documentation, because it is surely not self explanatory. I'm obviously not the only one confused by this behaviour. As mentioned earlier I did not find any information on this behaviour in the documentation. Did I overlook something, or is this not documented? If it's not documented, please try to get a short description of this into the documentation. It could potentially have saved me from hours of troubleshooting what turned out to be "expected behaviour".

    I can add that since my last post I did the implementation so that the Animator components are disabled at all times, and only enabled when specifically requested. That resolved the issues that I had, and by doing it this way I'm able to support both Animator animations and scripted animations (two approaches that serves two different purposes). But I consider myself lucky to be in a situation where this solution was a viable option for me. For other people with different usecases this approach may not be a viable option. And then you'd be left with having to overwrite values in LateUpdate, which is a horrible solution imho (because when something suddently does not act as intended you'll have no idea if it is due to the Animator system or due to an error in a LateUpdate implementation somewhere).
     
    nbaris, vvorkCase and madfatcat like this.
  14. MildlyAnnoyed

    MildlyAnnoyed

    Joined:
    Jan 12, 2017
    Posts:
    7
    Hi, thanks for getting back to this thread despite it being somewhat old. I posted a question above directed at you, but I'm making this reply as well because I wanted to address the stuff you say in the quoted part.

    I'm really happy to hear that a solution is under development that will ease this up. If you can elaborate a bit on what I've got to look forward to here, that would be awesome. Are you hinting at an implementation where only the actively playing state(s) influence values. Because if that's the case that would just be amazingly awesome! I'm really stoked to hear what this could be!

    Then regarding not having multiple Animators in the same hierarchy. I have a hard time accepting that. When doing UI a common case is to have a button prefab that's reused in multiple screens. It may be stretched or fitted in other manners where it's used, but I think that the button prefab would usually have an Animator on it to control the button animations when it's interacted with.

    However, that button is usually placed on some screen object. And if that screen object is animated onto the device screen (for example sliding in from a side), it's not impossible to imagine that the screen has an animator as well. So this setup would be not recommended according to you? Or am I misunderstanding you? If I've understood you correctly I'd like to hear your approach for the Screen with button setup. How would you approach something like that if not by having a seperate Animator on the Screen and one on the button. Would you make unique Animator systems for each and every screen that takes all that screens children into consideration? Because that would become insane workload in terms of animations because no Animator would be reusable with such a setup.
     
    theANMATOR2b likes this.
  15. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I was not clear enough, I should have added that having 3 animator in the same hierarchy that animate transforms is not recommended, as very often all the transform hierarchy is animated.

    As long as you know that you're animated properties doesn't overlad between each animator you are out of trouble. Currently there is no tools in unity to detect such case so you must be sure that all the people doing animation in you're project know this limitation.

    No it's not documented anywhere, we will improve the documentation
     
    theANMATOR2b and Nodrap like this.
  16. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    When you document this stuff, please make sure you also mention (a) all animations in the animator will be taken into account, and (b) what write defaults does. Even after I figured out the animations in the animator part (what you said, thank you), I ran into another similar issue, this time because of Write Defaults. Luckily I had found that other post.

    I definitely agree with MildlyAnnoyed ... had this all been documented thoroughly somewhere, days of time would have been saved. Once I understood it, I was able to get around our issues by making sure our animations did not touch anything our scripting has to (luckily we're able to do that). Its a bigger issue than it seems, since by the time any issues are found, projects are already underway with assets already created.

    All told, thank you for clarifying things.
     
    ModLunar and theANMATOR2b like this.
  17. MildlyAnnoyed

    MildlyAnnoyed

    Joined:
    Jan 12, 2017
    Posts:
    7
    Hi again.

    Thanks for clarifying your statement regarding multiple Animator setups. What you say here makes much more sense to me than your prior post. I'm happy to hear that this is what you meant. I had started questioning my knowledge about Animators following your prior statement, so it's really nice to know that I'm somewhat on the right track with my approach! :)

    Also, thank you in advance for adding that explanation to the documentation. I'm sure it's going to be a great help for people that may go into animation stuff with assumptions similar to what I had. It's completely acceptable that a system deviates from the user's (possibly faulty) expectations in some regards, but it becomes so much more acceptable when things are documented. Especially when it's behaviour that's not self explanatory (which I'd argue is the case here). At the same time I should probably disclaim that I've not really worked with animations in other systems than Unity, so my expectations were based solely in how I imagined that things would work, and thus not based on any prior experience. So there's of course always the chance that I'm just fully and utterly insane! Never the less having this documented would have been a great help for me, and I believe that once it gets into the documentation it's very likely to be helpful for others!
     
    theANMATOR2b likes this.
  18. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    As of today (5/17/17) using a beta version of 5.6 (b8 I think), turning the "Write Defaults" checkbox off worked properly. Checked, it applied the default values when moving to an animation which did not actually touch those values, unchecked, it left those default values alone.
     
    theANMATOR2b likes this.
  19. Numior

    Numior

    Joined:
    Apr 4, 2015
    Posts:
    2
    It's really great that I've finally found this post. Lost only a couple of hours figuring that animator was even responsible.
    One thing I didn't get to work and not sure if I'm figuring this right, but I'm disabling the animator component with an event on the final key and still not able to change the properties.

    A little background: I have a prefab with the animator component disabled, in the Start() method I sometimes enable the component to blink a few times with alpha and then disable it with an event. Non-activated instances are working fine with the color change, but animated ones still have color values locked, even with the disabled animator.
     
  20. MildlyAnnoyed

    MildlyAnnoyed

    Joined:
    Jan 12, 2017
    Posts:
    7
    It's difficult to say what the issue is without any more information about your setup. Since you are claiming that you are able to make the change for instances that did not have their Animator active, my immediate thought is that the change you are trying to apply may be applied too early (e.g. same frame as you disable the Animator). Try a setup where you are certain that the Animator has been disabled for at least a frame before making the change, then report back.

    You may get more traction on the feedback if you create a post for yourself though. You could in that case also provide some more information about your setup.

    I know that disabling the Animator is a viable solution, because I implemented it and got it working. So at least that verifies that it's possible. Good luck.
     
  21. LukasAtharis

    LukasAtharis

    Joined:
    Mar 20, 2015
    Posts:
    5
    Still nothing new on that? I'm trying to blend a Mecanim animation with a Procedural animation and this is very frustrating.

    The scenario is that I have a turret having an idle animation and whenever the play comes it range I'm doing some scripting to move the turret to aim toward the target. Because of that issue, I have to do that code in LateUpdate which prevents me from having that as a StateMachineBehaviour. If I disable the Animator to move the object as soon as I enable it back it "snaps" to the previous state which doesn't look good. Disabling the Animator also means that I can't have all my bot living as a state machine.

    More generally, I want to be able to animate a property which isn't affected by the currently playing AnimationClip.
    I attached a min repro here.
    What I want: Pressing on "Trigger" should rotate the cube along Z instead of Y.
    What I get: Pressing on "Trigger" just freezes the cube in place.

    Is there any reasonable workaround which doesn't involve having a completely artificial second Animator, or completely disable it with some weird other thing? Can the Playable APIs be used to make that happen?
     

    Attached Files:

  22. bourriquet

    bourriquet

    Joined:
    Jul 17, 2012
    Posts:
    181
    I'm surprised I haven't had issues with this before.
    It's pretty obvious that an intuitive behaviour would be to lock only the values that are animated in the current state. So the code would handle a property only when it's not animated in the current state.
    But I guess there is a problem with this that I'm not seeing.
    In this case, it should at least be well documented.

    And using LateUpdate doesn't help, as it will override the animation when entering a state in which the property is animated.
     
    madfatcat likes this.
  23. getwilde

    getwilde

    Joined:
    May 4, 2016
    Posts:
    18
    I've run into this issue as well; surprised that values I'm not animating are locked regardless.
     
    AldeRoberge and SlowSeer like this.
  24. stevenwanhk

    stevenwanhk

    Joined:
    Jul 20, 2016
    Posts:
    113
    Not sure how you handle this:

    A non-human creature model
    3 animations:
    1. Jump from point A to point B
    2. IdleA
    3. IdleB

    What I used to do is using the following hierarchy:
    |- GlobalMovement <-- Animation 1 will have keys on this transform to move from A to B
    |-- Body <-- Animation 2 and 3 will have keys to do the idle animations, and also jumping animation of Animation 1

    So now I choose to have only 1 animator. Animation 2 and 3 now have no key on the transform "GlobalMovement", so the model can play IdleA and IdleB no matter where it stands. But due to Unity overwrites the values, playing IdleA or IdleB will lock the transform of "GlobalMovement" into unknown values making the whole approach fail.

    My current thought is to use 2 animators, one (animator A) for "GlobalMovement" only, another one (animator A) for "Body" only. However animator B has no idea about when animator A finish playing jump animation, you need to add logic to check so animator B can play IdleA after animator A finishes playing jump animation. It looks so stupid.
     
    Last edited: Dec 5, 2017
  25. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    Actually about the animator locking up fields and such, I used a coroutine so I only have to set the value once when I want to. Based on Unity's execution order of events (in the documentation here), you can wait till the end of the frame, and then do something:

    Code (CSharp):
    1.  
    2. private IEnumerator OverwriteTheField() {
    3.    yield return new WaitTillEndOfFrame();
    4.    // Set the field/do stuff here -- this happens AFTER Unity's internal animation update!
    5. }
    6.  
    and then call the coroutine by using StartCoroutine(). It's hard for me to tell right now if the animator switches the value back the next frame though, I'd need to experiment more with it.
     
    petera1980 likes this.
  26. dsalisbury

    dsalisbury

    Joined:
    Mar 5, 2018
    Posts:
    4
    This forum series reflects exactly the issues that I am having, as well as all the reasons I do not understand why this behaviour is considered "expected".

    I have a card game. The cards have an Animator that has 2 states, each with a clip:
    Idle - Card will occasionally jiggle (rotation oscillates between -5 and 5 degrees).
    Discard - Card will animate localPosition to 0,0,0 over 1 second

    There can be multiple discard decks on the board, so the idea is that when I tell a card to Discard, I will first parent it to the deck that it needs to Discard to with a transform.SetParent(deckToDiscardTo.transform, true);

    The 'true' in that statement above is supposed to make the card stay at its current world position when it parents to something else, so the position values should change so the card visually doesn't move.

    However, because I am already animating position changes in the Discard animation in the Animator, the Animator locks those values so that the SetParent(object, TRUE) cannot do its job. The Card will snap to the the new parent because it is being forced to ignore positions changes because the Discard clip is using them, even though I told the SetParent that worldPositionStays = true.

    And none of that makes any sense to me as to why it would be intended.

    Any help would be greatly appreciated. Else, my plan B is to say screw the Animator component altogether and do it manually with legacy Animation components and script-crafted AnimationCurves, and that is going to get ugly really quickly.
     
    madfatcat likes this.
  27. abiasi

    abiasi

    Joined:
    Nov 12, 2015
    Posts:
    3
    We are experiencing the same issue and I agree that the correct behaviour should be to only lock properties in the current state unless there's a really good reason it can't be changed, at least offer an option to enable/disable.

    In our case, we have a screen that has an In animation, an Idle animation and an Out animation. During the In animation some objects are animated, those same objects are not animated in the looped Idle animation and in our scripts we need to dynamically animate them but we can't because the properties that need to be changed are locked by the Animator.

    Of course there are workarounds but it's taking a big chunk of time/money when this could be completely avoided with good documentation and an intuitive behaviour.
     
  28. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Does the updated solution mentioned in post #19 above (write defaults) solve your issues?
     
  29. LucasRizzotto

    LucasRizzotto

    Joined:
    Dec 11, 2015
    Posts:
    27
    #19 didn't work for me. LateUpdate() is not overriding the actions of the Mecanim. I'll describe my issue since it appears that this is a pretty serious bug.

    upload_2018-3-27_20-29-7.png

    I have two blocks: both of them have scripts that change the material color to blue on LateUpdate(). B has a mecanim with two animations: one that changes the color to red, and one that doesn't do anything. It goes by default to the animation that doesn't do anything.

    Now this is the strange part: even though the Animator is running the animation that makes no changes to the material, it still locks the property. The script can't change it on LateUpdate().

    So apparently if any animation inside of any given Animator changes a property, mecanim stops any outsiders from changing it at any given state - regardless of whether the current animation affects it or not.
     
    AldeRoberge, Oruji and ModLunar like this.
  30. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Lucas - I understand this is troublesome -
    So the states are entry -> no change -> color red.
    What is the purpose of the animation that doesn't do anything?

    Could this possibly be caused by the component order in the inspector, the blue script and the animation component? I know this doesn't solve the overall issue outlined in this thread, but might be a 'fix' for your setup.

    Are you using animator component or animation component for the red color change?
     
  31. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    I have this same problem, I want to animate my UI, then change button colours on mouse events, it can't be done.

    @Mecanim-Dev can't we have an exception for uGUI UI stuff? Doing colour changes to UI elements after fading them in using the animator is a pretty reasonable use case, but it's impossible right now, I need to animate my UI fade in using lerps in code because of the mecanim lockdown.

    I have posted a reasonable use example here: https://forum.unity.com/threads/change-text-colour-after-animating.524788/
     
  32. del_unity

    del_unity

    Joined:
    Jan 23, 2018
    Posts:
    5
    "Some people like it some people hate it, it depends on your needs.
    We are working on a solution that will give you more flexibility but it not yet available."

    Any news on this? The current behaviour is utter nonsense, if the animation currently playing doesn't animate a property, it should not be set, end of story. Not only is this counter intuative, it's a performance nightmare in the UI.
     
    Ultroman, ModLunar and madfatcat like this.
  33. madfatcat

    madfatcat

    Joined:
    Jul 3, 2014
    Posts:
    14
    "Some people like it some people hate it, it depends on your needs." - sane people cannot like such a weird behavior, sorry.
     
    admin_unity602 likes this.
  34. Oruji

    Oruji

    Joined:
    Nov 5, 2012
    Posts:
    14
    I'm struggling with this as well.
    LateUpdate() does not override the animation.
     
  35. glaucotodesco

    glaucotodesco

    Joined:
    Dec 17, 2015
    Posts:
    1
    Same problem here.
     
  36. PZ4_Bailey

    PZ4_Bailey

    Joined:
    Oct 15, 2017
    Posts:
    6
    Is there no fix for this yet? I have pool of enemies with Animators attached. If enemy dies it plays Death animation then disabled but when re-enabled(Spawn) then it spawns into the Death animation
     
  37. lionheartmg

    lionheartmg

    Joined:
    Jun 4, 2018
    Posts:
    2
    In case it helps anybody out there (even if its an older thread). I was having the same issue as the OP. It was driving me nuts (and I couldn't get the right google search to find any help).

    This worked for me.

    Working on a simple word search game and, upon success, I wanted to play an animation for each letter/game object. If the "Success" animation changed the scale/sprite/etc, the initial state of that game object would be messed up. Disabling the Animator on the prefab fixed this but then the animation didn't work.

    What did work was simply disabling the Animator in code. When creating the objects/letters from a prefab, I get the Animator component and set enabled = false (animator.enabled = false). If, right before I play an animation, I set animator.enabled = true on that object, it works as expected (at least for me). Not sure about best practice but it works and that beats trying to animate it through code.
     
    atef_by likes this.
  38. PZ4_Bailey

    PZ4_Bailey

    Joined:
    Oct 15, 2017
    Posts:
    6
    What if have a idle animation that always plays

     
  39. yanivng

    yanivng

    Joined:
    May 21, 2017
    Posts:
    43
    Hi,

    Glad to find out I'm not the only one suffering from this mechanism.
    I have created a project to reproduce the problem I'm currently facing. I'm running a simple animation that moves a game object and expect to be able to reset the gameobject position. This can be done by adding an empty animation, that (since it does not change anything) simply writes the default values, thus returning our gameobject to its original position.
    But here is where things get complicated: if the animator gameobject is set inactive while the animation is running, new incorrect defaults values will be saved when gameobject is saved active, and I am unable to reset my gameobject position.
    To reproduce this issue, run the attached project:
    1. Change the stop method to "PlayEmpty"
    2. Hit Start Animation and watch the left "Hello world" text travel.
    3. While it is traveling, click Disable Text GO. The left text disappears.
    4. Click Enable Text GO and see the text comes back at its last location.
    5. Click Start Animation and watch the left "Hello world" text travel.
    6. Click Stop Animation - the text is returned to the position where it was when enabling the gameobject, rather than its original position.

    Any help is welcome, suggestions on how to change the code to make the above scenario work.

    Thanks,
    Yaniv
     

    Attached Files:

  40. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I've never personally had this problem, but Unity's Simple Animation component on GitHub has a section that sounds like it's talking about the same thing under the headding "SimpleAnimation doesn’t support only writing the values of the current clip by default" so that may be a viable solution for some people.
     
  41. GilesDMiddleton

    GilesDMiddleton

    Joined:
    Aug 12, 2015
    Posts:
    91
    I just had this problem now -

    My gameobject was in the default state, doing NOTHING (has an animator applied, but not yet entered an animatable state). I couldn't change the localScale programatically to be 0,0,0. Even with write defaults off, the next frame the scale jumps back to 1,1,1

    I fully expected that
    1. in a state where no animation takes place, you can tweak the transforms/properties of the object and any future states will start from the current values unless curves are set to explicitly override those values.
    2. In a state that animates say, only position.x, that scale, or position.y could be altered independently by code (unless Write defaults is on).

    Without hacking into LateUpdate.
     
    GloriousJonatan likes this.
  42. cornucanis

    cornucanis

    Joined:
    Jun 13, 2018
    Posts:
    2
    I know I'm beating a dead horse at this point with all the complaints here about the issue already, but why would this possibly be not only the default behavior but completely unmodifiable? As many have said already, anybody would intuitively expect it to only overwrite values that are utilized by the currently active animation.

    Many people here have presented the solution of disabling the animator component when not in use, but that's not an option when you have an idle state and animations to cover every potential player state requiring the animator to always be active. I tried disabling "Write Defaults" as suggested by many here, but that didn't fix anything. I've confirmed that it's only one animation state within the controller causing the issue by removing it temporarily. Even so, setting the sole problem state to not "Write Defaults" fails to fix the issue of constantly overriding the value even when there are no transitions associated with the state. I'm just completely at a loss as to why this would be considered desirable behavior, and still utterly ignored after years of complaints.

    At least now that I know this is an issue I can work around it. I would never have expected the animator to be causing this sort of problem though, so I didn't think to check the documentation for the animator when the bug first occurred. Only after an hour or two of bug tracking did I find out it was a single animation state that was never touched in my tests causing the issue.

    Edit: Forgot to mention, the LateUpdate solution is also not always an option. If you're calling a method via Invoke, a physics trigger, a callback, etc then you don't really have that freedom as far as I know. That could just be by inexperience showing, though.
     
    Last edited: Oct 13, 2018
  43. spider853

    spider853

    Joined:
    Feb 16, 2018
    Posts:
    42
    Similar issue with a blink anim.
    Player has Idle anim and on the hierarchy I have a blink animation that randomly triggers.
    The Player other anims uses the blink morph controllers.
    Now if the blink controller is in Empty state then when playing other anims that uses blink rig controllers they play wrong because the blink controller overwrites them.
    So the current behaviour is:
    1. A overwrites B
    2. A finishes an animation -> write A.defaults
    3. A has empty animation, A.defaults overwrites B animation

    Expected behaviour (Solution)
    1. global defaults
    2. A overwrites B
    3. A finishes an animation -> write Global.defaults
    4. A has an empty animation, B non empty animation overwrites Global.defaults

    If it's possible to implement this, as there is no elegant animation solution to this, except disabling the blink anim controller...
     
  44. Der-Kleine

    Der-Kleine

    Joined:
    May 14, 2015
    Posts:
    2
    I'm not expecting much to change here going by what's already been posted, but just wanted to share my experience here since I also struggled with this limitation.

    Basically I'm making a Kinect game for a university course where the player controls an Owl, with the wings being mapped to Arm movements in script. The player can trigger an animation where the owl forms its wings into more of a ball shape when performing a specific gesture.

    The whole process of having the wings controlled by code most of the time, but through an animation when triggering this gesture ended up being way more complicated than necessary due to the inability to modify values that are animated in any state of the animator.

    In the end I went with the solution of only enabling the animator in that one specific instance, as a result I was forces to kind of smooth over the transition between script control and animator control in code, with the result falling slightly short of what I was hoping for. The point is: Having the animator overwrite values in states where no values should be written to makes no sense, the "Write Default checkbox" doesn't seem to actually do anything (when from my understanding of its description it should fix precisely this problem) and the workarounds to achieving what I was looking for were sub-optimal.

    I'm not holding my breath for this getting fixed, but come on...
     
    Last edited: Nov 26, 2018
  45. ethancorssel

    ethancorssel

    Joined:
    Apr 25, 2016
    Posts:
    6
    You can see the problem very easily without even write code. if you had a 'x' value used by a single animation in your hole animation hierarchy, just try to modify that value in inspector during play mode; you cannot, even if that animation isn't playing.
     
  46. ethancorssel

    ethancorssel

    Joined:
    Apr 25, 2016
    Posts:
    6
    I think my case is even simpler:

    2D Sprite animation: Walk

    1st half of the animation the sprites just fine.
    2nd half of the animation the sprites flip in x (so you save tex space)

    As you move left or right, the sprite has to be flipped again x axis (by script obviously), oh but you cannot, because you have that value locked by the animator.
     
  47. ethancorssel

    ethancorssel

    Joined:
    Apr 25, 2016
    Posts:
    6
    @SilentSin I'm actually using that component but the issue still happens; maybe because the component requires Animator component anyways, it seems like the simple existence of the animation on game it's enough
     
  48. heck37

    heck37

    Joined:
    Mar 9, 2018
    Posts:
    1
    If it helps motivate @Mecanim-Dev and the Unity team, I'll add in my two cents as well:

    I've been working on a game where I have three heart elements in the UI, one of which exists by default, the other two are cloned off of the first in code. Naturally, I put the second and third hearts at different positions equally spaced from the default position driven by the first heart - again, I do this part in code. Each heart has several identical animations, including one specific animation, only used in one very specific scenario, that changes the Transform position of the heart.

    Because of the sole presence of that specific animation, all the hearts, each frame, are moved to their default position that's driven by the first heart, regardless of which animation state they're in. In-game, that makes it look like there's only one heart, when really there's three, and the animator makes it incredibly difficult to move the second and third hearts off of the first heart's default position.

    To beat a dead horse (or maybe to add fuel to the fire, more optimistically), this was very unintuitive behavior to me, and honestly it just seems weird to figure out that this was intended. I can't think of a good reason for this to be desirable behavior, though I understand that technical limitations may, for some reason, make it necessary behavior. I get that there are ways to work around this quirk, but unchecking Write Defaults doesn't seem to do anything for me (like most everyone else in this thread), using LateUpdate to re-adjust animated objects' positions every single frame seems like a very needlessly performance-heavy solution, and anything that involves disabling the Animator itself seems just as unintuitive and annoying as the quirk itself. For what it's worth, I'm another person who would really appreciate seeing this intended behavior changed.
     
  49. shreedx

    shreedx

    Joined:
    Feb 7, 2018
    Posts:
    4
    I'm quite happy I only wasted hours, not days trying to figure out if it is just me, or Unity doing some unintuitive magic again. Whoever came up with this and thought it is a good idea, please present us with one good use case. I am not seeing any. And even yet, if you want to keep it this way - why would you force it on us? Why not just give us an option to choose whether we want this behaviour or not with one simple checkbox? I just spent hours changing animations to less appealing ones just to make the game work properly.
     
    Last edited: Jan 22, 2019
  50. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    262
    This behavior caused me to waste almost an entire day. In our case, we had a group of animations in a single controller that set active/inactive on some UI elements. When we would get to an animation state that didn't include a prior UI element, it would get set to the UI Element's last active value, even though it wasn't in the track list. We noticed that this was happening when we tried to toggle active/inactive in the inspector but something was locking the value. Turns out it was Animator.

    The expected behavior here is that only the tracks that are in the active animation should be affected.

    Our solution is to manage active state in code and remove all tracks relating to Active from the entire animation controller.