UberLogger - Redux
Originally published here.
Having not touched UberLogger framework/) 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!
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:
- 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.
- 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.
- 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!