Unity: Starting your First Project (Part 2)

Posted: November 22, 2011 in Uncategorized

This is part two of a four part series detailing starting your own game. I will talk about actually creating the game, and how to think about coding  your game features. This tutorial is geared mostly towards Unity, but the concepts can be applied to any game engine! The first part of this article well focus on concepts behind the creation of your game, specifically on game mechanics. The second part will get in the nuts and bolts of coding. The fourth part of this series will have some code examples of common basic game functions.

Creating the game

When creating your game, regardless of the genre, the first thing you have to think about are your game features. How will your game function, and what mechanics will the player interact with? For my game, the core mechanics rest of simulations and AI. Basically, the player provides the stimulus, and the game reacts to it. In many other genres, the game provides the stimulus that the player reacts to, like shooting at an enemy, and bouncing a ball. However, these mechanics are often built upon many simple mechanics. These “micro” mechanics are what make up the different mechanics of a game, and these are where you should start.

Deciding on Core features:

The first thing a developer should do when creating their game is make a list of core features that they want in their game. For example, in a platformer, one may want to focus on movement and jumping. Someone creating a building game (whether a classic RTS, or city sim, or combination) may want to focus on spawning buildings (at a mouse click, or at a certain position) first. These would be the micro mechanics that make up that larger more general game mechanics. Once you create this core functionality, you can add to it without worrying about disturbing the underlying functionality. They key to doing this is making sure that you thoroughly test the core features, and make sure they are done well! Unity’s unique development environment makes incremental development like this a breeze, and you don’t have to go through the hassle of compiling and recompiling your assets over and over again.

Modular Development

Because of the unique environment Unity offers detailed above, developing different aspects of your game as if they were different modules and an easy and effective way to get your game done! Different scripts that create different functionality can be kept separate, and turned off at will. This also makes debugging very easy. Separate game mechanics can be their own GameObjects, composed of various scripts, sounds, and other things that make make up the micro mechanics. Unity’s use of Object Oriented programming also adds support to modular development, as well as the availability of prefabs. I will discuss prefabs in more detail later..

Importing Assets

One thing I haven’t touched upon yet are the visual assets of your game. Importing these, as I said earlier, is extremely easy, but I thought i’d give an overview of your process.

Whether you are importing textures, models, music, or entire prefabs to your Unity project, you simply follow these steps:

  1. Make sure your Unity Project is created, and navigate to “Assets” folder in your projects root directory
  2. Either Copy and Paste your assets to the correct folder inside the Assets directory, or save the image/model/sound/etc. directly to correct folder inside the Assets directory
  3. Open Unity and your asset should be imported!

Thats it! Simple as pie

Writing the Code

The first decision to make when you start to write code is what language to choose. While I haven’t used to Unity flavor of C# much, I find this topic worth talking about. Javascript in Unity has whats known as type hinting, which is a solution for when you want to take advantage of typing, without having to use typing at all times. Unlike C#, which is a statically typed language. This makes getting into Javascript much easier, and with all the libraries supplied by Unity, Javascript is just as robust as C#. However, at times I wish that I had chose C# instead of Unity. the dynamic typing sometimes run into strange problems. Many of these problems can be fixed with clever use of type hinting, but these solutions aren’t readily apparent. C# bypasses these problems by virture of being statically typed. C# also has various programming language features that Javascript doesn’t (like operator overloading, explicitly passing by reference, etc.). I am also starting to run into typing problems with my user defined classes. While I have been able to overcome these problems, at times I envy a statically typed environment. Whether you would like to take advantage of arguably quicker and easier development times versus more stability in terms of typing and other aspects of the language, sticking to one language certainly makes development easier. You can write in 2 (or more) different languages (Unity also has Boo, which I won’t get into) but it slightly complicates the development process.

Getting Different Scripts to Talk

One of the early hurdles that any game developer using Unity will run into will be getting different scripts to communicate with each other. Certain information (like a users life, held inside the script that controls the user’s different stats and attributes) will be needed by certain other scripts (like the combat script, or AI script). Luckily, Unity makes it easy for different scripts to talk!

GameObjects: To understand how Unity has each individual object communicate, it helps to understand how things work internally. Everything in a game is a GameObject. These GameObjects can be empty, or composed of what Unity calls components. Components can be scripts, mesh colliders, and other various generic objects that have a variety of functions. GameObjects can also be composed of other GameObjects (which would become children of the base GameObject). GameObjects, in code, are a class, and thus have certain methods and attributes. Of interest to us will be a method called GetComponent, which returns an object that represents the component of a specific game object. This component could be a sound (or AudioSource), or a script, or any other component. What we’ll be mostly doing is grabbing other script components.

Now, there are several ways in which we can get another script that depends on where exactly this script resides (or rather, what GameObject is this script a part of). There are two cases here.

The first is if we have two scripts wanting to communicate in the same game object. To communicate, we simply call the GetComponent method, and use the scripts name (case sensitive) as an argument. Consider the following:

Script1


var Points = 0;
var health = 100;

function Update(){
 //called every cycle
 //do walking and other character related stuff.
}

This could be a script that holds all the actions and information a player object has. Another script, Script2, could be in charge of some other unrelated function, like gathering and computing stats to be displayed


...
function Update() {
 ... gather other metrics ...
 //we want to display the points
 //first we grab the component script, titled Script1
 //the colon lets us use type hinting, to tell javascript what type is going into this variable
 scriptObject : Script1 = GetComponent(Script1);
 points = scriptObject.Points;//we can access the scripts variables just like any other objects attributes

 Display(points);//Display() is some helper function, perhaps communicating with some GUI script
 ... rest of logic ...

}
...

You can infer from above that if you call the GetComponent method without an object reference attached to it, GetComponent gets called on the GameObject that the script is a part of. If you want to get a script (or other component) that is part of a different GameObject, you need a variable to reference that GameObject.

Now there are several ways to get access to a GameObject, many of which are explained here: http://unity3d.com/support/documentation/ScriptReference/index.Accessing_Other_Game_Objects.html. I will go over the simplest method, using a reference that you can set up in the inspector view (part of Unity’s GUI).

The first thing you do, is add a variable to the script you want to do the communicating with. In the case above, If Script1 and Script2 were instead part of different GameObjects, I would add this variable in Script2, since its the one that queries Script1 for its data. This variable will be a reference to the GameObject that contains Script1. Lets say that this GameObject was called player (and we could call the GameObject with Script2 ScoreKeeper). Assuming these GameObjects already exist in your Object hierarchy (lower left side in most Unity setups), in Script2, we add a variable called, say, player, like so


var player : GameObject;

...
function Update() {
 ... gather other metrics ...

Now, we need to go object hierarchy, and select our GameObject called ScoreKeeper. We will then select Script2 in the inspector panel (there should be a slot for our newly added variable added), and go back to the hierarchy panel and drag the Player GameObject on to the player variable in the Script2 component. Once we do that the link is made! Now we can go back into Script2 and change it to the following


var player : GameObject;
function Update() {
 ... gather other metrics ...
 //we want to display the points
 //now we use the player GetComponenet method on the player GameObject, rather than the current scripts GameObject
 scriptObject : Script1 = player.GetComponent(Script1);
 points = scriptObject.Points;//we can access the scripts variables just like any other objects attributes

 Display(points);//Display() is some helper function, perhaps communicating with some GUI script
 ... rest of logic ...

}
...

Now regardless of what object we call GetComponent on, we can use the resulting object to call methods, just like we use it to get public attributes. So for example, we could do


function Update(){
 otherscript : OtherScript = GetComponent(OtherScript);
 var othervalue = OtherScript.OtherMethod();
 print(othervalue);
}

Separate Functionality: Because of the ability to communicate between scripts, separating out functionality, and making different interfaces (like methods and attributes) for two scripts to interact further aids the modular development I discussed above.

AI Basics: 

Writing AI can be a very difficult but rewarding experience. Depending on how complex your game is, you may need fairly complex AI, but many times you can, at least temporarily, get by with simple AI. For example, when developing the various AIs that control various city and building properties in order to see how they interact with each other in a timely manner, I started with very basic simulation. For example, originally, simulating happiness was only  based on the amount of water resource available. Now it is a function of many different city properties! AI is a vast and complicated subject of its own, so I won’t talk much more on it until a later article.

View the third part of this series here: http://wp.me/p1AGMt-5H

view the first part here: http://wp.me/p1AGMt-5E

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s