August 2014

Volume 29 Number 8

Unity : Developing Your Offset Game with Unity and C#

Adam Tuliper

Equally a software architect, I've written many systems, contrary-­engineered native code malware, and by and large could effigy things out on the code side. When information technology came to making games, though, I was a bit lost every bit to where to start. I had done some native lawmaking graphics programming in the early Windows days, and it wasn't a fun experience. I and so started on DirectX development simply realized that, although it was extremely powerful, it seemed like too much code for what I wanted to do.

And then, one day, I decided to experiment with Unity, and I saw it could exercise some astonishing things. This is the first article in a four-part series that will cover the nuts and compages of Unity. I'll prove how to create 2D and 3D games and, finally, how to build for the Windows platforms.

What Unity Is

Unity is a 2D/3D engine and framework that gives yous a system for designing game or app scenes for 2d, 2.5D and 3D. I say games and apps because I've seen not just games, but preparation simulators, first-responder applications, and other business-focused applications developed with Unity that demand to interact with 2nd/3D space. Unity allows you to interact with them via non merely code, but also visual components, and consign them to every major mobile platform and a whole lot more—for free. (There's likewise a pro version that's very nice, but it isn't free. You can do an impressive amount with the free version.) Unity supports all major 3D applications and many audio formats, and even understands the Photoshop .psd format and so y'all can just drop a .psd file into a Unity projection. Unity allows you lot to import and assemble assets, write code to collaborate with your objects, create or import animations for employ with an avant-garde blitheness system, and much more.

As Effigy 1 indicates, Unity has washed piece of work to ensure cantankerous-platform support, and you can change platforms literally with ane click, although to be fair, there's typically some minimal try required, such as integrating with each shop for in-app purchases.

Platforms Supported by Unity
Figure 1 Platforms Supported past Unity

Perhaps the virtually powerful part of Unity is the Unity Asset Store, arguably the best asset market place in the gaming market place. In it you can observe all of your game component needs, such equally artwork, 3D models, animation files for your 3D models (see Mixamo's content in the store for more than 10,000 motions), audio effects and full tracks, plug-ins—including those like the MultiPlatform toolkit that can assist with multiple platform support—visual scripting systems such as PlayMaker and Acquit, advanced shaders, textures, particle effects, and more. The Unity interface is fully scriptable, allowing many third-political party plug-ins to integrate correct into the Unity GUI. About, if not all, professional game developers use a number of packages from the asset store, and if you accept something decent to offer, y'all tin can publish it there as well.

What Unity Isn't

I hesitate to describe anything Unity isn't as people challenge that all the time. Yet, Unity by default isn't a organization in which to pattern your 2D assets and 3D models (except for terrains). You tin can bring a bunch of zombies into a scene and control them, but yous wouldn't create zombies in the Unity default tooling. In that sense, Unity isn't an asset-creation tool similar Autodesk Maya or 3DSMax, Blender or even Adobe Photoshop. There's at least ane third-party modeling plug-in (ProBuilder), though, that allows you to model 3D components right inside of Unity; there are second world builder plug-ins such as the 2D Terrain Editor for creating 2nd tiled environments, and you can also design terrains from within Unity using their Terrain Tools to create astonishing landscapes with trees, grass, mountains, and more. And so, once again, I hesitate to suggest any limits on what Unity can exercise.

Where does Microsoft fit into this? Microsoft and Unity work closely together to ensure great platform support across the Microsoft stack. Unity supports Windows standalone executables, Windows Phone, Windows Shop applications, Xbox 360 and Xbox One.

Getting Started

Download the latest version of Unity and get yourself a two-button mouse with a clickable scroll wheel. There'due south a single download that can be licensed for gratis mode or pro. You can meet the differences between the versions at unity3d.com/unity/licenses. The Editor, which is the main Unity interface, runs on Windows (including Surface Pro), Linux and OS X.

I'll get into real game evolution with Unity in the next article, just, first, I'll explore the Unity interface, project structure and compages.

Compages and Compilation

Unity is a native C++-based game engine. You write lawmaking in C#, JavaScript (UnityScript) or, less frequently, Boo. Your code, not the Unity engine code, runs on Mono or the Microsoft .NET Framework, which is Just-in-Time (JIT) compiled (except for iOS, which doesn't let JIT code and is compiled past Mono to native code using Alee-of-Time [AOT] compilation).

Unity lets you test your game in the IDE without having to perform whatever kind of export or build. When you lot run lawmaking in Unity, you're using Mono version 3.5, which has API compatibility roughly on par with that of the .NET Framework 3.5/CLR 2.0.

You edit your code in Unity by double-clicking on a code file in the project view, which opens the default cantankerous-platform editor, Mono­Develop. If you prefer, you can configure Visual Studio every bit your editor.

Yous debug with MonoDevelop or use a third-party plug-in for Visual Studio, UnityVS. Y'all can't use Visual Studio equally a debugger without UnityVS because when y'all debug your game, you aren't debugging Unity.exe, y'all're debugging a virtual environment inside of Unity, using a soft debugger that's issued commands and performs actions.

To debug, y'all launch MonoDevelop from Unity. MonoDevelop has a plug-in that opens a connection back to the Unity debugger and bug commands to it after you Debug | Adhere to Procedure in MonoDevelop. With UnityVS, you connect the Visual Studio debugger back to Unity instead.

When you open Unity for the get-go time, you lot see the projection dialog shown in Figure 2.

The Unity Project Wizard
Figure 2 The Unity Project Wizard

In the project dialog, you specify the name and location for your project (1). You tin import any packages into your project (2), though you lot don't accept to check anything off here; the list is provided only as a convenience. You can too import a parcel later. A package is a .unitypackage file that contains prepackaged resource—models, code, scenes, plug-ins—anything in Unity you can parcel upwards—and you tin reuse or distribute them easily. Don't check something off hither if you don't know what it is, though; your projection size will grow, sometimes considerably. Finally, you can cull either 2nd or 3D (iii). This dropdown is relatively new to Unity, which didn't take pregnant 2nd game tooling until fairly recently. When set to 3D, the defaults favor a 3D project—typical Unity beliefs every bit it'southward been for ages, then it doesn't need any special mention. When second is chosen, Unity changes a few seemingly modest—but major—things, which I'll cover in the 2D commodity later on in this series.

This list is populated from .unitypackage files in certain locations on your organisation; Unity provides a handful on install. Anything you download from the Unity nugget store also comes as a .unitypackage file and is cached locally on your organization in C:\Users\<you lot>\AppData\­Roaming\Unity\Nugget Shop. As such, it will show up in this listing once it exists on your organization. You could just double-click on any .unitypackage file and it would be imported into your project.

Continuing with the Unity interface, I'll go forward from clicking Create in the dialog in Figure 2 and so a new project is created. The default Unity window layout is shown in Figure 3.

The Default Unity Window
Figure 3 The Default Unity Window

Here'southward what you'll see:

  1. Projection: All the files in your project. You tin elevate and drop from Explorer into Unity to add files to your project.
  2. Scene: The currently open up scene.
  3. Bureaucracy: All the game objects in the scene. Annotation the use of the term GameObjects and the GameObjects dropdown bill of fare.
  4. Inspector: The components (properties) of the selected object in the scene.
  5. Toolbar: To the far left are Pan, Move, Rotate, Scale and in the middle Play, Suspension, Accelerate Frame. Clicking Play plays the game about instantly without having to perform split builds. Pause pauses the game, and accelerate frame runs information technology one frame at a time, giving you lot very tight debugging control.
  6. Console: This window tin can become somewhat hidden, but it shows output from your compile, errors, warnings and then forth. It also shows debug letters from code; for example, Debug.Log will show its output here.

Of important mention is the Game tab next to the Scene tab. This tab activates when you click play and your game starts to run in this window. This is chosen play mode and it gives yous a playground for testing your game, and even allows you lot to make live changes to the game by switching back to the Scene tab. Exist very careful hither, though. While the play button is highlighted, you're in play mode and when you leave it, whatever changes you made while in play mode will be lost. I, along with just about every Unity developer I've ever spoken with, accept lost work this style, and so I alter my Editor's colour to brand information technology obvious when I'm in play style via Edit | Preferences | Colors | Playmode tint.

About Scenes

Everything that runs in your game exists in a scene. When you lot packet your game for a platform, the resulting game is a collection of one or more scenes, plus any platform-­dependent code yous add. You lot can have as many scenes equally you want in a project. A scene can exist thought of as a level in a game, though yous can have multiple levels in one scene file by just moving the player/camera to dissimilar points in the scene. When you lot download third-party packages or even sample games from the nugget store, y'all typically must look for the scene files in your project to open. A scene file is a unmarried file that contains all sorts of metadata about the resources used in the project for the current scene and its properties. It's important to save a scene often by pressing Ctrl+Due south during development, just every bit with any other tool.

Typically, Unity opens the concluding scene you lot've been working on, although sometimes when Unity opens a project it creates a new empty scene and y'all take to get discover the scene in your project explorer. This can be pretty confusing for new users, but it'due south important to remember if yous happen to open up up your last project and wonder where all your work went! Relax, you'll discover the work in a scene file y'all saved in your projection. You can search for all the scenes in your project by clicking the icon indicated in Figure 4 and filtering on Scene.

Filtering Scenes in the Project
Figure four Filtering Scenes in the Project

In a scene, you tin can't meet anything without a photographic camera and you can't hear annihilation without an Audio Listener component attached to some GameObject. Notice, however, that in any new scene, Unity always creates a camera that has an Audio Listener component already on it.

Project Structure and Importing Assets

Unity projects aren't like Visual Studio projects. Yous don't open a project file or fifty-fifty a solution file, because it doesn't exist. You bespeak Unity to a binder construction and it opens the folder equally a project. Projects contain Assets, Library, ProjectSettings, and Temp folders, but the only ane that shows up in the interface is the Assets folder, which you lot can run across in Figure 4.

The Avails binder contains all your avails—fine art, code, audio; every single file you bring into your project goes here. This is always the peak-level folder in the Unity Editor. Only make changes but in the Unity interface, never through the file arrangement.

The Library binder is the local cache for imported avails; it holds all metadata for avails. The ProjectSettings folder stores settings you configure from Edit | Project Settings. The Temp folder is used for temporary files from Mono and Unity during the build process.

I want to stress the importance of making changes only through the Unity interface and not the file system directly. This includes even elementary re-create and paste. Unity tracks metadata for your objects through the editor, so use the editor to brand changes (outside of a few fringe cases). Yous can drag and drop from your file system into Unity, though; that works just fine.

The Earth-shaking GameObject

Near everything in your scene is a GameObject. Remember of System.Object in the .NET Framework. Almost all types derive from information technology. The same concept goes for GameObject. It's the base class for all objects in your Unity scene. All of the objects shown in Effigy 5 (and many more) derive from a GameObject.

GameObjects in Unity
Effigy 5 GameObjects in Unity

A GameObject is pretty simple equally information technology pertains to the Inspector window. Yous tin can see in Figure 6 that an empty GameObject was added to the scene; annotation its properties in the Inspector. GameObjects by default have no visual backdrop except the widget Unity shows when yous highlight the object. At this point, it'south simply a fairly empty object.

A Simple GameObject
Figure vi A Simple GameObject

A GameObject has a Name, a Tag (similar to a text tag you'd assign via a FrameworkElement.Tag in XAML or a tag in Windows Forms), a Layer and the Transform (probably the most important property of all).

The Transform property is just the position, rotation and scale of any GameObject. Unity uses the left-hand coordinate organisation, in which you recall of the coordinates of your computer screen as X (horizontal), Y (vertical) and Z (depth, that is, coming in or going out of the screen).

In game development, it'south quite common to use vectors, which I'll cover a bit more in future articles. For now, it's sufficient to know that Transform.Position and Transform.Scale are both Vector3 objects. A Vector3 is simply a three-dimensional vector; in other words, information technology's zero more three points—only 10, Y and Z. Through these three simple values, you tin can gear up an object's location and fifty-fifty move an object in the direction of a vector.

Components

You add functionality to GameObjects by calculation Components. Everything yous add is a Component and they all show up in the Inspector window. In that location are MeshRender and SpriteRender Components; Components for audio and camera functionality; physics-related Components (colliders and rigidbodies), particle systems, path-finding systems, third-party custom Components, and more than. You utilize a script Component to assign code to an object. Components are what bring your GameObjects to life by adding functionality, akin to thedecorator pattern in software development, but much cooler.

I'll assign some code to a new GameObject, in this case a simple cube you lot can create via GameObject | Create Other | Cube. I renamed the cube Enemy and then created another to have two cubes. You can see in Figure 7 I moved one cube almost -15 units away from the other, which yous can do by using the motion tool on the toolbar or the Due west key in one case an object is highlighted.

Current Project with Two Cubes
Figure 7 Electric current Project with Two Cubes

The code is a simple class that finds a player and moves its owner toward it. You typically practise movement operations via 1 of ii approaches: Either you lot move an object to a new position every frame past changing its Transform.Position properties, or you apply a physics force to it and let Unity have intendance of the balance.

Doing things per frame involves a slightly different way of thinking than saying "move to this point." For this example, I'm going to movement the object a little bit every frame so I have exact control over where information technology moves. If you lot'd rather not adjust every frame, in that location are libraries to exercise single function call movements, such as the freely available iTween library.

The offset thing I exercise is correct-click in the Project window to create a new C# script called EnemyAI. To assign this script to an object, I just drag the script file from the project view to the object in the Scene view or the Hierarchy and the code is assigned to the object. Unity takes care of the residue. It'due south that easy.

Figure 8 shows the Enemy cube with the script assigned to it.

The Enemy with a Script Assigned to It
Figure eight The Enemy with a Script Assigned to It

Take a expect at the code in Figure 9 and note the public variable. If you look in the Editor, y'all tin encounter that my public variable appears with an option to override the default values at run fourth dimension. This is pretty absurd. You can alter defaults in the GUI for primitive types, and you can besides expose public variables (not properties, though) of many different object types. If I elevate and drib this lawmaking onto another GameObject, a completely separate case of that code component gets instantiated. This is a basic example and it can be made more efficient by, say, adding a RigidBody component to this object, merely I'll go on it uncomplicated here.

Figure nine The EnemyAI Script

              public class EnemyAI : MonoBehavior {   // These values will appear in the editor, total properties will not.   public bladder Speed = fifty;   individual Transform _playerTransform;   private Transform _ myTransform;   // Called on startup of the GameObject it's assigned to.   void Start()   {     // Find some gameobject that has the text tag "Player" assigned to information technology.     // This is startup code, shouldn't query the player object every     // frame. Store a ref to information technology.     var role player = GameObject.FindGameObjectWithTag("Histrion");     if (!role player)     {       Debug.LogError(         "Could not find the main actor. Ensure it has the player tag set.");     }     else     {       // Catch a reference to its transform for apply later (saves on managed       // code to native code calls).       _playerTransform = player.transform;     }     // Grab a reference to our transform for utilise later on.     _myTransform = this.transform;   }   // Called every frame. The frame rate varies every second.   void Update()   {     // I am setting how fast I should motion toward the "player"     // per second. In Unity, 1 unit is a meter.     // Time.deltaTime gives the corporeality of time since the last frame.     // If you lot're running sixty FPS (frames per second) this is i/60 = 0.0167,     // so due west/Speed=2 and frame rate of 60 FPS (frame charge per unit always varies      // per second), I have a movement corporeality of 2*0.0167 = .033 units     // per frame. This is two units.     var moveAmount = Speed * Time.deltaTime;     // Update the position, move toward the player's position by moveAmount.     _myTransform.position = Vector3.MoveTowards(_myTransform.position,       _playerTransform.position, moveAmount);   } }                          

In code, I tin can get a reference to any component exposed in the editor. I can as well assign scripts to a GameObject, each with its ain Beginning and Update methods (and many other methods). Assuming a script component containing this code needs a reference to the EnemyAI class (component), I can simply ask for that component:

              public class EnemyHealth : MonoBehavior private EnemyAI _enemyAI; // Use this for initialization. void Start () {   // Go a ref to the EnemyAI script component on this game object.   var enemyAI = this.GetComponent<EnemyAI>(); } // Update is called once per frame. void Update () {   _enemyAI.MoveTowardsPlayer(); }                          

After you lot edit lawmaking in MonoDevelop or your lawmaking editor of selection and then switch back to Unity, you'll typically notice a short delay. This is considering Unity is groundwork compiling your lawmaking. You can change your code editor (non debugger) via Edit | Preferences | External Tools | External Script Editor. Any compilation issues will bear witness up at the very lesser condition bar of your Unity Editor screen, then keep an heart out for them. If you endeavor to run your game with errors in the code, Unity won't let you lot proceed.

Writing Code

In the prior lawmaking example, there are ii methods, Starting time and Update, and the class EnemyHealth inherits from the MonoBehavior base of operations grade, which lets y'all simply assign that class to a GameObject. At that place'southward a lot of functionality in that base class you'll apply, and typically a few methods and properties. The master methods are those Unity will call if they be in your course. There are a handful of methods that can become called (see bit.ly/1jeA3UM). Though there are many methods, only equally with the ASP.NET Spider web Forms Folio Lifecycle, you typically apply only a few. Here are the most common code methods to implement in your classes, which relate to the sequence of events for MonoBehavior-derived classes:

Awake: This method is called once per object when the object is first initialized. Other components may not all the same be initialized, so this method is typically used to initialize the current GameObject. Y'all should always use this method to initialize a MonoBehavior-derived class, non a constructor. And don't try to query for other objects in your scene here, every bit they may not exist initialized yet.

Start: This method is chosen during the first frame of the object's lifetime just before any Update methods. It may seem very like to Awake, merely with Start, you know the other objects have been initialized via Awake and exist in your scene and, therefore, you can query other objects in code easily, like and so:

              // Returns the first EnemyAI script component instance it finds on any game object. // This type is EnemyAI (a component), non a GameObject. var enemyAI = GameObject.FindObjectOfType<EnemyAI>(); // I'll actually get a ref to its pinnacle-level GameObject. var enemyGameObject = enemyAI.gameObject; // Want the enemy's position? var position = enemyGameObject.transform.position;                          

Update: This method is chosen every frame. How frequently is that, you ask? Well, it varies. It's completely ciphering-dependent. Because your system is ever changing its load every bit it renders different things, this frame rate varies every second. You lot can press the Stats push in the Game tab when yous go into play mode to encounter your current frame rate, equally shown in Figure 10.

Getting Stats
Figure x Getting Stats

FixedUpdate: This method is called a stock-still number of times a second, independent of the frame rate. Considering Update is called a varying number of times a second and isn't in sync with the physics engine, information technology's typically best to utilize FixedUpdate when you lot want to provide a force or another physics-related functions on an object. FixedUpdate past default is called every .02 seconds, meaning Unity also performs physics calculations every .02 seconds (this interval is called the Fixed Timestep and is developer-adaptable), which, again, is independent of frame charge per unit.

Unity-Generated Code Projects

Once y'all have lawmaking in your project, Unity creates 1 or more than project files in your root folder (which isn't visible in the Unity interface). These are not the Unity engine binaries, simply instead the projects for Visual Studio or MonoDevelop in which you lot'll edit and compile your code. Unity tin create what might seem similar a lot of dissever projects, as Figure 11 shows, although each one has a an of import purpose.

Unity-Created Projects
Effigy xi Unity-Created Projects

If you take a uncomplicated Unity project, you won't meet all of these files. They get created only when y'all have code put into various special folders. The projects shown in Figure 11 are broken out by merely three types:

  • Assembly-CSharp.csproj
  • Associates-CSharp-Editor.csproj
  • Assembly-CSharp-firstpass.csproj

For each of those projects, there'south a dupli­cate project created with -vs appended to it, Associates-CSharp-vs.csproj, for example. These projects are used if Visual Studio is your code editor and they tin be added to your exported project from Unity for platform-specific debugging in your Visual Studio solution.

The other projects serve the same purpose but have CSharp replaced with UnityScript. These are simply the JavaScript (UnityScript) versions of the projects, which will exist only if you use JavaScript in your Unity game and only if you have your scripts in the folders that trigger these projects to be created.

Now that you've seen what projects get created, I'll explore the folders that trigger these projects and bear witness you what their purposes are. Every folder path assumes it's underneath the /Avails root folder in your projection view. Assets is always the root folder and contains all of your nugget files underneath it. For example, Standard Assets is actually /Assets/Standard Assets. The build process for your scripts runs through four phases to generate assemblies. Objects compiled in Phase 1 can't see those in Stage 2 because they haven't yet been compiled. This is important to know when you're mixing UnityScript and C# in the aforementioned projection. If you lot want to reference a C# class from UnityScript, you lot need to make sure it compiles in an earlier phase.

Stage 1 consists of runtime scripts in the Standard Avails, Pro Standard Assets and Plug-ins folders, all located under/Avails. This stage creates the Assembly-CSharp-firstpass.csproj projection.

Phase two scripts are in the Standard Assets/Editor, Pro Standard Assets/Editor and Plug-ins/Editor folders. The terminal folder is meant for scripts that interact with the Unity Editor API for blueprint-time functionality (think of a Visual Studio plug-in and how it enhances the GUI, only this runs in the Unity Editor). This stage creates the Associates-CSharp-Editor-firstpass.csproj project.

Phase 3 comprises all other scripts that aren't inside an Editor folder. This phase creates the Assembly-CSharp-Editor.csproj project.

Phase 4 consists of all remaining scripts (those inside any other folder called Editor, such as /Assets/Editor or /Assets/­Foo/Editor). This phase creates the Associates-CSharp.csproj project.

In that location are a couple other less-used folders that aren't covered here, such as Resources. And there is the pending question of what the compiler is using. Is it .Net? Is it Mono? Is information technology .NET for the Windows Runtime (WinRT)? Is it .Net for Windows Phone Runtime? Figure 12 lists the defaults used for compilation. This is important to know, especially for WinRT-based applications because the APIs available per platform vary.

Figure 12 Compilation Variations

Platform Game Assemblies Generated By Final Compilation Performed By
Windows Phone 8 Mono Visual Studio/.Net
Windows Store .NET Visual Studio/.NET (WinRT)
Windows Standalone (.exe) Mono Unity - generates .exe + libs
Windows Phone 8.1 .Net Visual Studio/.Internet (WinRT)

When you perform a build for Windows, Unity is responsible for making the calls to generate the game libraries from your C#/UnityScript/Boo code (DLLs) and to include its native runtime libraries. For Windows Shop and Windows Phone eight, it will export a Visual Studio solution, except for Windows standalone, in which Unity generates the .exe and required .dll files. I'll discuss the various build types in the final article in the series, when I cover building for the platform. The graphics rendering at a low level is performed on the Windows platforms by DirectX.

Designing a game in Unity is a fairly straightforward process:

  • Bring in your assets (artwork, audio and so on). Use the asset store. Write your ain. Rent an creative person. Notation that Unity does have native support for Maya, Cheetah3d, Blender and 3dsMax, in some cases requiring that software be installed to work with those native 3D formats, and information technology works with .obj and .fbx common file formats, equally well.
  • Write code in C#, JavaScript/UnityScript, or Boo, to command your objects, scenes, and implement game logic.
  • Test in Unity. Export to a platform.
  • Test on that platform. Deploy.

But Look, I Want More!

This commodity serves as an overview of the compages and procedure in Unity. I covered the interface, basics of assigning code, GameObjects, components, Mono and .NET, plus more. This sets us up nicely for the next article where I'll dive correct into assembling game components for a 2nd game. Keep an heart on Microsoft Virtual University, as I'll be doing a two-day Unity learning event belatedly summer. And scout for local regional learning events at unity3d.com/pages/windows/events.


Adam Tuliperis a senior technical evangelist with Microsoft living in sunny Southern California. He's an indie game dev, co-admin of the Orange County Unity Meetup, and a pluralsight.com author. He and his wife are near to have their 3rd kid, so achieve out to him while he still has a spare moment at adamt@microsoft.com or on Twitter at twitter.com/AdamTuliper.

Thanks to the post-obit technical experts for reviewing this commodity: Matt Newman (Subscience Studios), Jaime Rodriguez (Microsoft) and Tautvydas Žilys (Unity)