The Long Way Home – Animating a UI
Listen, I’m not a gifted hobbyist when it comes to working with Unity. My approach has been to logically suss out what I want to do using my knowledge of application development, build some test cases in code, and hopefully rely on the script (that I know) far more than I would rely on whatever automation Unity offers (which is what I’m generally fuzzy on). Of course, using Unity means using Unity, so I can’t simply script my way to Nirvana; at some point I’m going to need to use the Unity Editor to Get Stuff Done ™.
Exhibit A: Animating a panel to fly in on a button press, and to fly out when I click Cancel. The goal seems relatively simple enough, and I figured I was halfway there because many moons ago I had done some work in Flash which introduced me to the concept of key frames, which are points along a timeline where properties of an object to be animated can be changed. Unity’s animation system, at it’s most basic, uses keyframes as well, so I figured that I could create an animation clip, set some keyframes and alter properties, call the Play() method from script (either SlideIn or SlideOut) when the appropriate button was pressed, and everything would work as I assumed it would.
Check out this monstrosity. Click to embiggen and feel your soul being drained as I explain how this simple task is hampered by the Power of Unity.
The top portion of the screen is my design surface. You can see the frame of the UI boundary on the left, and the panel to fly in is on the right. When we run this, that panel is outside the bounds of the camera that draws the UI, so we can call it “exit, stage right” (or left depending on whether you’re on stage or in the audi…you know what, I don’t care about this metaphor). The properties of the panel are just a whole lot of technobabble, but the important part is the bottom of the screen. That’s the “flow” of animation that I was forced to deal with. What isn’t shown is the panel that allowed me to define the animation through the use of keyframes. In that, there are two “clips”: one that moves the panel into view from right to left, and one that moves the panel out of view from left to right.
At some point, I had actually had a simple version working. I had just defined the two clips, assigned them to the panel, and was able to call them from script, by name, and it worked flawlessly. Then Unity decided to cough up a techno-hairball and screwed up a whole bunch of UI elements Just Because(tm), forcing me to rebuild a few. That messed up my animation setup, and when I attempted to recreate it, Unity decided that now it wasn’t good enough, and started throwing errors. This sent me in search of a way to animate a UI panel.
Let me tell you: there’s fuck-all for info on how to do something as simple as UI animation in Unity. Doing a search for “animation unity3d” with any additional criteria thrown in only brings back information on how to animate character models or sprites. Yeah, I get that the character is really the heart and soul of a game and it’s also pretty complicated, but does everyone understand UI animation? Am I just Extra Clueless? That’s rhetorical, by the way.
What I had to do was to create the Idle state for the panel, which means it’s not doing anything when you start, or after the panel has moved. I also created two boolean flags: IsOpen and IsClosed, and are using them to brute-force the situation. When the user clicks the OPEN button, the IsOpen is set to TRUE and IsClosed is set to FALSE, which routes the state machine to the SlideIn clip, and then back to Idle. Reversing the booleans when I click CANCEL routes to SlideOut, and then back to Idle.
I can accept this, but I really question why I have to, since I’m not using script and not Unity-proper to handle my buttons. I feel that it would be a lot easier just to build the animation clips for a GameObject, put those clips in a reference bucket on that object, and then call those clips from code to have them play. In fact, I know this can happen, because the Play() method exists, but I can’t find a straightforward tutorial on how to set up the environment in a way that allows me to refer to those clips by name, and since I did have it set up once, but was rebuffed when I tried to replicate that situation, I’m more confused than I was before.