Category Archives: Uncategorized

UberLogger – Redux

Having not touched  UberLogger for a while, two users contacted me this week with some very decent feature requests (thanks Steve and Gavin!). What should have been a fairly quick set of changes turned into an extensive rewrite. But good news – version 2 is now live!

screenshot_238.png

The core of the work was around  Unity’s GUI ‘layout’ system which takes care of placing GUI widgets. Instead of specifying positions for controls, you express your layout in terms of ‘vertical’ and ‘horizontal’ sections and flexible spacers and let Unity do the work of translating that into pixel positions.

Unfortunately I hit the point where it became more trouble than it was worth. Specifically:

  • I wanted to add ‘auto scroll’ to the logging list, so the logging window will automatically move to the end of the list. In order to do this you need to know where the end of the scroll window is… and when you use layouts you don’t know where the controls will end up. I tried working things out by myself, but ultimately just ended up fighting with the layouting.
  • Internally, when doing the layouting, Unity calls OnGui multiple times, first to get the control positions and then to render; in order for this to work it needs the results to be consistent between runs. This is normally fine, but I wanted to optimise the log view list, which gets slow when you’re adding 10k elements to it every time OnGui is run. The obvious optimisation is to not add elements that you know are outside of the scroll view (by calculating the positions of elements by hand) but this confused the layouting system – things were different between runs, and Unity complained.

Laying things out by hand is more work, obviously, but wasn’t actually as much trouble as I was expecting, and doing so allowed me to remove some fairly hacky bits of code and make the rendering several orders of magnitude faster.

After that, there was a fight with GUI skinning; as Gavin pointed out, UberLogger didn’t work nicely with the dark ‘Pro’ skin. Unity’s internal GUI skinning system is nice and flexible, but when you’re writing an add-on that’s meant to fit in seamlessly with the existing editor GUI skin you don’t want to create a new skin, you need to harvest what’s already being used. ‘EditorStyles’ is your friend here, and contains all sorts of useful styles you can reuse (like ‘toolbarButton’, for instance).

Unfortunately, it doesn’t contain all the styles the editor uses, and the console ‘log line’ styling is notably absent. UberLogger originally bodged around this by grabbing a slider bar control and hand-modifying some of the textures and colours – which is why it didn’t work on the Pro skin.

After poking around a bit, I realised that you can find all the GUI styles by iterating over GUI.skin.customStyles; spitting out the names, I spotted ‘CN EntryBackEven’ and ‘CN EntryBackOdd’, and harvested their organs for my own logger styles.

Finally, an old and somewhat poor design decision came back and bit me. When I started writing UberLogger I initially had difficulty extracting all the information I needed from log calls made via Unity’s own Debug.Logxxx methods – in particular, you don’t get a useful callstack from them. My initial approach to fixing this was to spoof the Debug namespace with my own static Debug class and thus capture all calls to Debug.Logxxx. This works, but:

  1. Doesn’t fix the problem with extracting callstacks from errors fired deep from within the bowels of Unity itself. This was fixed a while ago by wrangling the log message Unity gives to you.
  2. You have to spoof *everything* in the Debug namespace, even stuff you don’t care about. This is messy and guaranteed to break if ever Unity add something to the namespace.
  3. You can’t spoof everything – as Steve pointed out, among other things Debug.isDebugBuild is a property, and you can’t have properties in static classes in C#. Unfortunately this was breaking the Unity Test Tools, which is a bad thing.

Thankfully, since 1. was fixed ages ago, the proxying wasn’t needed anyway. So I’ve now moved all UberLogger debug commands from Debug to UberDebug, and renamed them from ULogxxx to just Logxxx. Obviously this is a breaking change, but I think it’s a legitimate one.

So – version two features!

  • Much, much faster rendering when there are lots of elements in the log window.
  • Pro skin supported.
  • No longer conflicts with Unity Test Tools.
  • A new ‘Collapse’ button – works like Unity’s collapse button, but grouping similar messages together.
  • A new ‘Follow’ button, which makes the log window scroll to follow new messages.

As ever, you can get UberLogger from here.

Let me know if it works for you, or if you have any problems!

UberAudio – an improved audio workflow for Unity

A few months ago I decided to rewrite/tidy-up and open-source a bunch of Unity add-ons I’ve written and regularly use. First up was UberLogger, a drop-in replacement for Unity’s debug console. Next up is something slightly bigger – UberAudio.

Much like UberLogger, UberAudio is designed to take something in Unity that’s good and make it better. Unity’s built-in audio system is very powerful, but I found the workflow fell a little short of my needs; but, as ever, the marvellous thing about Unity is that it’s so easy to extend. Specific areas of audio workflow that I wanted to improve include:

  • Keeping AudioSource settings out of scenes and prefabs. If the settings of an AudioSource aren’t correct, you shouldn’t have to hunt around for it and check out a scene or a prefab. All your audio should be in one place, and not in a scene.
  • Similarly, if you want an audio designer to do a pass on the audio in your game, they should be able to do so without touching levels, prefabs or code. They should be able to drop new audio into the game by themselves.
  • Loading. You should be able to load up audio data without having to load a new scene. UI audio, audio variations, dropping audio for things you aren’t using to save memory, even swapping out audio sets entirely – you should have control over what’s loaded and when, without changing any game logic.
  • Flexible audio triggering. It should be trivial to play a random sound from a selection. Similarly, if you’ve got a variety of different creature types and they share some sounds and not others, it should be easy to create defaults and override the ones you need, without touching code, scenes or prefabs.
  • Lifetime management. If a creature is playing some audio when it dies, most of the time you don’t want the audio to die immediately with it; it should finish playing first. Likewise, if you have something that plays a looping sound (a buzzing bee, for example) and it dies, the loop should be released and then end naturally. This should be the default behaviour.

UberAudio solves all of these problems, and several others, and does so without getting in your way – you can always get a handle on your raw AudioSources if you need to. It’s based on the audio systems I wrote for Dungeon Keeper and Fable, so the core design has been tested in fairly intensive production environments and historically has scaled well.

The workflow is very simple:

  • Create an audio bank.
  • Add audio to your bank.
  • Mount the audio bank in your scene.
  • In code, trigger audio ‘events’ on GameObjects. These events have an intelligent lookup system (see the readme) so you can easily create default sounds and specialise them later on in your audio banks.

Editing audio banks in Unity looks like this:

screenshot_230

As you can see, you have exactly the same level of control over how your audio behaves as with normal AudioSources but it’s all grouped together, with some extra fields for the new functionality.

Obviously this isn’t a competitor for great tools like wWise, but if you’re looking for something simple, flexible and free, UberAudio might be what you want.

Take a look and let me know if you find it useful. Feature requests, bug reports and pull requests are always welcome!

Simon

UberLogger – a replacement Unity console and logging framework

I’ve been using Unity for a few years now and have developed a deep and unhealthy love for it. As a game development framework it’s easily the most expressive and flexible system I’ve ever used, in 20 years of making games.

However, as with most things, there’s the odd bit of friction that could be smoothed over, and one of the joys of Unity is that it allows you to address them when you want to. I’ve developed a couple of such things over the years, which I intend on releasing freely to the community.

First up is a replacement logging system for Unity. Unity’s built-in logging system and console are great – being able to click on logs to select game objects, viewing callstacks, etc are incredibly handy features. But I found myself wanting more. Specifically:

  • Debug channels. When you’re trying to ship a game debug messages can get very spammy, and make it difficult to sift out the signal from the noise; at the same time those spammy messages can often be useful for tracking down rare bugs. Debug channels allow you to categorise your messages as ‘loading timings’, ‘weapon debugging’, etc, and limit your view to a particular channel, allowing you to keep all your messages without being overwhelmed by them.
  • Filtering out stack frames from the callstack. It’s not uncommon to want to create your own debug layer to manipulate your logging before it hits Unity. Unfortunately, by default your new methods appear in the callstack, and the source of the error is shown to be your own debug method, which is annoying – you want some way to remove elements from the callstack.
  • Inline source view. You see a bug and you want to quickly see the source code around one part of the stack frame, without necessarily jumping into your text editor.
  • A modular system to allow different backends to process logs. I want to be able to write my own file logger, or my own in-game console, and have full access to the callstack, etc.
  • Timestamps! I want to see when a log happened.
  • A more compressed view; Unity’s console uses space somewhat inefficiently, using two lines of text for every log.
  • An in-game console. Sure, much of the time I’m working in the Unity editor, but sometimes I want to see my messages on my target device.

UberLogger addresses all of these issues and some more. It’s a drop-in replacement for the default logging framework, so no code changes are needed – Debug.Log, etc, all just work, though if you want to use features like channels there are some new methods.

In the editor it looks like this:

UberConsoleEditor

And in game it looks like this:

UberConsoleGame

It uses an MIT license, so if you’ve got any features to add send me a message (or a pull request). And if you find it useful, let me know!

Simon