After putting it off for months, I finally sat down to attack this task I had secretly been dreading – adding NGUI support to the accessibility plugin.
What is NGUI and why is it important?
Up until now the accessibility plugin for Unity only supported Unity’s own UI system (uGUI). The system is included in your standard Unity installation and it’s quite capable. But that doesn’t mean uGUI is the most used UI solution in Unity. It’s a still fairly new and some kinks need to be worked out.
This is where NGUI comes in. NGUI existed long before Unity introduced their new uGUI system, and it’s one of the most used, most powerful and best supported UI plugins out there. (And I strongly believe that last bit ultimately led to the first two).
Here’s the link to the plugin on the Asset Store: NGUI: Next-Gen UI
The user base for this plugin is quite large and I don’t want to exclude them, obviously. Since people stick to what they know I don’t expect all those NGUI users to switch over to the new uGUI. Instead, I have to come to them. So, consequentially, the plugin needs to support NGUI.
Work In Progress
I was dreading this task because of all the code changes I would have to make to accommodate for a different UI system. For example, NGUI uses a completely different coordinate system for its UI, and things that were already working fine, like Explore-By-Touch, would basically have to be reimplemented. All calculations have to be adjusted to be able to tell what NGUI element is under your finger.
It turned out I had been worrying over this for nothing. After a weekends work, I already have basic NGUI support running. Navigating the UI with swipes or keyboard works, labels are read and buttons can be pressed. Other UI elements, like edit boxes and sliders are still on the TODO list, but Touch Explore is already working.
It was nowhere near as difficult as I expected. Incidentally, uGUI was written in parts by the same developer who created the NGUI system – because Unity hired him after NGUI’s success. (Smart move on their part!) As a result, there are a lot of similarities between the two systems, that make supporting them both rather easy. The biggest differences are in the calculation of screen coordinates and some juggling with the different UI roots and UI cameras that NGUI is based upon.
But then there is the issue of conditional compilation.
To get the information from the UI elements from NGUI, I need to access NGUI’s script components. But these classes won’t exist in any project not using NGUI. If I don’t separate my code, everybody would get compile errors. One option to avoid this would be to use reflection for everything NGUI related, and that is just such a mess. Not to mention it doesn’t make for easy to fix, maintainable code, in case some of the NGUI interfaces change in the future. Which is very likely to happen, since it is so very well maintained.
The only other solution is to create a pre-processor define that conditionally compiles in or out those bits of code that are only needed for NGUI. The downside of this is that I would like my plugin to work out of the box and not require the user to mess around with the Player Settings to manually add variables.
My compromise is using a preprocessor define, but make setting it up as easy for the user as possible.
The plugin tries to detect that NGUI is present in the project. If it is, it will ask the user to click a button to enable NGUI support and then set the preprocessor flag automatically. I also made it hard to miss. Every component, the About window and the Accessibility Plugin menu will have the option to do this, and the documentation explains how to do it manually as well, with pictures!
Too Long, Didn’t Read
Summing up: The initial release of the plugin will come with NGUI support, right from the start.