I’ve been planning for a while to do a regular Unity “tips and tricks” post on my blog. So I thought what better time to start a week after Unity 4 has hit our shelves (figuratively speaking). Now, in writing these tips and tricks post I don’t want to come off all pretentious, and wave an “Alex knows best” sign in your face. These posts will serve more of a “avoid things I did wrong, so you don’t have to deal with them” sign. The plan is each month I’ll list 3 – 5 tips that I’ve stumbled across, and what they’re useful for.

So to fire off this month’s post we’ll be looking at “common pitfalls”, dun dun dunnn. This basically equates to things that I’ve done and see on a regular basis that make projects more difficult to manage, degrade performance, and are generally bad coding practices. Which now Unity is becoming more and more popular, you as a developer, will be working on bigger an bigger projects, with more and more complicated implementations.

 

Tip 1: Encapsulation, makes life easier for everyone.

One thing that I started to do when I first began using Unity, was using public member variables over private ones. This immediately made me feel uncomfortable, as my lecturers had been spitting the words “encapsulate classes, don’t expose member variables, accessors and mutator methods” in my face since day 1. The biggest problem I faced, was that when I wanted to change a variable in the inspector, making it public is the only way I knew how. However, that all changed when I delve a bit deeper, and learnt how serialization works.

Before we move on, the people reading this that aren’t new to OOP and it’s principles can just skip this paragraph. However, for the people that have picked up Unity without a grounding in OOP theory, may be asking “I get the same results either way. Why should I care about encapsulation at all?”. Well, the main advantage of encapsulation is that it’s a good coding practice to get into, plus it’ll save you bags of time later down the line. Imagine, logging a variable only to see it’s being changed somewhere, in some other class, and you don’t know why. Encapsulation would prevent things like this happening. Furthermore, imagine every time you want to set a variable, you also want to apply that change to another variable, or set a colour of an object, with a single encapsulated set method, you could change a couple of lines of code, and voilà, you’re done!

 

So next time instead of this:

// For C# users
public int maxHealth;

// For UnityScript users
public var maxHealth : int;

 

Try:

// For C# users
[SerializeField]
private int maxHealth;

// For UnityScript users
@SerializeField
public var maxHealth : int;

 

Or if you you’re a bit of a minimalist, you could try:

// Excluding the access modifier for a variable will default it to private
[SerializeField]
int maxHealth;

 

Tip 2 : Encapsulate field option in MonoDevelop, speeds up writing getters and setters

How many times have you wrote, or copy and pasted a c# get and set method? Don’t you wish there was an easier way? Well, today’s your lucky day. Right I’ll stop the cheesy sales talk, and get right to business. A nice little feature I found in MonoDevelop is it’s “encapsulate fields” option, which allows you to select any field, and then MonoDevelop will generate the getters and setters for you (also allowing you to set other options, such as their modifiers in the process).

 

EncapsulateFields                    EncapsulateWindow

 

All you have to do (see above) is right click on the field, select encapsulate field, and a dialogue window will appear. Select the options you want, i.e. access modifiers, do you want it to be read-only and you’re done. There you go, you’ll never have to write or copy and paste another getter and setter. Not really technically amazing, but it’s little things like this that will speed up your workflow, and allow you to produce more code in a shorter space of time. Remember, the old saying “Time is money!”.

 

Tip 3: The print command

The print statement is simply Debug.Log() wrapped and inherited from the MonoBehaviour object. It has it’s disadvantage of the fact that if your class doesn’t inherit from MonoBehaviour, then you can’t use it. However, it’s advantage is that it saves you time, albeit a few seconds. So this one is more of a personal preference, but one that quite a few Unity developers (especially ones that primarily use c#) don’t know about. Note, it doesn’t allow you to pass an object for context, like Debug.Log(message, object) but for the 99% of times you need a simple Debug.Log(), I say try it out, and see if you like it. It generally saves me a lot of time, for quick traces.

 

void Start()
{
// The print statement is Debug.Log wrapped
print("Example");
}

 

Tip 4: Remove any empty Awake, Start and Update functions

Although arguable negligible in terms of performance, it’s still a good coding practice to get into. Unity will still use reflection to run empty Awake, Start or Update functions, which will create a small overhead. As mentioned it’s pretty negligible but if you project is riddled with these, and has a lot of instances, it can mount up. You’re still be going to get much more performance from other areas of your project, but getting into this practice will A) make your code run slightly faster and B) keep your code tidy. So why would you not do it?

 

Tip 5: Design, Design, Design

Without trying to sound too preachy, I think this one applies especially to Unity developers. Unity has always been known for it’s rapid prototyping prowess, and ease of access; it’s in my opinion Unity’s greatest strength. However, we have all had the tendency and temptation to just think “I’ll just reference that here, add a script there, use a singleton here” and if it works were happy. But remember at the end of the day, we’re still creating a piece of software and software design rules still apply. Wow, I do sound preachy!

This tip isn’t meant to serve as a Matilda “I’m right, your wrong” moment. More of a “I’ve made the mistake numerous times, so keep mindful of design, since it’ll save you a lot of hassle further down the line”. So you should always be asking yourself how can I make this more elegant, more efficient? If I wanted to change the system, how flexible is my code to do so? Will this code affect performance? etc.

Good architecture and good coding practices, will saves you bags of time later down the line, and you’ll be so happy you invested the time now, to save you the trouble later. Trust me, I’ve been there, done it, got the hours of error tracing to prove it (still waiting on the t-shirt though).

So that’s all folks, I’ll write another one next month, focusing on a different theme, I’m thinking graphics optimization tips. Hope you’ve enjoyed this, and it helps in some way.