Motivation
You should read this article if you are new to programming or new to the C#, Unity Script and Unity environments and want to know about coding structure and variable naming conventions. You will learn (/hear me rant about)
- Why we have variable naming conventions and why they matter
- How and where to declare variables
- Keeping your code DRY
Warning: this is like discussing religion or politics
There are very different opinions on naming conventions. This article represents the .NET standard (with Unity modifications and a few personal opinions). About the only wrong thing in naming conventions is not to have one, to have one that's half baked, or to have one that is opposite to a commonly practiced convention.
NamingConventions
It is very tempting when you start to program to just call your classes, your variables, your properties and your methods by whatever name you like and using any combination of capital letters, underscores and other paraphernalia that comes to mind. However naming conventions exist for a reason - and it isn't us pedants just wanting to dictate how things are done. Naming conventions do this for you:
- Reduce the number of coding errors you make
- Make your code more readable to someone else who looks at it
- Make your code make more sense to you when you come back to it after a month or two
- Reduce the need to create masses of documentation by self documenting your code
Identifier Names
Make your identifier names meaningful, even if it makes them long. If you use a decent editor like Visual Studio or MonoDevelop you will hardly ever type them all anyway - so do yourself a favour and don't write code like this:
var p = transform.position;
for(var i = 0; i < ar.Length; i++)
{
p += ar[i];
}
Does this make more sense to you?
var endPosition = transform.position;
for(var step = 0; step < pathStepVectors.Length; step++)
{
endPosition += pathStepVectors[step];
}
When you declare a boolean variable give it an auxilliary verb so that it has more meaning. For example alive is less useful than isAlive which clearly shows that your are sampling something that has a present value relevant now; activated could imply that something was ever active or that it was active right now while that question would not arise if you called your variable isActivated or hasActivated.
Capitals & Why They Matter
Ok so first here's the rules:
- Class names always start with a Capital letter
- Therefore, because classes and scripts are closely related in Unity, script names start with a Capital letter
- Public and protected fields of a class start with a lower case letter*
- Public and protected properties of a class start with a Capital letter, but Unity regularly uses lower case itself, so you can just adopt the rule:Properties and fields start with a lower case letter
- Methods or functions always start with a capital letter
- Private properties and fields of a class start with an _
- Parameter names start with a lower case letter
- All identifiers are written in camelCase - where the first letter of every new word after the first one is a Capital letter.
Camel case is great as itReallyMakesReadingIdentifiersFarMoreEasy - thanifyouwrotethemlikethis - and it is far_less_cumbersome_than_using_underscores.
Right so straight away I know that:
- thisVariable = 5 // does not call any code that has any effect, because it starts with a lower case letter.
- ThisIdentifier.thisValue // is probably a static variable (though it could be the value of something returned by a property - heh nothing's perfect) - I should be able to recognise ThisIdentifier as one of my classes
When I write a function that takes parameters I often want to store them in variables in my class - it's good to be able to have private variables start with a _ because then there isn't a naming conflict (and of course, I know that they're private!)
function SetTarget(targetPosition : Vector3)
{
_targetPosition = targetPosition;
}
Is clearer and more obvious than prefixing the variable targetPosition with this. every time we need to make a distinction - likely to lead to problems that. In fact it's also usually a good idea to make parameter names more obvious too:
function SetTargetPosition(newTargetPosition : Vector3)
{
_targetPosition = newTargetPosition;
}
Hungarian Notation
The standard way to name variables in C++ was always to use Hungarian notation so you can work out what type the variable actually refers to - it's kind of more important in C++, but not much and it lpszMakes szYour m_lpstrCode somewhat hard to read as you have to skip past a whole usBunch of characters to get to the meaning, and in any case do you know if a lpszVariable is actually compatible with an lpstrVariable? It's not obvious that it is. That and half the time you can't remember whether bByte is the right notation or is that bBoolean - hang on that's sFloatingPoint for a single isn't it and fBoolean for flag? Don't even get me started on arrays and other higher level collection structures.
It is not recommended to use hungarian notation, nor is the distracting m_inFrontOfAllMembers very clear is it? Don't use it. A variable is a variable - plain and simple, a private variable is far more legible as _variable and readability is actually more important than variable types to the meaning of your code.
Where and How To Define Variables?
Best practices currently dictate that variables in a function should be defined as close as possible to their usage, being defined as they are initialised is the best choice if that is possible.
Also remember that variables in a function have been allocated on the stack and are not initialized with their default value so you should always ensure that they are initialised before they are used or allocate the default value yourself.
- var x = 0; //x is an int
- var x = 0f; //x is a float
- var x = new Dictionary<string, float>(); // x is a dictionary of string to float
var lookupWeight = new Dictionary<string, float>();
Than this alternative:
Dictionary<string, float> lookupWeight = new Dictionary<string, float>();
It takes me a moment to even find the variable name in there, especially if it's buried in a bunch of other code and definitions.
One school of thought is that var should only be used for prototyping and that you aren't a proper programmer if you use it otherwise.
The other school, of which I am an evangelist (did you guess?), says that actually being able to read your code quickly is the most important part of the creative process and debugging process. Any accidental errors, like initialising something you wanted to be a float with an integer, are immediately caught in the compiler anyhow.
In fact when I'm calling a function to return a variable value then I really don't need to remember what the actual type is that's coming back from it is - so long as I (and intellisense) know what properties, methods or fields it has and whether I can access it with array semantics!
var newEnemy = CreateEnemy("Bob", EnemyType.pedanticProgrammer);
newEnemy.EvolveNow(); //Intellisense knew what newEnemy was
//I don't need to
This becomes even more important when using Linq or anonymous classes because it can actually be very hard to work out what the return value is, even though you (and again, intellisense) know exactly how to use it.
Where do you put variables in a class? Well I put the public ones at the top and the private ones close to where they are first defined and used. I don't do scrolling when I'm concentrating and I like to see the public variable interface of the class closely tied together. I will also put properties first, just after fields.
Subclasses and Enums
So you can define helper classes inside other classes or in global scope - if this class is ONLY going to be use in reference to another class or its functions then define it inside - Unity 3.x doesn't support namespaces so anything else will just end up with clutter. If you define subclasses then they should come at the bottom of your outer class definition. Remember to use #regions to simplify your file structure.
#region Is your friend for logical groups of code //Logical block of code #endregion
The argument for Enums is slightly less clear - simply because you will probably end up typing the name of them when you pass them as function parameters or set field or property values.
var easedPosition = Easing.EaseInOut(currentTime, Easing.EasingFunction.LinearEasing);
The answer in my case is to define enums in global space if they are used outside of a class often and if they are defined in the class, I think about how the final code will read and try to do something like this:
//Either: var easedPosition = Easing.EaseInOut(currentTime, EasingFunction.Linear); //Or: var easedPosition = Easing.EaseInOut(currentTime, Easing.Function.Linear);
In the latter, Function makes sense because externally it will be preceded by Easing and internally it's fairly obvious that this is an easing class.
Don't Be Wet Be DRY
DRY stands for Don't Repeat Yourself and it is a mantra that should be playing in your head all the time you are writing code. Cut & Paste can be the enemy of productivity. You write some code, you cut and paste is half a dozen times and everything is dandy - right up to the point where you decide to refactor or fix a bug and then you have to find all of the places you pasted that code - in the end you will forget one and the bug will go unnoticed for ages.
Bite the bullet and write a function if you are going to do exactly the same thing in multiple places. Try to organise where these functions live - create a global static class and put general utility functions in there. The effort of thinking about a function can be useful too:
- Pretty much all coding involves holding only a part of the whole structure in your head at a time. When you are writing code and just type in the name of a function in line and move on, then fill out that function afterwards.
Black box in other words - don't even worry yourself about how it will work until you fill it in. Sure you may have to add some parameters, but pretty quickly you will find you are building useful function prototypes as you code. Some refactoring tools will actually just build these functions out for you - working out all of the parameter types and names by inferring them from the variables you passed to the non-existent function. - Thinking about functions and the parameters helps you spot the theoretical mistakes in your architecture - you will write better code.
Always try to write a function that is efficient but has the maximum flexibility - the whole of your code is effectively the software equivalent of Frankenstein's monster - these functions are going to be the beautiful elegant bits!
Conclusion
The most important thing to do is be consistent, concise but readable in your identifier definitions and always indent your code. If you've indented more than 4 times, consider refactoring to multiple functions. Your code should be as DRY as possible.
The conventions presented here represent my view on the current recommendations from .NET and Unity - feel free to argue, rant, rave and call me names in the comments section.

November 14, 2012 - 11:58 pm
An excellent article! I’ll use it to show our fresh and new student developer why coding conventions aren’t bad (or as he may think just for that I could argue about his code).
Thx!
November 19, 2012 - 9:09 pm
Great article, thanks for taking the time to write it down, it kind of rewrote the programming() methods in my brain in a more consistent, concise, and readable way
Cheers!
E.
November 20, 2012 - 3:17 pm
Great article, I’ve seen way to much code that has no standard at all…
A few thoughts:
I don’t think it’s necessary to use “_” in front of private variables, for a lot of people, reaching for the underscore key, takes away from a good typing flow. Just start use Camel case on all private variables and Pascal case on all public.
I actually think it’s cleaner to use the “this” keyword, than an underscore:
Public void SetTarget(Vector3 targetPosition)
{
this.targetPosition = targetPosition;
}
Code order:
I think it’s easier to see all the variables/fields at the top in an order something like this:
Static variables
Public Fields
Private variables
Properties
Methods
You mentioned that for class private variables you put them “close to where they are first defined and used”. That could be a cause of scrolling around trying to find it, if they are all at the top, you know right where to go. There is also a school of thought that says a private variable should be touched by most methods in the class, otherwise that is a sign your class is doing too much and another class may need to be created.
One thing you didn’t mention is booleans. A good convention is to always start them with an action. A variable called “isDead” makes more sense than “dead”. You instantly know it’s a bool by reading it and reading your code will flow better. Just don’t use negative bools like “notDead” that can start to get confusing.
These are just a few things I prefer and have found work well. Keep up the great articles!
November 20, 2012 - 3:24 pm
Good points – I know a bunch of people who like using “this” rather than an underscore, but I prefer the clarity, especially given you can forget to use “this” the code compiles and when you are reading it you aren’t sure what is private and what isn’t. Each to there own I say
Great point on the booleans – yes no action is a bad idea – will add that to the main article.
On the location of private variables – I’m not sure I agree with you on that – I tend to have private variables that are related to a series of functions and define them near that, if there get to be a lot, and they are truly used abundantly, I would refactor like you suggest. I find that CMD D/CMD SHFT D is my friend on all variables though – never really go looking for them
November 21, 2012 - 7:26 pm
I’ve spammed a comment due to an expletive in the (fake) email address which is visible on this site:
The comment read:
This is terrible
In one sentence you speak of .net and c# then show us a bunch of javascript in the next
My response:
The naming conventions for C# and Unity Script (JavaScript) are the same. In Unity the version of JavaScript is a .NET derivation (more like Action Script than real JavaScript) and so the style should be maintained between both.
This tutorial deliberately mixes Unity Script and C# to show examples, as the code in this article is not designed to be used I considered that to be a reasonable way of showing the methods being used in both languages.
April 1, 2013 - 7:22 pm
Thanks for the good read. I too prefer not to use this.x syntax if I don’t have to.
Although I still consider is very important to know or be aware of its existence and functionality in order to better understand OOP concepts for those new to coding.
Also another drawback of Hungarian notation my mentor told me about is the case where you do find yourself needing to change the type of a variable after being used in a lot of code by any chance during code maintenance later on after such code has grown large enough.
April 13, 2013 - 2:40 pm
Excellent summary of this type of conventions.
I tend to use Capital letters for all Public variables, same for u guys?
April 29, 2013 - 2:37 pm
Pretty good tutorial.
One thing struck me as false though, “The standard way to name variables in C++ was always to use Hungarian notation so you can work out what type the variable actually refers to”.
No it wasn’t. Most of the popular coding standards followed by a great deal of C++ programmers (including myself) explicitly say to not use Hungarian notation. It’s not just avoided, it’s widely hated by quite a few.
April 29, 2013 - 3:13 pm
Well in my day every C++ programming book had hungarian notation in it. As you can probably tell – I hated it too. I guess it depends how old you are…