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?
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.
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().
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.
@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.
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.
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?
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.
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]
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
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).
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.
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
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.
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!
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.
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.
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.