Hi guys, Sen here from gaming reborn studio and today I want to talk to you about the most common mistake programmers make when switching to Unity3D.
So you’re a seasoned software developer, you’ve worked on a few projects, maybe you’ve been in the industry for a while, or maybe you just finished your degree in computer engineering.
Whatever the case is, you probably have a pretty clear understanding of how to develop optimized and robust software and you’ve developed a relatively specific method of thinking about what you are doing.
I’ve been a Unity3D developer for over 5 years now and have worked with many software developers that have started working with Unity for the first time and they all had this specific way they were thinking about programming and software design that is great for websites, applications and programs, but are simply wrong when thinking about video game development and Unity3D specifically.
Now you’re probably thinking “what is he talking about?”
I am talking about the lifecycle of a software.
When you are developing a software, or an app, or a program, you have a very clear idea in mind about what is going to be the lifecycle of whatever it is you are developing.
If we take web development as an example, we can clearly control every stage of the lifecycle of our webpage.
We start off by writing down all the functions we wish to happen before the page loads and put them one after the other in our code, having full control of what happens before and what happens after.
Most web development platforms, such as .ASP will even provide us with a multitude of functions to put our code in, which define the lifecycle of our web page, such as Page request, Start, Initialization, Load and so on.
Only when the page finished loading, can the user actually interact with it and start a new function, by, for example, pressing a button.
The new function will also, usually have a pretty clear lifecycle.
If we, for example, wish to send some information to the server, we might have something along the lines of - user pushes a button, function takes information from the fields of the page, checks information validity, sends information to the server, server checks validity again, writes the information to the database and gives back a response to the page, that loads the next page.
The lifecycle can be very complicated, have a lot of branching options and calculations, but it should always be 100% predictable and the developer should have full control of what happens when.
This means it is a good idea to pre-plan everything that you are about to be doing in advance and have a chart explaining all the possible functions that may be triggered in the lifecycle of the software and the exact order they’ll be called.
That is not the case with Unity.
Now, I‘m not saying you shouldn’t plan when developing in Unity, but I am saying you should let go of the notion that you will know exactly which functions and scripts will run in which order and here’s why.
Unity and other game engines, for that matter, have a very different life cycle than that of other programs.
Unity has, what is called scenes. Whenever you load a Unity software or application, you effectively load its first scene.
All objects in the scenes with scripts attached to them, run simultaneously when the scene is loaded.
Now, of course, they don’t “really” run simultaneously and there is an order to it “under the hood”, but it is a good idea to think of them as if they do.
In order to attach a script to an object, it has to derive from a class called “Monobehaviour”. In that new script, you will need to write a function called “Start”.
Whenever an object is created, either by being in a scene that was loaded or by being generated into an existing scene via something called “Instantiation”, it’s Start function is called.
If a scene loads with several objects, all having different scripts (or even different instances of the same script), all of the Start functions in those scripts run “Quote on quote, at the same time”.
Additionally, after the scene finished loading, objects in the scene stay “alive” by performing different operations in the Update function.
A scene in Unity runs in frames. All the different scripts currently in the scene run one after the other along with some auxiliary scripts, the frame is rendered and the loop happens again. The number of times this happens in a second is called “Frames per second” and it varies greatly, not only from scene to scene, project to project and device to device, but also from frame to frame.
This means that every frame, some objects in the scene will perform different actions such as checking data, moving, performing animations and so on.
As a programmer you need to work around not knowing which which scripts will run first and which will run after, or even how many times per second a single script will run.
Each object is fully autonomous and should rely on other objects finishing their jobs first, only in very rare and specific cases.
Now I’m not saying it is impossible to control the order the scripts run and in some extreme and rare cases there is no other choice, but in general you shouldn’t do that.
In all my 5 years of development in Unity3D I have done that maybe 3 times.
I would like to also mention that in addition to Start, that runs when the object is created and Update, that runs every frame, there are some additional functions in The Unity lifecycle, such as Awake, that runs before Start and FixedUpdate, that runs a fixed number of times per second, regardless of FPS.
But those are a subject for a future video.
Now, if you’re a seasoned software developer, I know what you’re thinking - Each object runs on its own thread and doesn’t rely on other objects to do it’s job? That’s called threading!
Well not exactly.
The Unity life cycle and threading have a couple of major differences.
First of all, there are no actual threads opening in the operating system.
Second of all, everything is controlled and runs at the same speed.
If you have started two operations that will run for 30 frames, they will both finish in the same frame.
It’s true that you don’t know how much time that will take, but unlike in threading, the FPS of all the different scripts is the same across the board.
And third, all scripts can affect and manipulate each other freely, without going through hoops as it is with threading.
So how do you change your mindset from that of conventional programming?
Well, first of all, in some situations you won’t have to.
Some operations you will do in Unity will still have a streamlined life cycle with some operations finishing their job and then calling the next operations in a predictable fashion and it is an acquirable skill to know when a more traditional methodology is called for.
In most cases, however, you need to think of every object in your game as autonomous and minimize dependencies as much as you can.
It doesn’t matter which scripts will run before and after, as long as they all do what they are supposed to.
If you are not satisfied with that answer, wait for my next post where I’ll be covering tips and tricks on integrating dependencies between different objects and scripts.