This post is not about Korn's masterpiece album. Sorry. It is, instead, about a very specific type of issue. We call them bugs. After a busy (yet productive) weekend, I managed to cobble together a few early cutscenes. This was not my first foray into cutscene creation, but I kinda went overboard with the new ones. Specifically, I wanted to talk about the two issues encountered today while attempting to record and upload a video of these cutscenes (Of course, Murphy and his law decide to show up at precisely that moment). Warning: this will be a fairly long and descriptive (aka boring) post.
After getting everything prettied up and presentable as much as possible, it was time to build the executable and run that bad boy. Right off the bat, as soon as Moroch stumbles down the stairs and begins to utter his first lines, a massive freeze-up happens, taking about two seconds to resolve itself. This hiccup, as it were, did not show up at all in the debug build (I believe that's the third or fourth law of programming, but don't quote me on it).
So we go back into the Unity editor. Unity, by the way, has an extremely handy tool that I had mostly taken for granted as a student and a younger developer. This little tool is called a profiler, and when hooked up to the program, immediately shows the culprit: the very first time we go to render any text, (but never any time thereafter), some random function decides to shit itself. I can't really follow it too deeply, but the actual issue seems to be something to do with loading cached fonts. Amazing. What is the point of a cache exactly?
So, we decided to consult the programming bible. After a quick google search, we found a bunch of different proposed solutions. Like any lazy bastard, I tried the 'fixes' in order of increasing difficulty (aka, changing a setting as opposed to needing to write a custom script). Despite our efforts, guess which method ended up working? Somehow, people are always able to find multiple solutions to these problems, but the easy ones NEVER work for me. Haha. Personal rant. Anyhow.
So, after a few modifications to a mostly-pieced-together script, we basically needed to 'force' Unity to load these fonts upfront. An unfortunate side effect of having the ability to dynamically change font sizes/styles is the fact that Unity, for some reason, needs to render all of this to a texture the first time you try to display it. The issue, mainly, is that Unity does not do this at the beginning of the script/program in any meaningful way. Basically, our custom script forces Unity to do just that, thus shoving this overhead to the beginning of the program and not in the middle of it.
With that out of the way, it was time to keep pushing on. The second issue had actually shown itself several times during development, but I thought I had killed it. That's the twelfth law of programming: Bugs never die. They just hide forever and come out every once in awhile like a nice swarm of cicadas/herpes.
This particular bug involves scene transitions. Specifically, during our scene transitions, we display a black texture laid across the entire screen. We smoothly fade from 0 (Aka, you don't see the black texture) to 1 (Aka, you DO see the black texture). Pretty standard stuff. We can control both sides of the transition, fading out (leaving a scene) and fading in (entering a scene). So far, so good.
When transitioning from cutscene to cutscene, Bodom's position in the scene actually changes as does his animation. For instance, at the end of the first cutscene, Bodom is laying down. At the start of the second cutscene, however, he is sitting on the bed, perhaps, not understanding how beds actually work. In order to produce an acceptable result, the position needs to change AFTER the fade out but before the fade in. This part is no problem at all--setting the position of something is more or less instant (or until the next update loop).
The issue, however, came about when trying to transition from one animation to the other. Without going too much into it, Unity handles animations rather nicely by providing what is called an Animator Controller. The way this works involves 'animation states'. There is a state for walking, a state for idling, a state for sitting, et cetera. Unity allows you to 'blend' between these states. It takes one pose and it takes the other pose, and over some amount of time, makes one pose match the other. For example, if you have an animation for idling and an animation for throwing a ball, without blending, you would simply go from idle immediately to having your arm raised in one frame's worth of time.
This behavior is clearly incorrect unless your name is Dock Ellis. For everyone else, there is a smooth transition from having your arms at your sides to throwing a damn ball. But for the case of the scene fading in, we do not want this transition. The reason why is because we basically want this transition to occur while the screen is completely black. We want it to happen before the fade in entirely, so that as soon as the alpha value begins to change, we can see that Bodom is already in the correct pose. There is a small window of time available in which to do to this. Basically, this required me to guess a bunch as to how long I waited to start the animation transition so that it would not be visible at all.
There were two immediate solutions to this: one bullshit one and one moderately ok one. I obviously went with the former, but with a slight modification to make it less bullshitty. Since that's what I went with, and I know the tension is palpable already, I'll explain the second solution first.
The moderately ok solution is to actually just set the animation transition from laying down to sitting up to zero. In this way, there would be no actual timing window (we hate timing windows) in which I needed to start the transition and I could do it immediately once the scene had loaded, but before the screen transition had started. The main drawback to this solution is that any other part of the game that would want to use this same transition would also have no actual blending. The main point being, it's fine to transition without this 'exit time' as long as the character cannot be seen. If the character can be seen, however, it's just not realistic (but it is slightly humorous).
This could still work, however, but would require different states for the same animation transitions: ones without exit time and ones with exit time. While it would fix the problem without actual code (which is always a plus), it would cause other issues down the road with maintainability and complexity. (two big minuses)
The first solution is pretty cheap: basically, we insert an artificial delay every time we are loading a scene. This means that the screen is guaranteed to remain dark for at least some pre-defined amount of time. This has a few issues: first off, it's an artificial delay, and it's almost never a good sign when you need one for something. Second, if the delay is only a half a second and the transition takes a full second, then guess what? YOU SOLVED NOTHING.
Sorry for yelling. Ahem. So, the modification was to account for this extra time if it existed and essentially only delay if the exit time was greater than zero. This meant that there was no possible time frame in which the character could be sliding around like an idiot, instead of sitting down and shutting up as he was told.
OK. That's all for now. Thanks for reading.
Monday, June 29, 2015
Subscribe to:
Post Comments (Atom)

No comments:
Post a Comment