GCS Unity Beginner's Tutorial
This tutorial was written for the CMU Game Creation Society for students brand new to game development. The session is friendly to non-programmers and assumes the student has never opened Unity. The tutorial uses 2D assets but everything here is applicable to basic 3D development. Please download the sample assets here.
1. Versions of Unity
This tutorial was made in February 2015 using Unity 4.6.2, but has now been updated for Unity 5.4. The last update occurred in September 2016. Please download the free version here. There are some differences between Unity Pro and the free version. For most games of GCS scale this isn't a problem. Just remember: If you're aiming to make bank on your game, purchase Unity Pro. There's a blurb in the user agreement about how much you can make/be awarded before you should buy the pro version (100,000$). The Unity community is a colorful spectrum; you will find people who will shame you for seeking help. Ignore them. The forums can be incredibly helpful, so make sure to Google your questions when dealing with tough obstacles. And if you still can’t find what you want, or you're just rolling in the dough, you can always purchase scripting packages and assets from the Unity store.
2.The 2D Framework
Upon opening Unity, you'll see an option in the top right to start a new project. Select this. The next window will have a directory path for wherever you want to store your project. Rename your project (Unity defaults to 'New Unity Project X'.) If you know of a particular asset package you want imported, select the asset package button and check the appropriate box. None of these default options have to be included in your game! Make sure to change the highlighted framework option in the bottom left corner to 2D. Hit create project.
You should now see four main panels. On the far left is the Hierarchy. This is where all the pieces of your game that are currently in existence within the playspace (are instantiated, for the programmers) are listed. I say playspace because, say for example, if your enemy is destroyed during play, he will no longer be visible in this panel but he will still exist within the game's “playspace”. Below Hierarchy is the Project-Console bin. All game assets are stored under the Project Tab. Console is where the game sends you debug readouts and code errors. To the far right is the Inspector. Here you can make changes to the attributes of each instance in your game. The inspector is the edit menu in Photoshop. In the center is the game screen. The Scene view is where you make changes. Game view is what the player sees. What's important here is the Play and Pause buttons above the game screen. Play allows you to play the game. If you hit pause during this, you can pause the game and make changes dynamically. However, while the play button is pressed, these changes wont be saved! Click play again to exit this demo mode (the arrow will no longer be blue.) In the top left you should see a row of five buttons. Selecting these buttons tells Unity which way you want to maneuver in Scene view. For our purposes you'll be using the first three. The hand allows you to pan around the space, moving the 2D view of the scene, not the camera in the game. The directional arrows mode allows you to move objects around in space. And finally the cyclical arrows let you rotate objects in space. Go ahead and click on the directional arrows.
Most nouns in Unity are GameObjects. Every GameObject has some basic properties: a name, a position, and a tag. A tag is an organization technique used for identifying groups of objects. Tags can be things like “minion” or “enemy.” All GameObjects also reside in a layer. It's a good idea to keep track of your layers and organize the same types of objects on the same layer. I have had Unity pull objects to weird layers or instantiate objects in weird layers, causing unexpected behavior. If you're having a similar issue, check your layers and the order of objects within that layer.
You should see an “Untitled” object in the Hierarchy automatically. This is the current scene you are in. Scenes are chunks of games that can be put together. Once use of scenes could be to have an opening menu as one scene, and then your game as another. Scenes are useful for managing load times.
You should also see a “main camera” object in the Hierarchy automatically. This object is generated in Unity by default when creating a new project. Typically, 2D games only have one camera unless they're doing split screen magic. Multiple cameras come into play with 3D games.
To make a new object, go to the GameObject tab at the top left of the screen. Click and select create empty. Here we'll rename the GameObject to Player by changing the name in the inspector. Upon creation of the new GameObject, you should see a box with two arrows in the scene view.You can move the object around in the view by clicking and dragging the position values x and y in the inspector. If you change to the view with the arrows, then you can drag the object by the arrows. (Z is the depth axis and used in 3D games.) Make another object and name it Background. Make another object and call it Platform. Note that if you have an object selected in the Hierarchy and attempt to make a new object, you’ll create a child object nestled under the selected object. Make sure your Background and Platform objects are not children!
When making images for a background, keep in mind that Unity loves powers of two. Make your image's height a power of two. 2048 pixels is a good number. The camera's ratio is adjustable from there, so make your image's width greater than its height. Save the image as a PNG file. PNG format allows you to preserve transparency while still retaining a decent image quality. If your image has no transparency or is too large to PNG format, a JPG file will work fine for games of GCS scale.
To get your background image into Unity, drag it into the project bin. You can also go to the ASSETS > IMPORT NEW ASSET and find your image in the directory. Once imported, the asset will appear in the Project bin.
Note that if you move assets around in the directory after this, you'll have to reimport them.
Select the image in the Project bin. It will appear in the Inspector. Set Texture Type to 'Sprite (2D\ uGUI) and Sprite Mode to 'Single.' This tells Unity that you're dealing with an image that won't need to be mapped and that won’t need to be sliced (as opposed to a sprite sheet for animations.) Set the Filter Mode to 'Point.' The Filter Mode handles the quality of an image, and point is the cheapest option for performance. This is fine for us because our background image is a solid color. Now change the Max Size to the actual, power of two, height of your image. This will keep Unity from blowing out your image. Hit apply to save the changes.
Select the image from the Project bin and drag it to the Hierarchy. Hover over the Background object until it's highlighted. Un-click. The image should now appear in the scene window. What we've done is made the image a child of the Background object. Making graphics the children of their object representation is a common practice. This allows you to manipulate the object's script without tampering with its images. If you select the new child, you will find it now has a Sprite Renderer component attached. This module controls how Unity displays the image. For the sake of sanity, name your graphics child “BackgroungGraphics” to distinguish it from its parent. Next we need to make the background fill the camera window. There are a lot of solutions to this problem. We will change the size of the camera by clicking it, and in the inspector changing its size to fit. We will also change the size of the background image, something we can do here because the image is just a solid color. Note that if your image had detail, this process can blow that out. To make the background larger we will click it in assets and change its “Pixels to Units” value in the inspector. Lowering the number will make your image bigger and vice versa. Hit apply when you are done to keep the changes. Finally, select the parent Background object (not the child Background Graphics!) and change its Z position to 1 in the inspector. This places the background further away in space so it doesn't interfere with the interactive parts of our game.
Sprites are 2D images that represent characters or objects in a game. You can import a single sprite into Unity using the same process as backgrounds. Do this for the character and platform sprites. This time drag the character sprite image onto the Player object in the Hierarchy. If you think the scale of the sprite is off, you can make it bigger by selecting it in the project bin and lowering the pixels per units measure in the inspector. To make it smaller, increase the measure. Move the Player object (not just the graphics child!) up 5 units in the inspector. We do this to see both the player and platform sprites. Now we’ll do the same adjustments for the Platform sprite (leave it in place though), but this time we’ll use the scale metrics in the inspector. Increase the X and Y scales to 10. Leave Z at 1. Sometimes Unity will place your sprite in a different location than your actual game object. The sprite and the object need to occupy the same space so that physics will appear to apply to the sprite and to keep yourself sane. Make sure to line up your sprite with the blue box by selecting the graphics child and changing its position to 0, 0, 0 (this aligns the child in relation to the object.)
7. Colliders and Rigidbodies
Now that we can see what we're dealing with, it's time to make them interact. First we'll deal with the player. In Scene view, select the player. Make sure you select the player object and not the player's graphics! In the Inspector, click the Add Component button. Select PHYSICS 2D > CIRCLE COLLIDER. A green circle will appear around the boundary of the sprite. If the sprite image is a PNG file, then the collider will automatically be created along the alpha channel. If the green line is not correct, you can change the radius of the circle in the inspector. There are also box, edge, and polygon colliders to make crazy shapes from. Just remember that the more vertices that are in your collider, the more work Unity has to do to get the collider to work (translation: slow.)
Next we'll add a rigidbody2D. This concept is based off a physics engine called box2D. Basically, a rigidbody allows your object to have mass and thus allows forces to be acted against it. To add the rigidbody, go to ADD COMPONENT > PHYSICS 2D > RIGIDBODY2D. For the moment, leave the rigidbody settings alone. Again, make sure your rigidbody is attached to the player object, not its graphics child!
Make sure that these components are all under Physics 2D. Physics 3D will not do what you expect in the 2D framework! (Same goes the other way around if you're working in the 3D framework.)
Next we'll add a collider to the Platform. This time give the platform a polygon collider. Note that you can select and move the vertices by entering edit collider mode in the inspector and selecting vertices. Remember to exit this mode when you're done by clicking the button in the inspector again. Don't add a rigidbody to the platform just yet.
*When updating this tutorial I found I could no longer use the edit collider button to edit my colliders. If this occurs try WINDOW>LAYOUT>DEFAULT to reset your window layout (this will result in the layout in the above image) and this problem may go away.
Just like in real life, forces are what move objects in Unity. The most basic is gravity. Notice that the rigidbody on our player has an option for Gravity Scale and by default, it's set to 1. Setting it to 0 removes all gravity from the object. We can test this by positioning the player over the platform and pressing play. If gravity is present, the player falls. If not, nothing. For now, keep gravity at 1. The gravity test is more fun if we turn the platform over. Do this by selecting both the graphics child and the parent Platform object (hold control/command.) Then rotate the sprite and the collider will come with it. Position the Player above the platform but not over the direct center. Hit play. The Player rolls away.
Notice that the platform doesn't obey gravity. This is because it's just a collider. All colliders do is recognize when they've been hit. Rigidbodies detect and react to physics. Flip the platform back over.
There are lots of different forces you can apply to objects in your game. Later, when we ask a player to move via our keyboard input, we will exert a left or right velocity on the object.
All scripts have a start and update function. The start function should contain all of the information you want the object, in this case the player, to know upon startup. These are properties like initial health amount, color, ammo count, etc. These properties need a beginning value, but may change over time. The update function is continuously called (once per frame) by Unity. This is where Unity checks what the player is supposed to be doing and makes changes accordingly.
To make things easier, I've supplied this tutorial with a sample script on player movement. It's heavily commented to explain what’s happening when. You can import scripts the same way you import other assets. To add an imported script to an object, select the object, add a new component in the inspector, chose 'scripts', then the script you want. This comes in handy for grabbing scripts or bits of code from the internet. If you make a change to a script, make sure to save it! Then hit BUILD>BUILD ALL. If MonoDevelop tells you the build was successful, then you can head back to Unity.
See how our player's script changes the player's motion? You can adjust the values in the script to get different kinds of motion. There are countless ways of approaching motion in scripting, and each have varying outcomes in the game. Searching what others have scripted is a good way of examining these differences and finding out how to implement mechanics that you want. You don't have to be a coding wizard to make cool shit, you just have to be literate enough to know what to change. And don't be afraid of assholes online. If you are a coding wizard, don't be a jerk to those seeking help on the forums.
When you're ready to have others play your game, you need to package it into an executable. To do this in Unity, you’ll first need to save your scene. Note that you should regularly save both your scene and your project. Save and name your scene by selecting FILE > SAVE SCENE AS and entering a name. The name you entered should appear as the name of your scene in the Hierarchy. Next go to FILE → BUILD SETTINGS. A window should appear with an option on the right to “Add Open Scenes.” Click it, as this will add your current scene to the build. Add all the scenes you want to be played into the build. For our purposes we'll make a build for download. In the Platform menu, select PC, MAC, and LINUX. Then on the right, select your target platform. If you don’t see the platform you are looking for, then you may not have downloaded that export module with Unity. You can redownload Unity and opt in to the export modules you want. Then select the appropriate architecture. If you are building for Mac, select the universal architecture! Then click build. You should then find an executable to play in the same folder as your unity project. If you are sending a build to someone on a Mac, you can just zip the entire .app folder and send it off. If you are sending a build to someone on a PC, zip the executable and the data folder together, then send.
Play your game by opening the executable, selecting your resolution settings, and pressing play.
And there you go!