You are on page 1of 83

15 JANUA ARY 2013

Intermedi iate Un nity 3D for i D iOS: P Part 1/ /3


If you're ne here, you may want to sub ew m bscribe to my R feed or fo RSS ollow me on Tw witter. Thanks for visiting!

Lea how to make a full 3D game for iOS with Unity! arn

This is a tu utorial by Joshu Newnham, the founder of We Make Play an independe studio craf ua f y, ent fting creative d digital play for em merging platfor rms. Unity is ar rguably the most popular 3D g game engine fo iOS and fo many good r for or reasons! Rap developme Writing yo game with U pid ent. our Unity is far qui icker than tryin to write you own 3D engi or ng ur ine, than using lower level 3D frame n l eworks. Vis sual scene layo Unity com with a powe out. mes erful 3D scene editor that you can use to de u esign a huge pa of art you app often without having to write code! ur w g Cro platform. If you write you game with U oss ur Unity, you can deploy it to iO Android, W OS, Windows, Mac, or , eve the web! en Eas to learn. Un is far easie to learn than straight OpenG or lower le framework Its friendly to sy nity er GL evel ks. y beg ginners and is easy to get star e rted! We just rel leased an epic three-part Beg ginning Unity 3 for iOS seri but if your itching to learn more, wev got 3D ies, re ve you covere ed! This time, you will create a simple but fun 3D basketb game calle Nothing bu Net. Along the way, youl e ball ed ut ll cover the m major concepts used in Unity and will be ready to create y s your own apps! ! Some of th tutorial will be review, but youll learn a ton along the way since this game is much more complic his l s h cated than the H Heroic Cube game ;] g Note: This tutorial was made with Unit 3, so there m be some sli s m ty may ight difference with Unity 4 es 4. Shall we play a game? :]

Designi the App ing p


As with an app, before you begin codi you should first determine what it is you making and why! You ny y ing d ure u should figu out your tar audience, what your idea is and why it appeals to them, and what fe ure rget a eatures the app p should hav ve. Lets give this a shot!

Introducing yo target audience Bryan! our e:

For this tut torial, lets assu your targe audience is a male between the ages of 12 ume et n 2-35 lets cal him Bryan. B ll Bryan is: a 33 year old Acc countant own an iPhone ns is in nterested in sports is a office dweller with an aver an rage commute time of 20 min per day on pu n ublic transport. .

Like most smartphone us sers, Bryans iP Phone is a regu form of entertainment du ular uring commutin and in gene ng, eral, every spare moment whe he is alone and even som e en metimes when h bored at di hes inner, much to his wifes annoyance e! Your goal will be to crea something th offers Brya a chance to escape for a fe minutes dur ate hat an ew ring his day. Youll create a ve simple (but fun!) app with just a single a easy to lear mechanic. T way, it can be easily pick up ery h and rn This n ked and used in a noisy and disruptive envir n d ronment, such as commuting g. As your tar audience is males between the ages of 12-35, your th rget i heme for the ga will be spo related. Mob ame ort bile casual gam play typicall ranges betw me ly ween 4-8 minute so aim for a complete gam es ming session including load ding and starting the game to last 5 minut g tes. So you w a simple mechanic, and a quick sportswant m -related game. How about sho ooting a basket tball? Heres a sketch of w it could lo like: what ook

Ah your getting some re ewhere! Time t flesh out the functionality and componen you will nee to e nts ed! Mechanic/ /Interaction: Goal: score as ma points as possible within the time limit any To throw the ball, the player tap and holds their finger on th screen. The longer their fin ps he nger is held do own the harder the ball will be throw Leaving it d wn. down too long will raise a fou ul. Features: Vis sually rich and engaging to at ttract the playe er Sim support menu (overlay the game screen with the opti to start the game) mple m n ion Rea alistic physics to allow for rebounds Inc crease the diffic culty by movin the avatar ar ng round the court more frequen as time pas and the pla t ntly sses ayer gets more comfor rtable with the game). Game asse and their fe ets eatures: Env vironment Hoop Ring Court Skybox

Sco oreboard Avatar Idle anima ation

Throw ani imation Move anim mation

Okay, now that you have the basic design of the app d w e down, its time to start creatin :] e ng!

Introdu ucing Unity 3D y


If you alrea have Unity feel free to s ady y, skip this section n. Otherwise, you need to download Unity before you ca proceed! Yo can download a free trial a the Unity we , d y an ou at ebsite. Simply run the installer, and youll be r n ready to start u using Unity. Unity is fre for non-com ee mmercial use, b you do need to register it i order to use it for your pro but d in ojects hence e the Registe button you will see on first use. Once Un is launches the AngryBo sample project will appear er w t nity s, ots r. You want t start with a new project, so select File\N Project from the main me and save it wherever you want. to n o New enu t u Dont worr about select ry ting packages t import just n to now. Your first t time opening Unity (after hav U ving registered you will pro d), obably see:

Note: The introductory videos and man v nuals listed here are helpful re e esources to che out after yo finish going eck ou g through thi tutorial the will give you a good overv is ey view of Unity a what its capable of. For a more and comprehen nsive review, check out the of fficial documentation athttp://doc cs.unity3d.com m/Documentation/Manual/Lea arningtheInterf face.html.

Before you get started, ha a quick loo at Unitys u interface, w u ave ok user which will beco the comm ome mand center for all of your Unity projects! :] y

The Un Interfa nity ace


Lets do a quick review of the Unity Int o terface. If you already com re mfortable with this, feel free t skip to the n to next section.

Unitys UI is made up of 5 individual p I f panels, each tig ghtly related, bu giving you a different pers ut spective of the project. First, the P Project panel provides you w an overview and quick ac p with w ccess to all the assets of your game. Assets s means any resources that your game wi use, such as scripts, texture sounds, and data files. y t ill es, d Note that s some of the folder names that will appear in this panel are used for speci tasks. For i t n e ific instance, when using n graphical e elements for G Gizmos, which are design tim icons, you need to place t h me them in a Gizm folder so U mo Unity knows whe to search fo them. ere or Second, the Hierarchy pa anel is a view of all assets th are in the cu hat urrent scene. Th allows you to quickly sele his u ect items witho having to navigate throug the 3D view or perform a multi-select. A quick tip t get focus of a out n gh w to particular a asset, hover yo mouse over the item you w to focus o in the Scene panel and tap the F key. our r want on e p On to the C Camera panel! This gives yo the point of v ! ou view of the cam mera(s) in the scene. Note the three toggle e buttons at t top right. Maximize on P maximizes the window w the M Play s when you selec Play. Stats is handy when y ct s you are ready to optimize you app, as it wil show you dr calls and ot ur ll raw ther useful stat ts.Gizmos allow you to show and ws w hide specif Gizmos in the game scene fic t e.

The panel above the Cam mera panel is w where youll sp pend most of yo time design our ning your level This is theS ls. Scene panel whic allows you to visually desi your level. If youre fami ch t ign iliar with 3D m modeling tools, then you shou uld feel pretty comfortable here! :] If not, d dont fret Un is pretty in nity ntuitive and eas to learn. sy The selecte item, includ ed ding the camera can be manip a, pulated using t manipulatio tools at the t of the wind the on top dow:

The hand t tool allows you to pan around the scene. Th translation t u d he tool will show handles on the selected item e m, allowing y to move, or translate, the item around th scene. Rotat you r he tion and scale a allow you to m manipulate the selected ite by rotating or scaling it. em Note: Its w worth getting comfortable wi the short-cu to these tool Its pretty easy to rememb them; theyre the c ith uts ls. ber first four le etters on the ke eyboard and they correspond in order to the four tools: Q ( e (Hand), W (Tr ranslate), E (Ro otate), and R (Sca ale). Dont forg your good f get friend F to focu in on the sel us lected item you will use F a lot! :] A quick no about Scale its best not t manually sca things unle you are usin it for a visua effect. Scale your ote e: to ale ess ng al e models via the import op a ptions, which youll get into s shortly, and lea the scaling to 1.0. This en up being a lot ave nds more effici ient. The final p panel is the Insp spector panel this gives acc to all the p cess publicly accessible properties of the selected d object. Thi is an importa concept to u is ant understand so take some time explaining w this means e what s. All elemen in your gam inherit from GameObject. Different Com nts me mponents, whic derive from a component ch called Mon noBehaviour, are attached to each GameOb o bject. These Co omponents det termine how th GameObject will he t behave in y your scene. Each one o these Compo of onents is visibl via the Inspe le ector panel wh you can tw here weak their prop perties. Compo onents vary widel and can rang from anythi from a simp script that y write, to a camera, physi properties, an ly, ge ing ple you ic nd more. Esse entially, a Com mponent provides you with a f flexible way to build up your game element in a modular o r ts r fashion. It worth noting that all Game s g eObjects have a Transform component th heTransform co omponent determines where the Ga s ameObject lives in 3D space. Note: If yo oure familiar with iOS development think o your GameO w of Object as an NS SObject. Rathe than inheritin er ng functionali you attach specialized cla ity, asses to the obj each give it different f ject es functionality bu they are bun ut ndled together as one unit. s Below is a screenshot of the Inspector p panel when the camera is sel lected.

The components here include: Transform (attached to all GameObjects), Camera, GUILayer, Flare Layer, and Audio Listener. Dont worry about what they mean yet I just wanted to show an example of how you can see components on an object and configure its settings. Along with the panels, Unity exposes a host of functionality via the toolbar. The two items youll be most interested in are the Game Object and Component items. The Game Object menu item provides you with a list of items you can add to the current scene. The submenu items youll be interested in are Create Empty and Create Other -> GUI Texture. Create Empty places a new (empty) GameObject onto the scene. Create Other -> GUI Texture creates a GameObject with the GUITexture component attached and the currently selected texture as its texture, or the default Unity logo if a texture is not selected. At this point, you have a basic understanding of the Unity interface. Youll get a chance to start playing around with it in the next section, where youll start creating your Unity scene!

Game A Assets
In this sect tion, youll wal through the process of imp lk porting an asse into Unity, di et iscover how U Unity handles as ssets, and quickly cover what Materials are an what role th play in Uni y M nd hey ity. Looking at the list of feat t tures from the design section of this tutorial you have a p n l, pretty good han on what A ndle Assets youll requ uire. Imagine your designer h created the assets for you, including the images and fon necessary t y has , nts to create the m menu scr main reen:

Here the us can quickly initiate a gam and see their progress. Not that social networking is not implemented in ser y me r te this tutoria al. Your desig gner has also cr reated some tex xtures and 3D models for the main level, w e which will look like this:

He has delivered all of th hese assets as a zip file, which you can down h nload here. Af you unzip t file, you sh fter the hould see a directory of textures, fonts, image and models like this: es,

Now lets i import a few of the assets int your project. On the Projec panel in Unit click on the Createbutton and o to ct ty, e n select Fold Create the structure as sh der. hown below:

Start with t GUI graphics youlll be u the using in this tut torial. Drag all the files in the /NBNAssets/ l e /GUI folder int the to /NothingBu utNet/GUI fold These are the graphics th you will be using for your GUI, includin the icon and der. hat r ng d splash scre een. Unity will automatically detect the type of asset your importing an set some default properties In this case, Unity e re nd s. assumes th the .png file youre importing will be us as 3D mod textures and apply compre hat es sed del d ession to them. This . will result in a reduction in image quali when rendering them as G Textures, w ity GUI which you don want! :] nt Youll need to go through each image a set the type to GUI. To do this, select an item, navigat to the Inspec h and e o n te ctor panel and s select GUI option from the T Texture type dro opdown (as shown below).

Repeat the above for each of your imag h ges. Next, impo the textures for your mode Drag the .p files from t /NBNAssets/Textures fol ort s els. png the lder into the /NothingBu utNet/Textures folder in Unit Since these are textures fo your 3D models, you can l s ty. e or leave the defau ult settings as they are. Now import the fonts. Dr the .ttf files from the /NB rag s BNAssets/Fonts folder into the /NothingButN s Net/Fonts fold in der Unity. The fonts come from www.dafont.com (http://www.dafont ese t.com/score-board.font by Bo Fonts, ou and http://w www.dafont.co om/varsity.font by Unknown) t ). Finally, im mport the models. Drag the .fb files from th /NBNAssets bx he s/Models folde into the /Noth er hingButNet/M Models folder in U Unity. Note: The models for this game were cr reated in the op source (fre 3D creation tool Blender and exported a pen ee) n as FBX. Unity provides exte y ensive support for a wide array of media fo t ormats for audio graphics, an 3D assets be o, nd eyond just FBX f files for more information o the file form supported by Unity, please refer to Unitys importing e on mats guide. After addin the models, you should ch ng heck the texture are correctly associated wi your model To do this, c es y ith ls. click on each mo and inspec in the Previe pane of the Inspect panel If you click o the model an move the m odel ct ew l. on nd mouse around, yo can rotate th model to insp it from all sides. ou he pect l

If your mo odels are grey, then its most l t likely that the l link between th Material and Texture is br he d roken. Ill explain how this lin nking works an how you ca fix it in the n section m nd an next materials and t textures!

Materia and Tex als xtures


Models are associated wi Materials. M e ith Materials are a assigned a Shad (Shaders ar small prgram in the graph der re ms hics pipeline th determine how the models vertices are positioned and h the model is rasterized to the 2D screen) hat h s how l which dete ermines how Unity renders th image based on lighting, normal mapping and pixel da Some Shad U he d g, ata. ders can be proc cessor intensiv so the best i ve, idea here is to a assign Shaders specifically fo mobile to yo Materials. s or our Open up th Materials fo he older found und Models. He you can find the materials for each model. Select each der ere s Material in this list and change the Shad from Diffu to Mobile/D n der use Diffuse. If your texture hasnt bee associated w the materia then youll see a blank gra spot in the b where the i en with al, ay box image should be ( (theres a Sele button in t bottom righ here). To ass ect the ht sociate the corr texture, yo can click the rect ou e Select butt to choose a texture, or sim ton mply drag the texture onto thi spot. is For the pla ayer, the materi should look something lik the following ial k ke g:

For the Ho oopTex Materia youll requi transparency to be set. Sel this materi and choose the al, ire lect ial Transparen nt/VertexLit Sh hader. Theres jus a few things left to do in th section befo you wrap th st his ore hings up. There is no standard e dized scaling between 3D modeling too so to get th models to a reasonable siz select each o them and up D ols, he ze, of pdate their scale factor from 0.01 to 1 as shown below: m s

Finally, open up the Player model and youll notice a few child elem p y ments, as below: w

Some of th hese child elem ments will differ depending on what 3D mod n deling tool you are using. In B u Blender, the BP Player and BPlaye erSkeleton are the objects, th BPlayer (und BPlayerSke he der eleton) is the m mesh data that d describes the geometry o the player, and finally the i of a items below th are animatio frames, whi will be desc hat on ich cribed in furthe er detail once you start wirin up your pla e ng ayer!

Setting up the Sce ene


In this sect tion you will visually setup th scene of you game. The g here is to g some hands on experience he ur goal get s e working w the Unity scene environm with s ment, discover s some more Components that Unity offers, a finally end up t and d with a scen ready for yo game. ne our Before you start visually designing you scene, consid the requirem u ur der ments from the design stage. Youll have th e he camera fac cing side on to the court and t player, and positioned so that one of the hoops on the court can be se the d e een. Your goal is to arrange th scene so it lo he ooks somewha like the follo at owing:

However, t is easier sa than done! :] this aid This is you first chance to start playing around with t Scene, Cam ur t g the mera, and Hiera archy panels in Unity. Perform the n m following s steps: Sel the Main Camera in the H lect C Hierarchy folde and set X=6 Y=7, Z=14 and the Y-Ro er, 6.5, 4, otation to -180 0. Dra a scene mod into the Hie ag del erarchy panel, and set X=0, Y Y=0, and Z=0. You should se it appear in t ee the Cam window! mera Dra a player mo into the Hi ag odel ierarchy panel, and the Y-rota ation to 90. Now that y have some basic objects a you appearing, exp periment movin the player ar ng round the scen using the Sce ne ene panel. Sele the player, and drag it arou the scene u ect a und using the X, Y and Z arrows that appear ne to the playe Y, s ext er when its s selected. You can also change the perspectiv of how youre looking at t scene using the perspectiv c e ve the g ve switcher in the upper righ of the scene panel. n ht

At this poin add the rem nt maining objects the basketba and the hoop See if you c arrange the into roughly the all op. can em y right spot y yourself using the Scene and Hierarchy pan if you ge stuck, you ca always set th position ba to nels et an heir ack the center ( (X=0, Y=0, Z= =0). While youre playing aro ound with this, you might not that whatev you click o in Hierarchy is highlighted in tice ver on y d the Scene. You can also easily zoom in on an object in the scene vie for examp try double clicking on the e n n ew ple, e Player to c center it.

If it isnt centered the wa you want it, use your mous wheel to zoo in or out, d ay se om drag the view in the window w n with the mouse, or hold down the Alt/Option key to rotate around and see things from a , n e another angle. Note that n none of these operations affec the actual po o ct osition of objec its just to h you get a better view. cts, help Now that y have your scene roughly set up, time to configure the scoreboard! you

Separating the Scoreboard from the Scene


Currently, the scoreboard is a child of the background, but you want it as a separate object. So in the Hierarchy view, drag it from a child of the scene into the root of the Hierarchy. The following dialog will appear click Continue.

Note: GameObjects can have children and those children can have children, and so on and so forth. Children of a GameObject dont directly inherit functionality of their parent (unless explicitly scripted), but rather use their parents scene space to position themselves. For instance, if the parent was moved along the x-axis, then all the children of the parent would also be moved e.g. if you held a basketball (your child) and walked forward, the basketball would move forward with you. To make a child independent so that it doesnt inherit the translation, orientation, and scale of its parent (also known as the objects pose), then simply drag it out of its parent folder as you did here. The reason you split out the Scoreboard like this was so you could add some 3D Text objects to it, to show the earned points and remaining time. This is not mandatory but rather an choice for aesthetics and organisation. Doing so helps (visually) de-couple it from the rest of the scene and gives you the choice of creating a prefab (which we will talk about later) that you would use if you were to create multiple levels. The 3D Text object is surprise! :] an object that renders text in a 3D environment. Add a 3D Text object to the scene by selecting the Menu GameObject -> Create Other -> 3D Text. This will place a new GameObject called New Text into your scene. Rename this 3D Text object to Points and drag it into your Scoreboard object. Next, associate thescoreboard font with the 3D text by performing the following steps: Drag the Project\NothingButNet\Fonts\Scoreboard font to theHierarchy\Scoreboard\Points\Text Mesh\Font property Drag the Project\NothingButNet\Fonts\Scoreboard\Font Material material to theHierarchy\Scoreboard\Points\Mesh Renderer\Materials\Element 0 property In the inspector for the 3D Text, set the default text to 0000 and the alignment to right middle aligned. Then use the Scene panel to position the font on the right spot on the Scoreboard. Note you may have to rotate the text to get it to show up right for me, my settings were X=0, Y=0, Z=2.8, Rotation X=270, Y=180, Z=0. Now perform the same step for the Time text by duplicating the Points text using Cmd-D and positioning it slightly below. Name the duplicated object Time and set the default text to 00:00. In the end you should have something that looks like the following:

Turn the Lights On


Have you n noticed that the scene appears pretty dark? Thats because you havent a e e added any light to the scene, so ts , lets light i up! it Note: Ther are some con re nsiderations to be made when adding lightin to a scene. A n ng Adding lightin to a scene co ng omes at a rendering cost. If you have done an Shader prog u ny gramming in the past, then you understand th additional e he effort to support the rendering of dynamic ligh o hting. Each lig requires eac rendered obj to calculat the final ligh ght ch ject te hting effect depe ending on the Shader/Materia being used, a has a high computational cost. S al and l If at all pos ssible, bake all the lighting details into th texture of the object before rendering. Ba g he e e aking is a way of rendering t textures with a static light the ting effect applied, so that no additional com o mputation is re equired to get t the

same visua effect. Also, use the scenes ambient light to control the lighting inten al e nsity; this can b accessed via the be a Edit -> Ren nder Settings panel. p In your sim scene, you will add a lig Select Gam mple u ght. meObject -> Cr reate Other -> Directional Light to add a n new directional light GameOb l bject to your sc cene that will b brighten everyt thing up. A full discu ussion about li ighting is out o scope for this tutorial, but a directional lig influences the whole scen of ght ne depending on where you direct of the li ight by rotating the Direction Light Game g nal eObject. Select the light and use t the move a rotate tools in the Scene p and s panel to experi iment moving i in different p it positions.

Camera P Position
Now turn y your focus (pun fully intende :]) to the co n ed! orrect positionin of the came Camera positioning is not a ng era. t science, bu rather more of an art. Play the part of the director, and d ut o drag the camera into place using the movem a ment and rotatio tools in the Scene panel. on S You can us the preview available in th Game panel directly below the Scene pan where youre doing your scene se he w nel building. A well, you ca make use of the little previ window th pops up whe the camera is selected in th As an f iew hat en he Hierarchy view. Next, in th you should update your Ga screen dim he u ame mensions to iPh hone Wide 480320, via the d dropdown in th he upper right of the Game panel. If you d not see this, go to Unity\Bu Settings, a switch your platform to iO t p do uild and r OS. At this poin you should have a view si nt, imilar to the on below: ne

Your scene is looking pretty good, isnt it? Feel like a real director yet? :]

Unity Physics: Colliders and Bodies


Its time to add Components to your Scenes GameObjects so that they can react to each other! Your goal is to have your objects react to each other when they collide. Luckily, Unity contains a fully-integrated physics engine and has packaged it up into a suite of Components that can easily dock onto your GameObjects.

Before you add physics capabilities to your objects, youll need to first take a look into what Physics means in Unity. Click on the Components -> Physics menu (top toolbar) and have a quick look through the types of components readily available to you.

Colliders define the physical dimensions of your object, which can be independent of the visual shape of the object. In general, the colliders are ordered by complexity, and the more complex the object, the performance cost of using these objects rises. Where possible, use Box/Sphere to encapsulate your objects, as these Colliders have the least computational load for your application. The other common Collider youll use frequently is the Mesh Collider. This uses the 3D models mesh to define the boundary of your object. In this case, the visual dimensions will equal the physical dimensions. In addition to physically colliding with other objects, a Collider can be set up as a trigger that can detect collisions (so you can make something happen programmatically), but not actually cause any collision responses. This will be useful so you can detect when the ball goes through the basketball net. In order for objects to react, each object must have some form of body in addition to a collider. This is done by either adding a Rigidbody or CharacterController to the GameObject. The best way to get comfortable with Physics is to play around lets make that basketball bounce!

Bounce that Basketball!


Select the basketball, and add a Rigidbody onto it by selecting Component > Physics > Rigidbody. Then hit the Play button in the upper center of Unity to preview the gameplay youll see the basketball fall below the floor. If your basketball warps to the middle of the scene when you click play, select the basketball and unclick the Animation checkbox in the properties and try again. It should stay in the right spot now. But it wouldnt be much of a game if the ball was allowed to fly out of the scene! :] Youll need to create a set of boundaries that will constrains the ball to the playing area. To do this, select the scene.Wall object and select Component > Physics > Mesh Collider. Repeat for the scene.Ground and scene.Background objects. Then select the scene.court object and select Component > Physics > Box Collider. If you play the scene again, youll see that it still falls through the floor. This is because you still havent set up a collider for the basketball! So select the basketball and go to Component > Physics > Sphere Collider to set up a sphere collider for your basketball. It will default to the right size, but you can change the radius if you want in the Inspectors Sphere Collider section. Along with the ball reacting to the environment, youll also want it to bounce when it collides with an object. To do this, youll need to assign a special type of Material that Unity provides called a Physic Material. Where Materials affect how objects look, Physic Materials determine how the object behaves when a collision occurs. This is associated with the Material property of the GameObjects Collider component. The following image shows the properties of the Rigidbody attached to the basketball:

On the Project panel, select the Create dropdown menu and then select Physic Material to create aPhysic Material , and name it BallPhyMat.

Now set the properties of the Physic Material as shown below. Details on the function of each of the properties shown below is out of scope for this tutorial, but further information can be found athttp://docs.unity3d.com/Documentation/ScriptReference/PhysicMaterial.html.

In order to allow the ball to bounce, friction is set fairly low. To associate the newly created Physic Material to the basketball, select the Physic Material you just created and drag it to the to the basketballs Collider material property.

Click the play button again, and this time it falls to the floor and bounces, w00t! :] As for the hoop, you want it to react to the ball as well as detect when the ball goes through the net. Add aMesh Collider to the hoop mesh (hoop.LeftHoop). Also, you want to set up a sensor or trigger to detect when the ball goes through the hoop. To do this, add a Box Collider to hoop.LeftHoop_001, but shorten the box and position it so its just below the net (you can do this by tweaking the values in the Inspector I changed Center Z to -1.4 and Size Z to 0.2). Also, click the checkbox to set the trigger property to true.

Note: to vi isually resize colliders using t mouse, sele the collider object and h the ect rs hold down Shif This will sh ft. how the handles of the collide allowing you to resize it us s er, u sing the mouse e. Okay! Tha takes care of the ball tim to take a loo at the Player object! :] at f me ok r

Meeting the Team g m


In this gam we want the player to bou me, e unce the ball an for the ball t not roll throu him. Stopp nd to ugh ping the ball ro olling through the Player is easy enough; go a e y ahead and add a Capsule Coll lider to the pla ayer GameObje ect. Youll then need to position and size th capsule I c n he changed the hei ight to 3.8 and the Center Y t 1.8. to

Note: Colliders are shown in the Scene panel in a green outline unless they are Mesh Colliders , in which case its the mesh that shows the collision boundaries. The approach used to bounce the ball requires that the game can detect when the ball collides with the players hand. When this occurs, you will push the ball back down to the ground, just like it happens in real life! To attach the collider at the correct position, youll drill down to the players skeleton and add the collider to the hand which will be used to bounce the ball.

The above screenshot shows you the children of the player GameObject. Where do these children come from? Good question! :] These children form the skeleton built to animate the player the parent is the pelvis which also has theSkeleton Mesh Renderer component attached to it, which is responsible for rendering the mesh,. The children are the bones of the skeleton which were built in Blender. ArmIK_L, ArmIK_R, LegIK_L, LegIK_R are just handles used in Blender and have no function in your app. Now add a Box Collider toplayer\BPlayerSkeleton\Pelvis\Hip\Spine\Shoulder_R\UpperArm_R\LowerArm_R\Hand_R and resize the Collider similar to what is shown below, and set the trigger flag to true.

Prefabs and ho to Take Advantage of Them s ow e m


This sectio is just an opt on tional note that may be usefu for you later feel free to s t ul skip if you need a break! :] d A game ap normally con pp nsists of a lot o objects that are identical bu are used mu of ut ultiple times. Fo instance, you may or have create a city using the same build ed ding over and o over again. An efficient way to do this is to create a maste n er template w which you can reuse over and over again. As well, it gives you the advan r s ntage of being a to update all of able the objects by simply upd s dating the temp plate. Unity prov vides the ability to do this thro y ough the use of Prefabs. Pref fabs allow you to create one master copy of an u object and create multiple identical cop of it. Howe pies ever, even if yo dont want t create multip copies of y ou to ple your object, it st provides an efficient way of creating and managing a s till n setup for each of your game o objects. To create a Prefab, you can either just d c drag over an ob bject from you Hierarchy pa to your Pr ur anel rojectpanel, or you can explici create a Pr itly refab via the Pr roject dropdow and then dra the object(s) from yourHie wn ag ) erarchy panel into this object. . Now each time you want to create anoth object from this template you just need to drag the Pr t her m e, d refab over to th he scene. Very easy and very useful! :] y Note: to m make an update to your Prefab just grab any Prefab of the type youre in b, y e nterested in, ma your updat ake tes, and then se elect the Game Object -> App Changes T Prefab optio from the too e ply To on olbar menu. Th changes will he l automagica propagate to all associated objects! all o d

Where To Go Fro Here? om


Congratula ations, you mad it! Youve g de gotten through the hardest pa getting use to the Unity GUI as a com art ed y mplete beginner from here on out it will be sm o mooth sailing :] Here is a sample project where we have left it off in th tutorial so f To open it i Unity, go to File\Open Pro w e he far. in oject, click Open Other, and bro n owse to the fol lder. Note that the scene won load by defa to open i select nt ault it, Scenes\GameScene. So far, you have explored how GameO u d Objects can cont children an their childre live in their space (in term of tain nd en r ms pose). You looked at Lig u ghting concepts and Colliders , and associat Physics con s s ted ncepts with you objects. You also ur u added a Ph hysic Material to the ball to in nfluence how i reacts when a collision occ it curs, as well as seeing how Collid can be use as triggers o by the physic engine. ders ed or cs

And thats it for the first part! :] In the next section of this tutorial, youll bring your scene to life with interactivity and animation. That will happen when youre introduced to Scripting. Until next time!

Beginning Unity 3D for iOS: Part 2/3

Learn how to use Unity to make a simple 3D iOS game!

This is a post by Tutorial Team Member Christine Abernathy, an Engineer on the Developer Advocacy team at Facebook. Welcome to the second part of the tutorial series on Beginning Unity 3D for iOS! In the first part of this series, you learned the basics of Unity by building a very simple project and deploying it to an iOS device. Youll want to be sure to go through that part of the tutorial before moving on to this one. Now in this second part, youll add functionality to enrich the project, including better player movement and better game scenery. Youll also learn how to use Unity Remote for debugging. Once again, game on!

Getting Started: A Change of Scenery


Open your Unity project from Part 1 of the tutorial. If you dont have it already, here are the download links:<="" a="" style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-weight: inherit; font-style: inherit; font-size: 13px; font-family: inherit; vertical-align: baseline; color: rgb(0, 104, 55); ">Unity Project, Xcode Project. Youll make your changes for this part of the tutorial in a new scene, so you can easily have the old one for reference later if youd like. Select File\Save Scene as and name your new scene Level_2. The new Level_2 scene should show up in the Project View. All the assets you had in the previous scene, such as scripts, are now available for use in your new scene. You can make changes to the GameObjects present in the Level_2 scene without affecting the same objects in the Level_1 scene.

Gettin Jiggy With It


First youll enhance the players movement. Currently your Heroic Cube always moves forward and rotates right. Thats not very smooth or exciting.

A Charact Controller is a Unity com ter mponent that yo can attach to a GameObjec to help create more realistic ou o ct e c movement. You manipul the Character Controller t late through script functions. For examp you can cal a pre-defined SimpleMove function to mo the charact The Simple ple, ll d ove ter. eMove function takes in a V Vector3 input representing th speed with w r he which to perfor the move. T characters movements rm The s automatica account for gravity, allow ally r wing it to move up slopes and down stairs. e d The charac also slides around any ob cter bstacles it finds in its path wit s thout your having to write co to take care of ode e that. To see wha this means, select the Cube GameObject (the player) in the Hierarchy View and at s e n y selectComp ponent\Physic cs\Character C Controller. You see a dialog asking for co ull g onfirmation to r replace the Box x Collider w a Character with rController.

Click Repl lace. You should see a new component in the Inspector for the Character Controller. Yo d e oure going to c create a brand-new script to co ontrol the playe movement so you no lon ers t, nger need to att tach the MoveSimple script t the Heroic C to Cube in this scen ne.

Click on th gear icon to the right of the MoveSimple script compon in the Insp he e e nent pector and sele Remove ect Componen The script should no longe show up in t Inspector. nt. er the

Create a ne JavaScript asset by selecti Assets\Cre ew a ing eate\JavaScript and name it M t MoveAround. D Double-click th he new script to open it in th MonoDevel Editor. Delete the stubbed out functions and add the fo he lop d s ollowing code:
var speed : float = 3.0; d var rotat teSpeed : fl loat = 3.0; function U Update () { var c controller : CharacterC Controller = GetCompon nent(Charact terControlle er); // Rota around y - ax ate xis tran nsform.Rotate(0, Input.Ge etAxis ("Horizon ntal") * rotat teSpeed, 0); // Mov forward / bac ve ckward var f forward : Vect tor3 = transform.Transfo formDirection(Ve ector3.forwa ard); var c curSpeed : float = spee * Input.GetAxis ("Vert f ed tical"); cont troller.Simp pleMove(forward * curSpeed d d); } @script RequireCom mponent(CharacterContro oller)

Save your changes. The last lin in the script specifies that this script can only be attached to a GameO ne Object that has a Character Controller component. The Updat function ge a handle to the Character C te() ets Controller com mponent. It then rotates the tra n ansform around the y-axis base on inputs rep ed presenting left t/right moveme ents. By defaul the left/right movement is controlled by b lt, t both the left/righ arrows and the A/D keys. ht t The Input.G GetAxis() valu ranges from -1 to +1. A ne ue egative value w result in an anti-clockwise rotation and a will n e positive va a clockwis rotation arou the y-axis. alue se und The Simple eMove functio moves the ch on haracter forward or backward depending on the input obt d, tained from Input.GetA Axis(Vertical This input is triggered by e ). s either the up/down arrows or the W/S keys. As with the r . horizontal input, the Inpu ut.GetAxis() va ranges from -1 to +1, and negative and positive value will result in alue d d es n backward a forward movement, respectively. You u a speed mu and m use ultiplier to cont the rotation angle or the m trol n move distance. Attach the new script to your Heroic Cu By now yo should know the drill. y ube. ou w (Hint: If yo dont remem ou mber, its Comp ponents\Script ts\Move Aroun :]) nd. When youre done, you should see the n Move Aro s new ound script com mponent in the players Inspe ector.

Why dont you take your Heroic Cube for a spin using the Unity Editor? Click the Play button and experience your newfound freedom oh, the joy of being able to rotate left and right, and move forwards and backwards! Use the left/right/up/down arrow keys to move around, and also test out the W/A/S/D keys. The player movements are much smoother now, thanks to the Character Controller component and your scripting genius. Give yourself a pat on the back before continuing. :]

Debugging with Unity Remote


You might have noticed in the last tutorial that testing your project on your iOS device was a bit cumbersome. The entire process of exporting to an Xcode project and building and running on your device can take quite a bit of time, which really adds up during development. The good news is theres a better way! The fastest way to debug your game on iOS is using an app called Unity Remote. This allows you to skip the steps of building your project for iOS, launching Xcode and deploying on your device. With the Unity Remote iOS app, you can link your iOS device to the Unity Editor and control your Unity Editor from the iOS device. This allows you to quickly debug your game inside the Unity Editor. Unity Remote is available for free via the App Store. Download and install the app on your device. Note: To use Unity Remote, your iOS device and your computer should both be on the same Wi-Fi network. In addition, the Unity Editor window must be in the foreground in order for this to work. If you send the Unity Editor window to the background, youll get a Waiting for game view. Press Play message on the iOS app. Click Play in the Unity Editor. On your iOS device, launch the Unity Remote app. Select your computer from the list that appears. If your computer is not listed, try entering your computers IP address in the Unity Remotes IP setting.

When Unit Remote has paired with yo computer, y ty our your iOS devic should be ab to control th game runnin in ce ble he ng the Unity E Editor. The resolution of the d display on the device wont b ideal, but it a great way t quickly prot be s to totype your game. However, you want to oc ull ccasionally buil the project f iOS and lau ld for unch it from Xc code so you ca an properly te game physic under more realistic condi est cs itions. Test the ga on iOS. Yo ame oull find that t theres no way to move the p y player on your device because your e left/right/u up/down inputs do not exist on iOS (howeve you can still control it on y n er, l your Mac). Ne up, youll ext implement some joystick controls to fix this. t k x

Double the Joysti icks, Double the Fun n


Lucky for y Unitys Standard Assets (Mobile) pack you, S s kage includes a assets that imp plement joystick functionality y. Select Asse ets\Import Pac ckage\Standar Assets (Mob rd bile) to import t relevant ite (as showin below) from the the ems ng m package.

Select the i indicated items that relate to j s joystick functi ionality. Click Import. When the import is c n complete, the Project Vie will contain a new folder called Standar Assets (Mob ew n rd bile). You may see a warning in Unity 4 with the y g imported jo oystick script, similar to this (in yellow at th bottom): he

To resolve this, double-click on the war rning. That sho ould open the J Joystick script file. Put your c cursor on the li ine with the warning:
game eObject.active = false; e

Modify the statement to: e


game eObject.SetAc ctive(false);

Now when you switch ba to the Unity Editor, the w n ack y warning should vanish. Take t that! First add th Dual Joystic prefab to y he cks your scene. A p prefab is a reusa and often customized Ga able ameObject. Yo can ou add a prefa to a scene by either draggi it from the Project View o adding it pro ab y ing or ogrammatically via a script. F y For example, y could build a prefab that represents a pl you d layer and progr rammatically a multiple players to a scen add ne. In your Pro oject View, open the Standar Assets (Mob rd bile)\Prefabs fo older. Drag the Dual Joystick prefab into y e ks your Hierarchy View.

You can se the joysticks by clicking th Game tab to go to the Game View: ee s he o m

Go back to the Scene Vie o ew.

Click on the triangle next to the Dual Joysticks GameObject in the Hierarchy View. Notice that the Dual Joysticks GameObject is actually composed of two child GameObjects. A procedure called parenting was used to set up the joystick parent/child GameObject relationship. Parenting is useful if you want to create a composite GameObject that has linked GameObjects. For example, you may want the left and right joysticks to be enabled or disabled at the same time, and its much easier to do this via script if they can be treated as a single object. Select the LeftJoystick GameObject and note that it has the Joystick script component attached to it. Select the RightJoystick GameObject and verify the same. The Joystick script detects touch events on the GUI Texture (the graphic) attached to it and repositions it with certain constraints. For example, the graphics only move inside a given boundary. The script also normalizes the position output so that its within the -1 to +1 range. This allows you to use the joystick in an iOS environment as a substitute for Input.GetAxis(). At this point youve placed the two joysticks in the scene, but theyre not yet connected to your Heroic Cube to drive input. Youll modify the script to assign the right joystick the task of rotating the player, while the left joystick will move the player back and forth. Modify the MoveAround script to handle joystick input. Open the script for editing and add two public variables representing the move and rotate joysticks (at the top where the other variables are):
var moveJoystick : Joystick; var rotateJoystick : Joystick;

Then add a new function that looks at the joystick position and returns an output between -1 and +1. Add it right after the Update() function:
function joyStickInput (joystick : Joystick) { var absJoyPos = Vector2 (Mathf.Abs(joystick.position.x), Mathf.Abs(joystick.position.y)); var xDirection = (joystick.position.x > 0) ? 1 : -1; var yDirection = (joystick.position.y > 0) ? 1 : -1; return ( ( absJoyPos.x > absJoyPos.y) ? absJoyPos.x * xDirection : absJoyPos.y * yDirection); }

The joystick input is a Vector2 input, having x and y components. You use the larger, absolute value of x or y to set the output. You use the direction of the joystick as a multiplier to denote a negative or positive value. This results in an output value between -1 and +1. Modify the Update() function to handle input from the Unity Editor or from an iOS device:
function Update () { var controller : CharacterController = GetComponent(CharacterController); // Rotate around y - axis var rotatePos = Input.GetAxis ("Horizontal") ? Input.GetAxis ("Horizontal") : joyStickInput(rotateJoystick); transform.Rotate(0, rotatePos * rotateSpeed, 0); // Move forward / backward var forward = transform.TransformDirection(Vector3.forward); var movePos = Input.GetAxis ("Vertical") ? Input.GetAxis ("Vertical") : joyStickInput(moveJoystick); var curSpeed = speed * movePos; controller.SimpleMove(forward * curSpeed);

The transfo orms Rotate() function gets i input from eith the left/righ arrow (or A/ keys or from the rotate jo her ht /D) m oystick input. The Character Con ntrollers SimpleMove functio gets input fr on from either the up/down arrow (or W/S) key or w ys from the le joystick inpu eft ut. Save your script changes. Select the pla ayer GameObje (the cube) a note that th Move Aroun script comp ect and he nd ponent has two ne public varia ew ables for Move Joystick and R Rotate Joystick k.

These varia ables are not cu urrently assign With the p ned. player GameOb bject still select drag ted, the LeftJoy ystickGameOb bject to the Move Joystick var riable. Drag th RightJoystic GameObject to the Rotate he ck t Joystickva ariable. (Or inst tead of draggin you can use the selector next to each variable, as indi ng, ed icated before.)

Click Play in Unity Edito Start Unity Remote on you iOS device. or. ur Test the joystick function nality and verif that you can move forward and backward using the left joystick and r fy n d d t rotate left and rig using the rig joystick. A you move th joysticks on your iOS device, you should see the joystic ght ght As he d cks moving in the Unity Edit tor.

Note: The joystick image might appea stretched like you see here. Dont worry, they wont sho up like that on es ar e . ow t the actual d device.

A Clear Bright Skybox r, S


Now that y youve improve your Heroic Cubes movements, how ab ed c bout improving the scenery? S far the players g So been occup pying a dull, gr world. Tim to do some l rey me landscaping. :] Thankfully this is fairly simple. Unity includes assets in the Standar Assets pack y, s rd kage that you ca use to create a an e sky, add ve egetation and vary the height of the terrain. v t In this sect tion, youll add a sky by mea of a skybox component. T skybox is a big cube obje thats added to d ans x The ect d the Main C Camera in your game. Once y add the com r you mponent, you c dress it up by adding a m can material that cov vers the cube an is rendered to create the sk nd kybox effect. Select Asse ets\Import Pac ckage\Skyboxe to begin the import process Select Sunny Skybox.mat then click Im es s. y2 t, mport.

When the i import is comp plete, your Proj View shou have a new Standard Assets\Skyboxes f ject uld folder that cont tains the newly i imported asset t.

Select the M Camera object, then sel Componen Main o lect nt\Rendering\S Skybox.

The new co omponent show up in the In ws nspector. Notice that it has a v variable representing the material. This is w where the skybox material you imported earlie comes into p x i er play. Click on th little circular icon next to t Custom Sky he the ybox variable. The Select Ma aterial dialog s should pop up l listing any material assets that are available fo your project use. a or s

Click on th Sunny2 Sky he ybox material, t then close the Select Materia dialog. The C al Custom Skybox material shou x uld now have t Sunny2 Skybox material assigned to it. the

Your Scen View will no magically c ne ow change to display the sunny sk youve just added. You ca click on the ky an Game tab t view the sky in the Game V to y View, or click the Play button n.

The sun ha come out! And even thoug it may appea overcast, tha encouragem to add som green life to your as A gh ar ats ment me o world.

Dont F Forget You Veggies ur


Switch bac to the Scene View. You ca create veget ck e an tation by first a adding a terrain GameObject, then adding n material (e grass) and objects (e.g., t e.g., trees). You no lon nger need the plane GameObj p ject, as the terr will take o rain over flooring re esponsibilities. Right-click on the n plane Gam meObject in the Hierarchy Vie and select D ew Delete. Select Asse ets\Import Pac ckage\Terrain Assets.

Click Impo to import al the selection The Terrain Assets should show up unde your Standar Assetsfolder ort ll ns. d er rd r. You can us the imported assets to mod the behavi of a terrain GameObject. se d dify ior Select Terr rain\Create Te errain to add a terrain GameO Object to your scene. Select t terrain obje and change its the ect transform p position to -1000,0,-1000 usi the Inspecto This stretch the terrain o far enough to give your p ing or. hes out h player room to mo ove.

The Terrai (Script) sect in tion contains to that you can use to dress up your terrai ools s in:

Select the P Paint tool to br ring up the bru ushes you can w work with:

Youll be p painting your terrain with gra Click Edit Textures\Add Texture: ass.

In the Add Terrain Textu dialog, click Select in the Texture area, s d ure k select the Grass (Hill) texture, close the Select s e l Texture2D pop up, then click Add: D c

Click aroun in your scen to paint the grass. To chec out your artw nd ne ck work, click on the Game tab:

If only land dscaping could always be so easy! d Switch bac to the Scene View now y ck e youre going to plant some pa trees! Sele the Place Tr o alm ect Trees tool in the Terrain (Script) secti n ion:

Click Edit Trees\Add Tre ee:

In the Add Tree dialog, click the circular icon next to the Tree entry select the Palm GameObject, then click Add: d c a y, l c

Set the Bru Size to 20: ush

Start addin trees to your scene by click ng r king where you want the tree to be. Hint: Z u es Zoom into the scene and pan around as y place the trees. Try adjus you t sting the Point light range and height to see more of the sc d cene as you add d trees.

When done your scene should look som e, s mething like th his:

Wow, thats much better! Its starting to look like a re world down there. But you terrains stil looking a bit flat, o eal n ur ll t isnt it? You can ea asily add some height variatio to your terra In the Terr e on ain. rain (Script) se ection, select th leftmost too to he ol raise and lo ower the terrain height: n

Set the Bru Size to 20, then in the Sce View, click on two to thr spots aroun the player (n too near, th ush ene k ree nd not hough) to vary the terrain height. e

Preview th game and mo around the scene. Tweak the number of trees in the sc he ove e k f cene as you see fit but remem e mber to stop the game before making any cha m anges you wish to keep. h

Save your scene. Test your p project using Unity Remote a when satisf U and fied, build it as an Xcode pro s oject. Select Fil le\Build Settings an in the Build Settings dialog, click Add C nd Current to add t Level_2 sc the cene. The new s scene will show up w in the Scen In Build lis Deselect the Level_1 scene to build only Level_2. nes st. e e

Click Build choose to replace the previ d, ious project if asked and then launch the Xc n code project. D Deploy and test on t your iOS d device.

Not bad, eh Imagine how long it would have taken to do all this wi raw OpenG ;] h? w o ith GL

Where to Go From Here? o H


Well done! Youve taken another big st n tride forward in developing y n your Unity skills. :] Soon, you Heroic Cube will ur e be closing in on the finish line, too. h Here are so download with all of th code from th project up un this point: <="" a="" styl ome ds he he ntil le="margin: 0p px; padding: 0px; border: 0px outline: 0px font-weight: inherit; font-st x; x; tyle: inherit; fo ont-size: 13px; font-family: in nherit; vertical-ali ign: baseline; color: rgb(0, 10 55); ">Unit Project, Xco Project. c 04, ty ode In the final part of the tut l torial, youll bu on the proj by adding gameplay. Then youll polish it up by addi all uild ject ing the bells an whistles tha players expec nd at ct.

Begi inning Unity 3D fo iOS: Part 3/3 g y or

Lear how to use Unit to make a simple 3D iOS game! rn ty

This is a po by Tutorial Team Membe Christine Abernathy, an En ost l er ngineer on the Developer Adv vocacy team at Faceboo ok. Welcome t the third and final part the Beginning Un 3D for iOS tutorial series! to d nity In the first part of this ser ries, you toured the basic Uni tools, create a game with a simple play control d ity ed h yer mechanism and learned how to deploy your project on iOS. m h n Then in the second part of the series, yo enhanced th movement o your Heroic Cube and brou e o ou he of ught some life t the to world it oc ccupies with sk grass, trees and a variable terrain. ky, In this third and final par youll add ga d rt, ameplay to the project. Instea of simply m e ad moving around t scene, your the r Heroic Cub will have to dash (as cubes do) to a finish line within a certain amoun of time. be o nt To give the player a chall e lenge, obstacle will rain dow on the Cube as it zigs and zags its way to that finish lin A es wn e d ne. countdown timer will add to the drama. Success will b greeted with cheers failu with the deafening silence of n d . be h ure e defeat. :] Youre alm to the finis line too, so remember its hip to be squ most sh uare!

Getting Started: The End in Sight! g T n


First, save the Level_2 sc cene as a new s scene named L Level_3. Youll be making all your changes for Part 3 of th l l he tutorial in t new scene this e. Youll crea a finish line using two posts and a thick line connectin them, so that the player can clearly see th ate e ng n he target desti ination. The fin line will in nish nclude an invis sible wall thats used as a trig gger when the H Heroic Cube crosses the finish l line. Select Gam meObject\Crea Empty to cr ate reate a new obj that represents the finish line. This is th parent ject he GameObje under which youll add po ect h osts, a line, and a wall. d Rename th object to Fin Line via th Inspector pa or by right-clicking the o he nish he anel object and sele ectingRename. Set the Transfo Position to 0,0,0. orm o

To create t first post, se the elect GameObj ject\Create Ot ther\Cylinder. Rename it to P Post1. Set the T Transform Scal to le 1,3,1. Set t Transform Position to -10 the 0,0,20 to put it in front of the player and to t left. Using the Move Too the ol, adjust the y position so th the bottom of the cylinder object is just a little below t ground. hat r the Hint: View the scene fro the z-axis to help you mak the adjustme w om o ke ents.

Drag the P Post1 GameObj and place i under the Fin Line Gam ject it nish meObject to set the latter as th parent for P t he Post1.

To create a second post, select Post1, ri s ight-click and s select Copy. R Right-click once more and sele Paste. Rena e ect ame the new Ga ameObject from Post1 to Pos Using the M m st2. Move Tool, ad djust the x position so that the post is to the right e of the play yer. Hint: View the scene fro the y-axis (f w om from above) to help you mak adjustments. Alternatively, setting the o ke , Transform x position to 10 should do th trick. 1 he

Next, creat the wall that helps you dete when the fi te t ect inish line is cro ossed. Select G GameObject\Cr reate Other\Cub and rename it to Goal. Set the Transform Scale to 24,10 be m 0,0.5. Set the in nitial Transform Position to 0 m 0,2,0.

Move the w to just beh wall hind the two po osts. If you nee to, adjust the x scale value so the wall str ed e e retches from on ne post to the other.

With the w still selecte open the In wall ed, nspector\Box C Collider compo onent and check the Is Trigge value. Unche k er eck the Mesh R Renderer comp ponent to make the wall invis e sible.

Drag the G Goal GameObje and place it under the Fin Line Gam ect t nish meObject to par the object. rent

Connect the Dots


Next youll create the line connecting the posts so that the player can clearly see the finish line. Youll do this by drawing a line from one post to the other via script. Select Asset\Create\JavaScript to create the new script and name it FinishLineRender. Open the script by doubleclicking it in the Project View. Delete the stubbed out functions and add the following code:
// The finish line posts var post1 : Transform; var post2 : Transform; var lineColor : Color = Color.green; function Start () { // Set the visual for the finish line posts var lineRenderer : LineRenderer = gameObject.AddComponent(LineRenderer); lineRenderer.SetPosition(0, post1.position); lineRenderer.SetPosition(1, post2.position); lineRenderer.material = new Material (Shader.Find("Particles/Additive")); lineRenderer.SetColors(lineColor, lineColor); }

The LineRenderer class allows you to draw lines in 3D space. Given an array of points, you can use the Line Renderer component (Components\Effects\Line Renderer) to draw straight lines. You could have added the Line Renderer component to the Finish Line object and hard-coded the transform positions for Post1 and Post2, but its easier to create the Line Renderer through code. Thats what youre doing here. You draw the line in the Start() function, as it only needs to happen once. First you add the LineRendererscript interface component, then you set the first and second points for the line to the values from the variable inputs that will be tied to the two posts. You set the material for the renderer. Finally, you set the color for the start and end of the line. The line color variable is made public so you can change it. Attach the FinishLineRender script component to the Finish Line GameObject. Hint: You can add the script to the GameObject by selecting the Finish Line object and then tapping the Add Component button in the Inspector. This should bring up a search box simply type the first few letters of the word FinishLineRender and it should show you the script.

Assign the Post1 and Pos GameObjec to the Post 1 and Post 2 v st2 cts variables, respe ectively.

Preview th game in the Unity Editor. Y should see two goal post and a green l across them indicating th he U You e ts line m he finish line. Stop the game e.

Next youl create a new script that dete the finish l crossing event, and will attach this new script to ll ects line w the Goal G GameObject. To do this, selec Assets\Creat o ct te\JavaScript a name the scriptFinishLin and neDetection. Open the n script and delete the stub new bbed out functio Add the fo ons. ollowing code: :
function O OnTriggerEnt ter(other : C Collider) {

if (other.gameObject.tag == "Player") { Debug.Log("You made it!!!"); } } @script RequireComponent(Collider)

You call the OnTriggerEnter() function whenever another collider enters the GameObject. The GameObject needs to be set up as a trigger for the event to fire (which youve already done for the Goal object). The player GameObject has a Character Controller component that is a Collider. So when the player runs into the Goal GameObject, the OnTriggerEnter() event is fired. In your code, you check if the GameObject that entered the Goal has a tag named Player. If thats the case, the Heroic Cube has crossed the finish line. Attach the FinishLineDetection script to the Goal GameObject. Hint: With the Goal object selected in the Hierarchy View, you can drag the FinishLineDetectionscript from the Project View to the Inspector\Add Component button to attach the script component to the GameObject. Before you tag the player, give the player GameObject a name other than plain old cube. To keep things consistent, rename the Cube GameObject to Player.

Now, add a tag to the player object to enable the finish line detection logic. In the Inspector for the player, drop down the Tag selection and choose Player.

Player is on of the pre-b ne built tags availa able. Later on, youll create y your own tags t help identify all enemies in the to y n game. Click Play and move the Heroic Cube p the goal lin You should see a You m past ne. d made it!!! log m message letting you g know that the player cros ssed the finish line.

Yes, the Heroic Cube can get to the goa line and win the game, but you cant let it off so easy. Y n al Youll add two levels of co omplexity to th game: a time he e-based challen and obstac nge cles. First, lets add the obstac s cles.

Create the Launc cher


Create an e empty GameOb bject and add i to the scene. Name it Laun it ncher. This represents the evil block empire thats e launching o obstacles to pu a stop to the Heroic Cubes advances. ut s Using the M Move Tool, pla the launche object in bet ace er tween the player and the finis line in the z direction and above sh the player. You can start with a Transfo Position of 0,12,8 and tw orm f weak it as neces ssary.

The main r reason for the launchers exis l stence is to laun obstacles, so you need to give it some t launch! nch o to Ammunitio is typically created in Uni by designing GameObject and then crea on ity g ts ating Prefabs th can be hat instantiated in the scene, as required, du d uring gameplay Youll create an Obstacle G y. e GameObject, t turn it into a Pr refab, and then le the Launcher take care of la et r aunching it ont the hapless p to player.

Create the Obstac cles


Create a cu GameObje and name it Obstacle. Set the Transform Scale to 2,2,2 so its bigger than the player and ube ect m 2 r hence more intimidating. These are cub that have go to the Dark Side. :] bes one k Give the ob bstacle an inter resting look ot ther than the de efault grey mat tter. To match t completed sample, first im the mport a material from the Chara acter Controlle package: sele Assets\Imp Package\C er ect port Character Controller, then se elect the constru uctor_done ma aterial and the r relevant textur as shown in the image bel res n low, and finally click Import. y

The new m material should show up in yo Project View. our

Select the O Obstacle GameObject. Chang the render m ge material by mo odifying the Ins spector\Mesh Renderer\M Materials\Elem ment 0 propert Click on the circular icon n to the pro ty. e next operty to bring up the Select Material di ialog.

Select the constructor_done material yo just imported. Close the Se o ou e elect Material dialog.

Now you must tag the Obstacle GameObject so that later on you can take care of clearing out Obstacleinstances of the scene when a new game is started. For this, create a new tag named Enemy. Click on Inspector\Tag\Add Tag. The TagManager will show up in the right side panel. Expand the Tags array by clicking on the triangle next to the Tags label). Set the value of Element 0 to Enemy.

Select the Obstacle GameObject and tag the object with the new Enemy tag.

When Obstacle is instantiated, the code youll add will expect a Rigidbody component to be attached to the obstacle. Set that up by adding a Rigidbody. Select Component\Physics\Rigidbody (with Obstacle still selected):

Click on the Assets folder in the Project View. Create a Prefab of your obstacle by selectingAssets\Create\Prefab. The Project View should show an empty Prefab. Name it Obstacle.

Note: If you have larger asset icons than in the screenshot above and wonder how you can get the list view of asset items, simply slide the slider below the asset list all the way to the left. :] Drag the Obstacle GameObject into this new Prefab.

The Prefab changes to a blue color to indicate that it has been assigned. Now that youve created the Prefab as a reusable asset, you no longer need it in the scene. The launcher will take care of instantiating an Obstacle instance when needed. In the Hierarchy View, select theObstacle GameObject, right-click and select Delete.

Release the Krak Err, Obstacles


Next, complete the process by creating logic through a script to launch obstacles. Create a new script asset and name it ObstacleLauncher. Hint: You can also right-click in the Project View and select Create\JavaScript to create a script. Open the new script and replace the stub functions with the following code:
var var var var var projectile : Rigidbody; speed = 5; maxObstacles = 2; launchInterval : float = 5.0; target : Transform;

private var nextLaunch : float = 0.0; private var numObstaclesLaunched = 0; function Start () {

if (target == null) { // Find the player transform target = GameObject.FindGameObjectWithTag("Player").transform; } } function Update () { if ((numObstaclesLaunched < maxObstacles) && (Time.time > nextLaunch)) { // Set up the next launch time nextLaunch = Time.time + launchInterval; // Set up for launch direction var hit : RaycastHit; var ray : Ray; var hitDistance : float;

// Instantiate the projectile var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.position, transform.rota // Simple block, try to get in front of the player instantiatedProjectile.velocity = target.TransformDirection(Vector3.forward * speed); // Increment the launch count numObstaclesLaunched++; } }

The launcher is programmed to launch a certain number of obstacles just in front of the player. It therefore needs an input that represents the player. Previously, when assigning GameObjects to script, youve done so by dragging the GameObject to the script variable using the Editor. The Start() function code shows another way to do this. In Start(), a check is made to see if there is no target assigned. If no target is found, the code looks for a GameObject with the Player tag and assigns this GameObject to the target variable. The GameObject.FindGameObjectWithTag() function call is typically an expensive call, as it needs to look through all GameObjects. So youll want to call this in Start() (which gets called once) and avoid putting it in, say, Update() (which gets called multiple times). In the code, Update() first checks if the Launcher has sent out the maximum obstacles allowed. If not, it also checks if a set time interval has passed. This is to avoid launching too many obstacles within a short amount of time. If its time to launch another obstacle, then the Obstacle Prefab is instantiated at the position and rotation corresponding to the Launcher. The instantiated obstacle is then launched in a direction that matches the players forward direction, so as to land just in front of the player. Now save your code and tie up loose ends. First, attach the ObstacleLauncher script to the LauncherGameObject. Assign the Obstacle Prefab to the projectile variable in the script (you can drag the Prefab from the Assets list to the variable). Assign the Player GameObject to the target variable in the script.

Play the ga in the Unit Editor and v ame ty verify that the b blocks are laun nched in front o the Heroic C of Cube as it move es around. Ad djust the launch hers position s that the bloc are launche in between t player and the finish line. You so cks ed the . can also ad djust the finish line by movin the Finish L ng Line GameObje in the z dire ect ection, away fr rom the player. . Hint: You can set the Tra ansform Position to 0,0,2. When you move the Finish Lin object, the c ne child objects co ome along for th ride, which is one perk of parenting or g he f grouping related GameObject d ts.

You have m of the gam functionalit working now Next youll pull everythin together with a mission con most me ty w. ng h ntrol script that displays the ga timer, coordinates the ga ame ameplay and re esets the scene to start a new g game.

The Fin Countd nal down


Create a ne script asset and name it G ew GameController. Open the scr ript, delete the stub functions and add the s following c code:
static var gameRunni ing : boolea = true; an

var gameTimeAllowed : float = 20.0; private private private private var var var var gameMessageLabel = ""; gameMessageDisplay : Rect; timedOut : boolean = false; gameTimeRemaining : float = gameTimeAllowed;

function Awake() { gameMessageDisplay = Rect(10, 10, Screen.width - 20, 40); } function OnGUI() { GUI.color = Color.yellow; GUI.backgroundColor = Color.black;

var text : String = ""; if (timedOut) { gameMessageLabel = "Time's up!!"; } else { text = String.Format( "{0:00}:{1:00}", parseInt( gameTimeRemaining / 60.0 ), parseInt( gameTimeRemaini gameMessageLabel = "Time left: " + text; } GUI.Box(gameMessageDisplay, gameMessageLabel); } function Update() { if (!gameRunning) return; // Keep track of time and display a countdown gameTimeRemaining -= Time.deltaTime; if (gameTimeRemaining <= 0) { timedOut = true; gameRunning = false; } }

Unity provides GUI controls that make it easy to add text labels and button functionality. ThegameMessageDisplay variable controls where the display is shown. Here you set up the countdown timer to display across the top of the screen. OnGUI() is called when an event occurs such as a mouse click, or at least once a frame. GUI.Box() creates a Box Control using the dimensions you set up initially and with the current game message, which consists of the countdown time info, a success message or a failure message. The gameTimeAllowed variable represents the game timer and is set to 20 seconds. ThegameTimeRemaining variable tracks the currently remaining time. It is initially set to thegameTimeAllowed value and is decremented by Time.deltaTime in Update(). Time.deltaTime is the time in seconds that the last frame took to complete. Keep in mind that the frame rate may vary and so this value may also vary. When the gameTimeRemaining value is below zero, thetimedOut flag is set to true and the player is shown a timeout message. The code also sets up a gameRunning flag to track if you guessed it the game is running. This is useful to stop the countdown logic and youll use it later on to control object behavior when the game is not running.

Attach the script to your Main Camera object:

Play the game and dawdle around until time runs out in order to test the countdown display and the failure case. Its a little hard to see, but dont worry, youll change that soon. Stop the game.

Sometimes You Win, Sometimes You Lose


You should display a success message when the Heroic Cube crosses the finish line, or rather the invisible wall it deserves some encouragement for finishing the challenge! The message will include the time it took to complete the challenge. You should also let the player know when times up! The best place to set these messages is the GameController script. However, the finish line detection code is in another script: FinishLineDetection. One way you can handle this is to define a function in GameController that the FinishLineDetection script can call when the player crosses the line. This function can then trigger the desired message display via theOnGUI() function. Add two private variables to the GameController script. One will track the time to complete the challenge and the other will flag a successful mission (the following code can go below the other existing private variables):

private var missionCompleted : boolean = false; private var missionCompleteTime : float = gameTimeAllowed;

Then add the following code to the end of the GameController script:
function MissionComplete() { if (!gameRunning) return; missionCompleted = true; gameRunning = false; missionCompleteTime = } gameTimeAllowed - gameTimeRemaining;

MissionComplete() checks if the game is running. If it is, it sets a private missionCompleted flag to true and the gameRunning flag to false. The time it took to complete the mission is then saved. Now modify OnGUI() and add the success case (as shown below) to show the time it took to complete the message. The new code goes just after the var text : String = ; line and alters the existing if condition:

if (missionCompleted) { text = String.Format( "{0:00}:{1:00}", parseInt( missionCompleteTime / 60.0 ), parseInt( missionComple gameMessageLabel = "Mission completed in: " + text; } else if (timedOut) { gameMessageLabel = "Time's up!!"; ...

Switch to the FinishLineDetection script and modify it as follows (the additions are marked with comments):
#pragma strict var gameControllerScript : GameController; // 1: new function OnTriggerEnter(other : Collider) { if (other.gameObject.tag == "Player") { Debug.Log("You made it!!!"); gameControllerScript.MissionComplete(); // 2: new } } @script RequireComponent(Collider)

The new code is numbered and does the following: 1. 2. Defines a public variable that points to the GameController script. Youll assign this shortly. Calls MissionComplete() in the GameController script to trigger the success case.

To assign the gameControllerScript variable, select the Goal GameObject, then select Inspector\Finish Line Detection and click the circular icon next to the Game Controller Script. In the pop-up dialog, select the Main Camera GameObject and close the dialog.

Play the ga and dash to the finish lin dodging tho nefarious blocks. Check that the correct message is ame t ne, ose h displayed w when you mak it in time. ke

Stop the game and click Play once more. Test the failure case to make sure that that logic still works.

Transformer-ing the Display Font


You may have noticed, particularly if you have tested the game using Unity Remote or your iOS device, that the font displaying the game messages is very small. This is as good an excuse as any to learn about importing fonts into Unity. There are a wealth of fonts you can get from sites such as http://dafont.com. The sample youre going to use was built with the free Transformers Font. Yes, its the original font from the Transformers movie! Maybe your Cube and blocks are hiding alternate personalities. :] I added the above font (and a few other resources youll need later) to a Resources.zip file that you canhere. Download the resource archive and extract its contents. Find the font file and drag the Transformers Movie.ttf into your Project View\Assets folder to import it. Select the Transformers Movie asset in the Project View. The Inspector shows the import settings. Change the Font Size setting to 36. Click Apply.

Youve just imported your custom font and its ready for use in your project. Open the GameController script to modify the message font. Define a public variable to set the font:
var gameMessageFont : Font;

Change the font used for display labels by modifying OnGUI(), as shown below:
function OnGUI() { GUI.skin.font = gameMessageFont; GUI.color = Color.yellow; ...

You assign the gameMessageFont public variable to GUI.skin.font to change the font. Now select the Main Camera GameObject. Assign gameMessageFont to your newly imported font by dragging the font asset into the gameMessageFont variable.

Preview the game and verify that the messages are displayed using the new font.

Ah, much better!

Its Always Play Time!


Next, create an in-game button that will control the start of the game and allow the player to restart after a success or failure. Youll display the button whenever the game is not running. Recall that you defined agameRunning flag that you can use to control the buttons visibility. To create the play button and related functionality, you must modify the GameController script. First define a private variable that controls the play button text:
private var playButtonText = "Play";

Then add a new function called startGame() that sets up a new game:
function startGame() { // Reset if starting a new game gameTimeRemaining = gameTimeAllowed; timedOut = false; missionCompleted = false; // Change button text after the initial run playButtonText = "Play Again"; // Kick off the game gameRunning = true; }

Now modify OnGUI() to show the button when the game is not running by adding the following code to the end of OnGUI() (after all the existing code):
// The menu button if (!gameRunning) { var xPos = Screen.width / 2 - 100; var yPos = Screen.height / 2 + 100; if( GUI.Button( new Rect( xPos, yPos, 200, 50 ), playButtonText ) ) { startGame(); } }

Finally, set the gameRunning flag to false. Just modify the existing line for the variable to switch the initial value from true to false:
static var gameRunning : boolean = false;

OnGUI() places a button using the GUI.Button() function. The button text is a variable, so it says Play initially and Play Again every subsequent time. GUI.Button() is wrapped in an if statement. This returns true if the button is clicked. When the user clicks the button, you kick off the game. startGame() first initializes the game, changes the play button text and finally sets the gameRunning flag to true. Preview the game in the Unity Editor. Verify that the play button is initially visible and is hidden after you click on it. Verify also that when a run is completed, the play button becomes visible once again and that the text has changed from Play to Play Again. Note that each time you click on the play button after the first time, the time is reset and the countdown starts afresh. But also notice that the player can move even before the play button is tapped. Thats a little annoying, isnt it? Dont let your Heroic Cube get a head start!

To take care of that detail, make use of the gameRunning variable, which is a global variable by virtue of the static modifier. Add the following code to the top of Update() in the MoveAround script:
if (GameController != null && !GameController.gameRunning) return;

You should also disable the launcher from dropping obstacles when the game is not running. Add the following code at the top of Update() in the ObstacleLauncher script:
if (GameController != null && !GameController.gameRunning) return;

Preview the game to ensure that when the game is not running, the player cant move and obstacles are not launched.

Every Cube Deserves a Fresh Start


While the play button works correctly now, you may notice that even though the timer is reset when a new game is started, other aspects of the game are not reset. The obstacles stop falling, as theyve probably reached the maximum spawn count, but they dont disappear. Nor does the Heroic Cube revert back to its original position. A true reset requires that the game start fresh, i.e., the obstacles are cleared and reloaded and the player position is reset. The ideal way to accomplish this is to send a message to all interested parties to reset themselves. The Heroic Cube would then slink back to its original position and the launcher would reload. One way to do this is to have a reset function defined in a script that handles the reset behavior.GameObject.SendMessage() can then be used to call this reset function in the hope that a component (a script) attached to the GameObject handles the function call. Heres how youll implement this: 1. 2. 3. 4. Youll define a function called resetGame() in the MoveAround script that resets the players position to the original position when the game started. Youll define a function called resetGame() in the ObstacleLauncher script to reset the obstacle count to zero. Youll loop through a given list of GameObjects that include the player and launcher GameObjects, calling GameObject.SendMessage(resetGame, ) to initiate the reset. Youll add the reset logic in GameController when the user resets the game. But code speaks louder than words. First, open the MoveAround script and add the following variables and functions to it:
var originalPosition : Vector3; var originalRotation : Quaternion; function Awake() { originalPosition = transform.position; originalRotation = transform.rotation; } function resetGame() { // Reset to original position transform.position = originalPosition; transform.rotation = originalRotation; }

Then open the ObstacleLauncher script and add this new function:
function resetGame() { // Reset to original data numObstaclesLaunched = 0; }

Next open the GameController script and add the following variable:
var gameObjectsToReset : GameObject [];

The above line defines an array of GameObjects that will have the resetGame function called on them to initiate a reset. Now replace the existing startGame() function with the following (or just update the code to match):
function startGame() { // Reset if starting a new game gameTimeRemaining = gameTimeAllowed; timedOut = false; missionCompleted = false; // Change button text after the initial run playButtonText = "Play Again"; // Clean out any enemy objects var enemies = GameObject.FindGameObjectsWithTag("Enemy"); for (var enemy : GameObject in enemies) { Destroy ( enemy); } // Call all game reset methods for (var gameObjectReceiver : GameObject in gameObjectsToReset) { gameObjectReceiver.SendMessage("resetGame", null, SendMessageOptions.DontRequireReceiver); } // Kick off the game gameRunning = true; }

The new code clears out all enemy instances by looking for GameObjects with the Enemy tag. Destroy() is called on the enemy GameObjects. This clears out the obstacles in the scene. Then the code processes the gameObjectsToReset array and sends a message to each GameObject to callresetGame(). It is not mandatory for a component in the array to have implemented resetGame(). You need to assign the objects to process. Now select the Main Camera object and note the new public variable for Game Objects To Reset:

Set the Size to 2. The array elements will expand. Assign the Player GameObject to Element 0 and theLauncher GameObject to Element 1.

Preview the game and verify that the game fully resets itself after a success or failure. Verify that the player position resets to the original one, that the obstacles are cleared, and that the obstacles start falling once more when the game is restarted.

This Message Wont Self-Destruct


Your basic gameplay functionality is now complete, but it would be a nice additional touch to show some info about the game when its first launched. All youre currently showing is a play button. The user doesnt know what theyre in for. Adding some welcome text and a super-short explanation of what the games about will make it a lot more userfriendly. :] The welcome text will use the Transformers font you imported. For the description text, youll use the Arial font that is bundled with Unity. Create an empty game object, name it Intro and set the Transform Position to 0,0,0. Select GameObject\Create Other\3D Text to create a 3D Text GameObject and name it Description Text. Set the Inspector\Text Mesh\Text property to Get to the finish line before time runs out. Set the initial Transform Position to -10,1,12.

Preview th game with th Unity Editor and adjust the position of th object so tha its horizonta centered a he he r e he at ally and you can see it clearly. Hint: Youll likely have to play around with the x and z positions: x to center to ob d d bject, and z to zoom in and o out.

Check out the game with Unity Remote as well and m h e make sure the te is visible w ext when viewed on an iOS device. n Make any n necessary adju ustments. Place the D Description Tex object under the Intro Gam ext r meObject. You doing this so you can late show or hide the ure er e menu displ info easily via code. lay

Create a se econd 3D Text GameObject a name it We and elcome Text. T text should appear above the descriptio This d e on text, so set the initial Tran t nsform Positio to -6,5,10. S the Inspecto on Set or\Text Mesh\T Textproperty to Welcome. o Set the Fon property to Transformers Movie by drag nt gging that font asset from the Project View and into the Fo e ont property in the Inspector (or by tapping the circle with a dot icon ne to Font and selecting it fro the pop-up list): n g h ext om

Adjust the position of We elcome Text so that you can see it clearly when you test the game on both the Unity Editor o h o d and throug Unity Remote. gh

Place the Welcome Text object under the Intro GameObject. You want to hide the Intro GameObject (and its child objects) when the game is running. Open theGameController script and make the following changes:
var intro : Transform; ... function startGame() { ... // Turn off the intro text for (var child : Transform in intro ) { child.gameObject.renderer.enabled = false; } // Clean out any enemy objects ...

Here you add a new public variable to get a handle to the Intro GameObject. Then you modify startGame()to make the Intro object invisible by turning off the renderers for its child GameObjects. Now set the Intro variable by selecting Main Camera and dragging the Intro GameObject from the Hierarchy View to the Inspector\Game Controller\Intro variable to assign it. Or use the circle dot icon, since its easier. :]

Preview the game to test that the text is hidden when the play button is clicked and the game begins.

Every Brave Cube Deserves a Soundtrack


Audio plays a big part in the gaming experience, both by providing sensory feedback and creating mood. Youll add audio to further enrich the gameplay. Sound effects will be triggered when the player crosses the line in time, fails their mission, or when an obstacle hits the ground or bumps into anything. And of course, the game must have some background music! :] Adding audio with Unity involves attaching an Audio Source component to a GameObject. The Audio Source component has an Audio Clip property that you can assign to the sound you wish to play. The component has additional properties that can control when the clip should be played and whether it should loop. The supported audio file formats include .AIF, .WAV, .MP3, and .OGG. The following two sites provided the royalty-free music thats used in this tutorial: http://incompetech.com/ http://freesound.org/ (registration required to download sounds)

The Resources.zip file you downloaded earlier contains all the audio files that youll be using. Feel free to create your own audio effects instead of using the ones Ive provided. :] For your reference (and for the sake of attribution), the original links to the audio files included in the Resources.zip file are as follows:

victory: 20784__wanna73__crowd-cheering-football-01.wav defeat: 83916__timbre__benboncan-sad-trombone-tweaked.wav impact: 30668__hardpcm__hardbassdrum002.wav background: Gustav Sting.mp3

Do note though that the files in the Resources.zip file have been renamed for the sake of clarity and brevity. Go to the folder where you originally extracted Resources.zip and import the audio files by dragging them into your Project View\Assets folder.

When an audio file is imported into Unity, you can specify whether it should be compressed or remain as-is, i.e., native. (But note that MP3 and Ogg Vorbis audio are always imported in the compressed format.) Why does this matter? Compressed files tend to be smaller, but they need to be decompressed as the game runs, taking up CPU cycles. You generally want to compress background music. For short sound effects, native is better and tends to provide better sound quality. If the audio format is compressed, you can choose whether to handle the decompression using hardware, e.g., Apples hardware codec if running on an iOS device. Hardware is faster, but the hardware can handle one compressed music file at a time. You can also mark sounds as 3D. This means that when the sound is played, the effect will be relative to the 3D position of the GameObject. For example, if the GameObject is far away, the sound will be quieter.

Select the background audio in the Project View to show the Import Settings. Unselect the 3D Sound option. Select Hardware decoding. Click Apply to save the setting changes. The other audio files are .WAV files and you do not need to modify the default Import settings, which should be set to 3D and native audio format. For sounds to be heard, your scene needs an Audio Listener component to be added to a GameObject. There can only be one Audio Listener in the scene. The listener will pick up sounds from the audio sources close to it and send it to the device speaker. By default, an Audio Listener is attached to the Main Camera. You can leave it there or attach it to a different GameObject: the player, for example. In this game, youll keep the Audio Listener on the Main Camera, but you can experiment with the different options when you build your own games.

The Sounds of Victory and Defeat


Youre going to attach audio to the Goal GameObject that simulates a crowd cheering or jeering at the finish line. Select the Goal GameObject in the Hierarchy View and add an audio source by selectingComponent\Audio\Audio Source. Set the victory audio asset to the Inspector\Audio Source\Audio Clip property. De-select the Play on Awake option.

Now create a new JavaScript asset that will be used to play either a victory sound or a defeat sound. Name the new script FanReaction. Open the new script, remove the stub functions and add the following code:
var var var var audioVictory : AudioClip; audioDefeat : AudioClip; volumeVictory : float = 2.0; volumeDefeat : float = 2.0;

function playSoundOfVictory(isVictory : boolean) { // Stop any current audio if (audio.isPlaying) audio.Stop(); // Play either the sound of victory or defeat. audio.clip = isVictory ? audioVictory : audioDefeat; audio.volume = isVictory ? volumeVictory : volumeDefeat; audio.Play(); } function resetGame() { // Reset to original state, stop any audio if (audio.isPlaying) audio.Stop(); } @script RequireComponent(AudioSource)

The script takes in two audio clips, one for victory and one for defeat. The playSoundOfVictory() function first stops any audio thats currently playing, then plays the required audio based on the isVictory input. The resetGame() function stops any audio thats playing. Youll shortly wire up the GameController to callresetGame() every time the game is restarted. Attach this new script to the Goal GameObject. Set the victory audio asset to the Audio Victory variable. Set the defeat audio asset to the Audio Defeat variable.

Edit the GameController script and make the following changes:


var fanReactionScript : FanReaction; ... function Update() { if (!gameRunning) return; // Keep track of time and display a countdown gameTimeRemaining -= Time.deltaTime; if (gameTimeRemaining <= 0) { timedOut = true; gameRunning = false; // Play the sound of defeat fanReactionScript.playSoundOfVictory(false); } } ... function MissionComplete() { if (!gameRunning) return; missionCompleted = true; gameRunning = false; // Play the sound of victory fanReactionScript.playSoundOfVictory(true); missionCompleteTime = } gameTimeAllowed - gameTimeRemaining;

The code defines a new public variable that references the FanReaction script. You modifyMissionComplete() to call playSoundOfVictory(), passing in true to play the victory sound. You also modify Update() to call playSoundOfVictory(), passing in false to play the defeat sound. You can now link the FanReaction script in the Goal GameObject with the variable in the Main CamerasGameController script component. Select Main Camera and then click on the circular icon next to the fanReactionScript variable under the GameController component in the Inspector. In the dialog that pops up, select the Goal GameObject, then close the pop-up.

To call resetGame() in FanReaction, select the Main Camera Object. In the Game Controllercomponent section in the Inspector, increase the Game Objects To Reset array size from 2 to 3. Set theGoal GameObject to Element 2.

Preview the game and test out the victory and defeat scenarios to make sure the game plays the correct sounds. Verify that the sounds are stopped when you hit Play Again.

Thud in 3D
It would also be nice to have some sort of a sound when obstacles hit the ground. To achieve this, youll attach an audio source to the Obstacle Prefab, then detect collisions so you can play the impact audio when the obstacles fall or bump into anything. Add an Audio Source component to the Obstacle Prefab. Assign the impact audio to the Audio Clipproperty.

Create a new JavaScript asset and rename it to ObjectCollision. Edit the script, delete the stubbed functions and add the following code:
var impact : AudioClip; function OnCollisionEnter () { audio.PlayOneShot(impact); } @script RequireComponent(AudioSource)

The code implements the predefined OnCollisionEnter() event function and calls the audio.PlayOneShot()function to play the impact audio clip. audio.PlayOneShot() illustrates another way to play audio, allowing you to pass in the audio you wish to play. Attach the script to the Obstacle Prefab. Set the impact audio asset to the Impact variable in the script.

Preview the game and verify that you hear a pleasing thud sound when obstacles hit the ground or another object. Note that closer the obstacles are to the player, the louder the sounds.

A Little Cube Music


Your games almost complete. But theres one thing missing some background tunes.

Music does a lot to set the mood for a game. It can get a users adrenaline flowing and help them feel the game environment by providing contextual clues like bird sounds or wolves howling. So add some music! Add an Audio Source component to the Main Camera GameObject. Set the background audio asset to the Audio Clip property. Select the Play on Awake and the Loop options. These ensure that the background music starts as soon as the game starts and that it will play continuously. Adjust the volume property to 0.1 so it doesnt drown out the other sounds. If youre using your own sounds, tweak the volume level depending on your musics default volume level to achieve the same goal. Users should be able to hear all the sound effects while the background music is playing.

Preview the project in the Unity Editor. When completely satisfied, deploy the project to your iOS device. Youll need to add the Level_3 scene in the Build Settings.

Test out the gameplay on your iOs device while you enjoy the sounds youve adde h n i d ed.

Your Hero Cube has a soundtrack to g oic glorify its brav very!

Where To Go Fro Here? om


Congratula ations, youve made it to the end of this whi m irlwind walkth hrough of the basics of Unity! Youve show as ! wn much verv and vigor as your Heroic L ve Little Cube. Thi could be the beginning of a wonderful jou is urney with Unity gaming. Here are th source files with all of the code from this tutorial series <="" a="" sty he s s: yle="margin: 0 0px; padding: 0 0px; border: 0px outline: 0px font-weight: inherit; font-st x; x; tyle: inherit; fo ont-size: 13px; font-family: in nherit; vertical-align: baseline; color: rgb(0, 10 55); ">Unity Project, Xcode Project. 04, y Believe it o not, youve just scratched the surface th or j heres a whole lot more to learn. Stay tuned for an upcom e d ming intermedia tutorial serie that will tak you to the ne level with U ate es ke ext Unity! In the mean ntime, be sure to stop by the forums with your questions a feedback, and have fun b and building aweso ome games!

You might also like