There are a lot of different tools out there for making games. Some are just libraries like Irrlicht, OGRE, or JMonkey. Others are full on toolkits/IDEs like UDK, Torque, Shiva, or Unity. All of these generally have the same painful entry fee for a new user: you need to learn them before you can decide whether you’ll like them. What’s the workflow? What do scripts look like? Trying out these things one at a time is tiresome and takes a while. Demo projects help but don’t really convey what working on my own game will be like.

I’ve decided I’m pretty fond of Unity. I recently tried to distill what it’s like to make a game in Unity for some friends, and I’m now subjecting you to the same thing. We’ll survive this.

First, the things about Unity that kind of suck:

These could be deal breakers for some people, so I’m going to get them out of the way immediately.

Pretty water/dynamic shadows are only available in the paid version.

There are binary files in Unity projects unless you get the Pro version, where “force text” is an option. This makes version control and sharing of projects more difficult than it needs to be. There are ways to get this to work with Git/Mercurial, though, and there is also a (far too expensive) paid version control solution called Unity Asset Server. I work by myself, so I just check in all of my files willy nilly. It’s freeing.

But!

PC/Mac versions of the editor are freely available

PC/Mac/browser games can be exported (and sold!) for free (license).

Physics/networking built in

Purty graphics (even without dynamic shadows) that use DirectX on Windows and OpenGL on Macs

A graphical UI for setting up your game objects

Nice integration with Blender and other 3D modeling/animation apps.

An example:

Unity includes some really nice examples, but they’re a bit complicated for gaining a basic understanding of what’s going on and how things are organized in an average unity project. This project will help beginning users visualize and evaluate the basic workflow in Unity without actually learning it all as entailed here. Unity’s official documentation is very helpful, though, and I’ll be linking it wherever relevant.

You can download my simple BoxShooter5000 example here. If you’ve already got Unity downloaded, you can simply decompress the zip and open Assets/test.unity.

Well, that’s nice. Stuff. You can hit the play button in the center of the main toolbar now. WASD moves your hero (a wonderfully modeled blue box). You can aim and shoot boxes at other boxes with the mouse. Right clicking shoots a different box that explodes on impact. Groundbreaking stuff.

Let’s check out how that Player works.

Our player, like any object in the Unity’s hierarchy view, is a GameObject. You can create these via the GameObject menu. There are options for creating lights and such, but it’s important to remember that a GameObject is really just a container.

You can drag other GameObjects into a GameObject (seen: Cube, Launchers, Main Camera). These will follow the parent GameObject around, which is how the camera follows the player in this demo, and how lights/particles would follow a projectile, for example.

You can also drag components like Unity’s built in Character Controller or my own Player Controller script, as seen in the right “Inspector” view. Unity has the pretty sweet feature of taking any public variables in a script and making them settable in the UI. "Gravity", “Movement Speed”, etc., those are all members of PlayerController.js, and you can set them to different values in any GameObject that uses them. You can populate some of these public property variables with text/number entry, but more complex types can be set via drag/drop.

Scripting:

For reference, the source code of the PlayerController:

//This call generates an error if said script isn’t also attached

//to your GameObject. Conveniently, this will also automatically add the

//CharacterController component to any objects you drag this script to.

//In Unity’s javascript, includes aren’t necessary. This is just a convenience.

@script RequireComponent( CharacterController ) public var gravity : float = 5.0f;

//gravity’s 5.0f is only the default value

//and can be overridden in the editor.



public var movementSpeed : float = 5.0f; public var rotationSpeed : float = 1.0f; public var launcherObject1 : GameObject; public var launcherObject2 : GameObject; private var charController : CharacterController; private var launcher1 : Launcher; private var launcher2 : Launcher;

//Start() gets called at object initialization.

function Start() { charController = GetComponent( CharacterController ); launcher1 = launcherObject1.GetComponent( Launcher ); launcher2 = launcherObject2.GetComponent( Launcher ); }

//Update() gets called every frame (call FixedUpdate for

//things that need to be framerate-independent, like physics)

function Update() { HandleWepInput(); HandleMoveInput(); } function HandleMoveInput() {

//These input names and the corresponding keys are

//defined in Edit > Preferences > Input and

//can easily be changed by you or the player.



var theHInput : float = Input.GetAxisRaw( "Horizontal" ); var theVInput : float = Input.GetAxisRaw( "Vertical" ); var theMovementDirection : Vector3 = transform.TransformDirection( Vector3( theHInput, 0, theVInput ) ); theMovementDirection = theMovementDirection.normalized; var theMovementOffset : Vector3 = theMovementDirection * movementSpeed; theMovementOffset.y = -gravity;

// We always want the movement to be framerate independent.

// Multiplying by Time.deltaTime does this.

theMovementOffset *= Time.deltaTime; charController.Move( theMovementOffset ); var theMouseXDelta : float = Input.GetAxis( "Mouse X" ); transform.Rotate( 0, theMouseXDelta * rotationSpeed, 0 ); } function HandleWepInput() {

//These input names and the corresponding keys are

//also defined in Edit > Preferences > Input.

var theFire1KeyDown = Input.GetButtonDown( "Fire1" ); var theFire2KeyDown = Input.GetButtonDown( "Fire2" ); if( theFire1KeyDown ) { launcher1.FireInDir( transform.TransformDirection( Vector3.forward ) ); } if( theFire2KeyDown ) { launcher2.FireInDir( transform.TransformDirection( Vector3.forward ) ); } }

Some additional notes:

You can easily get at any GameObject’s transform simply by calling “transform.”, and get things like position, rotation, and scale. A lot of rotation/vector math can done for you by Transform, so be careful to avoid doing more work than you need to. For example, I use it in HandleMovementInput() to rotate the input WASD movement to be relative to the player’s current rotation (i.e., strafing) with the transform.TransformDirection() call.

I could obviously get really carried away here, but I’ll try to just cover the bare minimum and move on. You can, of course, check the actual examples for more scripts. The ExplodeOnImpact.js script may be of interest, for example, for how it uses OnCollisionEnter() to receive collision events from the projectile’s attached collider.

Scripting languages:

Scripts in Unity can be written in JavaScript, C#, or Boo syntax. I’m not going to pretend to know anything about Boo. Neither Unity JavaScript or C# is exactly the same as normal JS/C#, but the syntax is familiar enough to get by. Notably, you can, and probably should, specify the type of your vars in Unity JavaScript. Unity’s C# syntax is the same as standard, but its functionality isn’t.

There are lots of differences between JS and C# in Unity. C# builds about 4x faster, but most people’s projects build quickly, regardless. The Unity forums are full of debates about which language is best, but I’d say the biggest difference is that there doesn’t seem to be a functional way to define and inherit from an interface in JS, i.e. there’s no “implements” call. From a traditional programming standpoint, this would generally make JavaScript a lot less useful. In Unity, it doesn’t matter as much.

Modularity vs. polymorphism:

This is an important mental roadblock to surpass to get the most out of Unity’s workflow: You don’t need one script to implement n different interfaces. You can just add several different scripts/components to the same GameObject instead. Have a character that needs to handle health updates as well as be able to equip weapons? Give him a HealthHandler and an EquipmentManager.

Additionally, any object can simply call SendMessage( “MessageName”, Parameter ) to call the function MessageName( Parameter ) in all other scripts attached to the same object. This is good for those cases where you simply must call on a standard interface. Losing health and dying would be common places where this would be useful, for example.

Of course, inheritance is still a very convenient and important abstraction to have available, and you can do this in javascript by explicitly declaring your class in this manner: class SuperSweetSword extends Weapon

I can feel this getting wordy, so I’ll call it done. Hopefully I’ve given you some idea of the workflow and convenience available for game development, especially free-time game development, with Unity. For me, it’s been great to spend my time making games instead of futzing around with whatever new library I’d gotten into for a given month. I hope some of you can experience the same.

Want to learn more about Unity? Move on to the next step with my article on using prefabs and game art in Unity.