User experience (UX) refers to a person's entire experience using a particular product, system or service. - Wikipedia
I am a programmer, and I make games with Unity. Most of the times when we talk about UX in the team it’s from an end user perspective. “How can we build the game in such a way that it is intuitive to use for the player?” But as a programmer the users I directly impact with my work are my fellow programmers and other developers in the team.
In this post I like to talk about how to make the “Unity experience” as intuitive as possible and my ‘10 golden rules’ of achieving this. Eventually this will save a lot of time and makes working in Unity a lot faster and less painful, paving the way towards that ultimate end-user UX.
I decided to write this blogpost after watching this awesome video Entity System for Unity. I figured I could add some of my personal experiences from working with Unity to the mix.
The idea behind entity frameworks and the Entitias system itself is amazing. I played around with it a bit, did some small experiments, but after some time I fell into the same pitfalls I've I fell into so many times. It is just too counter-intuitive for any (Unity) developer - seasoned or not - to ask them to fix a bug, and expect it to be fixed fast.
The Entity system is very deep and optimized, and of course there are games out there that are in need of such a system. There is nothing wrong with the usability or the implementation of the system, but from my point of view it is an overkill of complexity without actually returning much of the initial investment. The point that I am trying to make that in order to get the best UX, you have to meet the needs of the user in regards to everything they already know about the subject.
There are a lot of right ways of doing something, thus no one right way of doing anything. Every single tutorial I took during my ‘critical period’ taught me things in a different way. Some of the tutorials used a lot of inspectors, some of them used none. Some of them used depth complex inspectors, some of them did everything by code. This freaked me out because I had no "best" way of doing anything, unlike the other languages I was used to working with.
Now, almost 7 years later and having worked with a lot of different developers in different teams, I found some best practices for myself. But let’s start with something Unity isn’t good at, and which hurts the user experience a lot… consistency. I’d like to walk to a couple of examples to paint a good picture.
Example #1: Unity and monobehaviour.
Unity harbors so many different methods in which monobehaviour can be implemented, and most of them are in a slightly in a black box. For instance, you have something like hits:
OnEnable, OnDisable, OnTriggerEnter, OnDestroy and 20 other OnSomething methods in Unity. Besides that you also have: Reset, Awake, Start, Update, LateUpdate ... methods! WHY NOT OnReset, OnAwake, OnStart, to keep it consistent?!
And this applies to a lot of other things in Unity in as well. You got a couple of property drawers working in this way, and a couple of others working in a completely different way but accomplishing the same thing.
I do like how Unity is dealing with the new Physics Raycaster. Basically you can implement IPointerEVENTHandler in any monobehaviour that has a collider on it, 2D or 3D and you get a nice implementation of the method:
In the future I would like Unity to do something like IOnAwakeHandler to get to a nice onAwake method. I’m not sure if having a lot of interfaces is the best solution, but at least bring some consistence.
In general this applies for a lot of things, like Unity Actions for example. Unity introduces this to get a better UX for non-programmers. But it can become an big issue in bigger projects with larger teams and a larger codebase.
Example #2: Unity and UI
Let’s imagine that you have a really complex UI. And somewhere deeply hidden in this UI there is a button that is supposed to open a different window. You could easily do something like this:
Looks great right? But now comes the bad part. Let’s say that someone else wants to add a new parameter to the AwesomeMethod, like a ool,this is what your reference will end up looking like.
Or even worse, someone needs to know who is using this method, to add something else to it.
That's right... Zero references! From the code we cannot know if this function is actually being used or if it's dead code lying around. No programmer wants to touch that! And because of this the dead code starts to pile up, muddying our codebase and making it harder to understand.
This is why I try to avoid Unity Actions and event triggers at all times. I much prefer to have one more class for just this button.
Example #3: Unity and automation
In some cases, usually when building more complex systems, a programmer can try and think how to get things automated. Let’s imagine the following situation:
You have one CharacterConfiguration scriptable object
Your player needs to load the character configurator to work properly
I've seen developers decide to go with this solutions to "avoid mistakes and scene references":
There are some immediate issues that pop up. Firstly that it is a hard coded string. If you rename or remove the file, it is gone. Secondly.. Designers. Designers like to duplicate things to test, and will probably end up doing this:
The easier and simple way of doing it, keep consistent in what unity does:
And setting the original right reference in the script itself:
I catch myself doing this a lot of times, duplicating something and then changing it to for test purposes. But because there is no reference to the object itself, is really hard to understand how you should setup this properly
The easier and simple way of doing this, and keeping it consistent with what Unity does is doing it like this:
And set the original right reference in the script itself:
Of course you can erase or rename the object, but things still can get broken. If you really want to have this, try a “default” to make things easier to use.
These are just a few examples, what it comes down to is that “the programmer way” isn’t always the “Unity way”. ersonally I try to follow my golden rules when building a system, to keep it consistent with what a developer expects Unity to do.
10 golden rules of Unity UX
Always built for for new team members. New team members need to be able to jump into the project and understand the system, or fix bugs in your system seamlessly.
Built features that help you understand how things work. For example: Click to Highlight, Find References in Scene, Find Usage in Code, etc.
If you are building a system, build it in a way that is consistent with what Unity Developers are familiar with.
Following from point 3, if you decide to build something that Unity already provide, make sure it is better or don’t build it.
Merge scenes if necessary. Yes they can be quite painful, but it is still easier than trying to understand an entire class to fix a null reference.
Only build a custom inspector or property drawers if it is absolutely necessary. Most of the time developers tend to overthink functionalities while the final version just requires a simple EditorGUI.Popup\
Building an drag and drop system for an artist is nice, but keep in mind that programmers should be able to work with the tool if it needs a new feature. How easy will it for someone else to add, understand and/or fix bugs in the system?
Avoid Unity Actions and Unity Event Triggers at all costs, it is always easier to create a simple script with a reference to the method.
Built your system for this project, and built it gradually. Don’t overthink the system for the next 10 projects. Start with what you need and built it in a nice fashion. If you want to make it more generic if you are sure you will need it for the next projects as well.
Debug Inspector is your friend! Use it to understand what is going on in with some game object
I hope these tips help make your life and that of your co-workers easier in the long term, feel free to add any tips or feedback in the comment section below
This post is written from my own experience and not set in stone. I am still learning new things every day. Most of the tips are Unity only but you can still use most of these tips in other languages or IDE’s.
Shout out to all my co-workers at Paladin Studios for their support.Stay awesome!