0:00:00.000,0:00:04.295 In Unity 4.3 we're launching our first set of 2D features. 0:00:04.295,0:00:06.295 To compliment this we have constructed a 0:00:06.295,0:00:08.295 demo project with these tools. 0:00:08.295,0:00:11.527 Our 2D platformer is nicknamed 'Tower Bridge Defence' 0:00:11.527,0:00:13.776 It depicts London's Tower Bridge in the midst 0:00:13.776,0:00:15.556 of an alien invasion. 0:00:15.556,0:00:17.955 It's a completely sprite-based, physics driven 0:00:17.955,0:00:20.216 2D sample level that we hope will help you 0:00:20.216,0:00:23.472 understand how 2D games are put together in Unity. 0:00:23.472,0:00:25.472 This video will discuss the background and 0:00:25.472,0:00:28.184 foreground construction, characters, effects, 0:00:28.184,0:00:30.184 camera tracking, animation and scripting 0:00:30.184,0:00:31.639 used in the demo. 0:00:31.639,0:00:33.639 To begin with, let's discuss the basics 0:00:33.653,0:00:36.139 of working in 2D in Unity. 0:00:36.860,0:00:39.291 Firstly, when working in 2D, you should set the 0:00:39.291,0:00:41.221 Editor Behaviour Mode to 2D 0:00:41.221,0:00:43.040 for various settings. 0:00:43.040,0:00:45.040 This can be done when making a new project 0:00:45.040,0:00:47.040 using the drop-down on the project wizard 0:00:47.040,0:00:49.543 or during a project by choosing 0:00:49.543,0:00:53.172 Edit - Project Settings - Editor from the top menu. 0:00:53.172,0:00:55.172 This means that by default textures 0:00:55.172,0:00:57.172 will be imported as sprites and the 0:00:57.172,0:00:59.630 Scene View will default to 2D mode. 0:00:59.630,0:01:01.630 This new mode gives you a completely orthographic 0:01:01.630,0:01:04.420 view in which to construct 2D games. 0:01:04.420,0:01:06.806 It also hides the usual 3D gizmo 0:01:06.806,0:01:09.197 in the top right of the view, giving you more space 0:01:09.197,0:01:11.941 to work in. Aside from these settings the work 0:01:11.941,0:01:14.244 flows for 2D have been designed to mirror 0:01:14.244,0:01:17.040 existing Unity approaches to 3D game creation. 0:01:17.040,0:01:19.040 So if you already know a little about Unity 0:01:19.040,0:01:21.040 you'll be in a great position to start making 0:01:21.040,0:01:22.929 2D games right away. 0:01:22.929,0:01:24.929 It's worth noting at this stage that you can 0:01:24.929,0:01:27.219 still mix 2D and 3D in Unity, 0:01:27.219,0:01:29.722 so if you want to add 3D elements to your 2D game 0:01:29.722,0:01:32.870 or vice versa you can do that with no worries. 0:01:33.366,0:01:35.496 Let's take a look at the demo project itself, 0:01:35.496,0:01:38.312 and how we built it up one stage at a time. 0:01:38.812,0:01:40.812 We began by sketching out the level design 0:01:40.812,0:01:42.812 for this sample level and then went about 0:01:42.812,0:01:44.812 recreating the layout in Photoshop. 0:01:45.312,0:01:47.312 Creating and exporting the layers, 0:01:47.312,0:01:49.312 we were able to import these in to Unity 0:01:49.312,0:01:51.312 using the new Sprite type. 0:01:58.373,0:02:01.306 In order to create parallaxing in our background later, 0:02:01.306,0:02:03.666 we kept some of the background elements separate 0:02:03.666,0:02:06.515 and placed them on to a Background Sorting Layer. 0:02:06.515,0:02:09.658 Yet another new feature of 2D development in Unity. 0:02:10.158,0:02:12.841 Having assigned all of our backgrounds to this layer, 0:02:12.841,0:02:15.157 we could then use the Order In Layer property 0:02:15.157,0:02:17.379 of the Sprite Renderer to sort them. 0:02:17.379,0:02:19.379 Once we were happy with their positions 0:02:19.379,0:02:21.379 we could lock the Background Sorting Layer 0:02:21.379,0:02:23.379 so that when we added foreground elements 0:02:23.379,0:02:25.379 we didn't need to worry about accidentally 0:02:25.379,0:02:27.751 dragging background elements around. 0:02:27.751,0:02:29.751 This is done using the Layers pull-down in the 0:02:29.751,0:02:31.751 top right of the interface. 0:02:32.817,0:02:35.531 Because the background elements are purely decorative 0:02:35.531,0:02:37.531 we did not require any additional components 0:02:37.531,0:02:39.531 on the sprite game object. 0:02:39.531,0:02:41.531 They were parented to an empty game object 0:02:41.531,0:02:44.201 that has a simple script to handle parallaxing 0:02:44.201,0:02:46.201 called BackgroundParallax. 0:02:46.201,0:02:48.643 For more information you'll find this script 0:02:48.643,0:02:50.643 fully commented in the Scripts folder. 0:02:54.914,0:02:56.914 Next up came the creation of the foreground elements 0:02:56.914,0:02:59.400 that our characters would actually traverse. 0:02:59.790,0:03:02.280 We designed London's Tower Bridge with a UFO 0:03:02.280,0:03:03.466 landed in the centre. 0:03:03.466,0:03:05.466 The character has the run of the environment 0:03:05.466,0:03:07.466 as enemies spawn from the skies and begin 0:03:07.466,0:03:09.216 to navigate around the level. 0:03:09.216,0:03:11.216 As such, each piece of the foreground required 0:03:11.216,0:03:13.632 a collider for characters to walk upon. 0:03:13.632,0:03:15.632 For most of the environment we used 2D 0:03:15.632,0:03:17.632 box colliders for efficiency, 0:03:17.632,0:03:21.239 but the UFO itself has a more complex shape. 0:03:22.505,0:03:24.505 Unity's Polygon Collider allowed us to 0:03:24.505,0:03:26.878 automate creation of the collider itself 0:03:26.878,0:03:28.724 based on the shape of the sprite. 0:03:28.724,0:03:30.724 It even meant that we could tweak the shape of 0:03:30.724,0:03:32.053 the collider later. 0:03:32.053,0:03:34.164 Moving, adding or subtracting points 0:03:34.164,0:03:36.164 of the collider shape to make it more 0:03:36.164,0:03:38.164 appropriate to walk over. 0:03:38.664,0:03:40.664 To sort these foregrounds we created a 0:03:40.664,0:03:43.154 Foregrounds Sorting Layer, which was drawn 0:03:43.154,0:03:45.599 above the backgrounds in the Tags And Layers manager. 0:03:48.875,0:03:50.875 Next, let's take a look at our hero. 0:03:53.709,0:03:55.598 Our player character was yet again designed 0:03:55.598,0:03:57.598 in Photoshop, and for this demo 0:03:57.598,0:03:59.598 we chose to make a character with independent 0:03:59.598,0:04:01.598 limbs and features in the style of 0:04:01.598,0:04:03.598 2D hits such as Rayman. 0:04:03.598,0:04:05.598 Our other option would have been to design 0:04:05.598,0:04:08.140 a sprite sheet-based animation and design each 0:04:08.140,0:04:09.643 each frame in Photoshop, 0:04:09.643,0:04:12.365 an approach we use later for the background Swan, 0:04:12.365,0:04:14.365 which we'll discuss later in the video. 0:04:15.072,0:04:17.072 Because our character had independent elements 0:04:17.072,0:04:20.196 that we wish to animate we finalised the design 0:04:20.196,0:04:22.196 and then moved his bodily elements in to separate 0:04:22.196,0:04:25.408 spaces on our canvas to allow Unity to isolate them 0:04:25.408,0:04:27.959 as separate sprites in the Importer. 0:04:28.763,0:04:30.763 This meant that we could then arrange all of 0:04:30.763,0:04:33.096 our sprites as separate elements to be animated. 0:04:33.096,0:04:35.495 We placed these on to a new Character Sorting Layer 0:04:35.495,0:04:38.167 that we created, and then used Z values in the 0:04:38.167,0:04:40.921 transform to sort their rendering depth. 0:04:48.811,0:04:50.811 All of these sprites are then arranged under an 0:04:50.811,0:04:52.811 empty game object, which has all of our 0:04:52.811,0:04:56.591 controls scripting, colliders, physics, excetera attached to it. 0:04:56.591,0:04:58.591 Once we'd done this we were able to use the newly 0:04:58.591,0:05:01.041 upgraded Animation window to create 0:05:01.041,0:05:03.906 Idle, Run, Jump, Shoot and Death animations 0:05:03.906,0:05:07.095 by animating each of the character's sprites over time. 0:05:07.095,0:05:09.795 With the new Dopesheet View in the Animation window 0:05:09.795,0:05:11.795 this is easier than ever. 0:05:13.414,0:05:16.006 We simply add animation to the parent object 0:05:16.006,0:05:19.403 and then create keyframes for any of the child objects. 0:05:19.403,0:05:21.403 Moving the playhead to where we want 0:05:21.403,0:05:23.403 and then moving the various parts of the character 0:05:23.403,0:05:25.403 to automatically keyframe the animation. 0:05:27.313,0:05:29.644 The ability to switch between Curve and Dopesheet 0:05:29.644,0:05:32.448 representation of our animation makes it easier than 0:05:32.448,0:05:35.064 ever to adjust timing and design. 0:05:36.730,0:05:38.730 With these animations created we can 0:05:38.730,0:05:41.370 then design a state machine for our character 0:05:41.370,0:05:43.801 so that when called upon in code, differing animations 0:05:43.801,0:05:45.277 could be played. 0:05:45.277,0:05:47.277 the animator controller for the character is 0:05:47.277,0:05:50.574 not driving a 3D biped, so we simply deselect 0:05:50.574,0:05:53.673 Apply Root Motion and select Animate Physics 0:05:53.673,0:05:55.673 in order to drive our animations in time with 0:05:55.673,0:05:57.287 the physics engine. 0:05:57.287,0:05:59.858 In order to traverse the environment our hero has a 0:05:59.858,0:06:02.231 circle collider at his feet and a box collider 0:06:02.231,0:06:04.564 to cover the rest of his body outline. 0:06:04.564,0:06:07.067 This means he can smoothly walk up and down hills 0:06:07.067,0:06:09.454 and when he jumps his head will hit the ceiling. 0:06:09.802,0:06:12.537 In order to control the character and it's animations 0:06:12.537,0:06:16.038 we wrote a script that moves him via 2D physics forces. 0:06:16.038,0:06:18.038 This means that we can apply physics to him 0:06:18.038,0:06:20.038 and the enemies during the game for more 0:06:20.038,0:06:21.427 dynamic game play. 0:06:21.427,0:06:23.814 In our PlayerControl script for the character 0:06:23.814,0:06:25.814 we check for player input. 0:06:25.814,0:06:27.814 We use this to apply physics forces 0:06:27.814,0:06:30.766 for movement and also send the value of the input 0:06:30.766,0:06:33.487 to the animator, which in turn defines which 0:06:33.487,0:06:36.475 animation should be playing and smoothly transitions 0:06:36.475,0:06:38.475 between the different animation clips that 0:06:38.475,0:06:40.475 we've created as states. 0:06:40.475,0:06:42.475 The great thing about using the animator to 0:06:42.475,0:06:44.475 create states from animation clips is 0:06:44.475,0:06:46.861 that we can go and tweak speeds of animation 0:06:46.861,0:06:48.861 to match our physics velocities 0:06:48.861,0:06:51.278 without having to reanimate anything 0:07:23.129,0:07:25.129 The FixedUpdate function evaluates with 0:07:25.129,0:07:27.588 each physics step, and the first thing we 0:07:27.588,0:07:29.588 do with this is to feed the value of Horizontal 0:07:29.588,0:07:32.994 input in to the Speed parameter of our animator. 0:07:33.950,0:07:35.950 The transition between Idle and Run 0:07:35.950,0:07:37.950 in our simple state machine requires 0:07:37.950,0:07:41.718 that the Speed parameter is above 0.1. 0:07:41.718,0:07:44.025 When it is, the animator blends from Idle 0:07:44.025,0:07:46.025 in to the Run state. 0:07:51.857,0:07:53.857 We then go on to add forces to the player's 0:07:53.857,0:07:57.184 2D physics component, the rigidbody2D, 0:07:57.184,0:07:58.822 in order to move him around. 0:07:59.626,0:08:02.521 We also handle which direction the character is facing 0:08:02.521,0:08:04.702 based on the value of Horizontal input, 0:08:04.702,0:08:07.710 checking whether it is above or below 0. 0:08:07.710,0:08:10.557 This is because in Unity, holding the left input key 0:08:10.557,0:08:14.573 returns a value of -1, where right returns positive 1. 0:08:15.073,0:08:18.700 Depending on input, we then call a simple flip function, 0:08:18.700,0:08:21.477 which reverses the X scale of the character, 0:08:21.477,0:08:24.566 giving him the appearance of facing the opposite direction. 0:08:26.848,0:08:28.848 To decide whether the player is grounded 0:08:28.848,0:08:31.605 we added a layer in Unity called Ground 0:08:31.605,0:08:34.982 and applied it to all of our walkable foreground surfaces. 0:08:43.397,0:08:45.969 We then used the Linecast function in 2D 0:08:45.969,0:08:47.969 to check whether something on the Ground layer 0:08:47.969,0:08:50.234 is below the character's feet. 0:08:50.234,0:08:52.777 To customise this more easily we created 0:08:52.777,0:08:54.777 an empty game object to use as a point 0:08:54.777,0:08:56.777 at which to check for the ground. 0:08:56.777,0:08:59.083 By adding a gizmo to this empty object 0:08:59.083,0:09:01.083 we are able to manipulate how far below 0:09:01.083,0:09:03.083 the character we'll check for the ground. 0:09:03.083,0:09:05.486 From a gameplay perspective this means that 0:09:05.486,0:09:07.958 the character can only jump when grounded. 0:09:08.456,0:09:10.456 Check out the rest of the comments in the script for more 0:09:10.456,0:09:12.648 information on the control of the player. 0:09:12.648,0:09:14.648 We will discuss the player's weapon 0:09:14.648,0:09:15.879 later in this video. 0:09:15.879,0:09:17.879 Next, let's take a look at how the camera 0:09:17.879,0:09:19.879 tracks the player in our demo. 0:09:21.291,0:09:24.352 In 2D games, much like 3D, the motion of 0:09:24.352,0:09:26.352 the camera tracking the action can make 0:09:26.352,0:09:27.824 or break your game. 0:09:27.824,0:09:30.581 For a classic 2D platformer, we looked at the mechanics 0:09:30.581,0:09:33.625 of one of the most interesting camera in 2D gaming history, 0:09:33.625,0:09:36.651 the camera from Super Mario World on the Super Nintendo 0:09:36.651,0:09:38.651 or Super Famicom. 0:09:38.651,0:09:40.651 In Super Mario world the camera tracks 0:09:40.651,0:09:42.651 horizontally, but uses a dead zone 0:09:42.651,0:09:45.119 or margin in the centre of the viewport 0:09:45.119,0:09:47.119 in which the character can move a little 0:09:47.119,0:09:49.342 without the camera tracking. 0:09:49.342,0:09:51.635 Once the character moved beyond this margin 0:09:51.635,0:09:54.047 the camera tracks back toward the player. 0:09:54.047,0:09:56.867 The Super Mario World camera used particular heights 0:09:56.867,0:09:59.544 to snap to vertically, but we didn't need this 0:09:59.544,0:10:01.544 kind of detail for our game as we 0:10:01.544,0:10:03.878 do not have a long level in the X axis 0:10:03.878,0:10:06.848 but more of a stage on which the action takes place. 0:10:07.210,0:10:09.210 For this reason our camera employs 0:10:09.210,0:10:12.787 similar tracking vertically as it does horizontally. 0:10:18.779,0:10:20.779 Take a look at the CameraFollow script on the 0:10:20.779,0:10:23.138 mainCamera game object to see comments 0:10:23.138,0:10:25.138 on how it achieves this effect. 0:10:26.135,0:10:27.845 There are several effects in the game, 0:10:27.845,0:10:29.845 but most important is our heroes ability 0:10:29.845,0:10:32.732 to slay the alien onslaught he's faced with. 0:10:32.732,0:10:36.338 Our hero shoots a bazooka which has animated recoil. 0:10:36.338,0:10:38.898 This action is made up of several parts. 0:10:38.898,0:10:41.643 First we listen for key input and when the Fire key is 0:10:41.643,0:10:43.962 pressed we instantiate a rocket, 0:10:43.962,0:10:47.969 play an audio clip and trigger an animation state to play. 0:10:47.969,0:10:49.969 Let's break this down even further. 0:10:49.969,0:10:52.418 in order to play the Shoot animation while other 0:10:52.418,0:10:54.418 animations such as Run are playing we 0:10:54.418,0:10:56.418 created a separate layer within our animator 0:10:56.418,0:10:57.677 called Shooting. 0:10:57.677,0:10:59.677 By setting the Weight property to 1 here 0:10:59.677,0:11:02.532 we can totally override motion in the base layer 0:11:02.532,0:11:04.532 on any parts of our character that are animated 0:11:04.532,0:11:06.980 by clips on the shooting layer. 0:11:20.499,0:11:22.499 In this layer we switch to the Shoot animation 0:11:22.499,0:11:25.351 from any state, when the Shoot trigger 0:11:25.351,0:11:27.351 parameter is called from code. 0:11:27.351,0:11:30.543 Let's take a look at the Gun script in charge of this. 0:11:32.700,0:11:35.140 Here you can see that we address the animator 0:11:35.140,0:11:37.402 and set that trigger to True. 0:11:37.402,0:11:40.513 Triggers simply act as a switch and reset themselves to false 0:11:40.513,0:11:43.247 on the next frame so that they can be called again, 0:11:43.247,0:11:45.511 which is perfect for actions such as shooting. 0:11:46.011,0:11:48.673 In addition to setting the animation we fire the 0:11:48.673,0:11:50.673 rockets themselves from this script, 0:11:50.673,0:11:52.673 playing an audio clip and dependent upon 0:11:52.673,0:11:54.673 the direction that the player is facing 0:11:54.673,0:11:57.775 we instantiate a rocket and give it a velocity 0:11:57.775,0:12:00.555 that's positive or negative in the X axis. 0:12:01.276,0:12:03.933 This script is attached to the Gun empty game object 0:12:03.933,0:12:05.294 in the hero's hierarchy. 0:12:05.294,0:12:08.078 We place code like this on to an empty game object 0:12:08.078,0:12:10.078 as it allows us to easily position 0:12:10.078,0:12:11.663 where the rockets are created. 0:12:11.663,0:12:13.663 We do this by placing the empty object 0:12:13.663,0:12:16.010 at the end of the barrel of the bazooka 0:12:16.010,0:12:18.010 and then we use it's own position as the 0:12:18.010,0:12:20.010 point at which to spawn the rockets. 0:12:40.248,0:12:42.804 The rocket itself has a 2D rigidbody 0:12:42.804,0:12:44.804 and we assign a velocity to that in order 0:12:44.804,0:12:46.804 to make it move. 0:12:46.804,0:12:49.096 It has a sprite swap flame exhaust 0:12:49.096,0:12:51.096 plus a particle system for smoke. 0:12:52.826,0:12:56.482 The particle system also accepts the new sprite type of graphics 0:12:56.482,0:12:58.482 so by adding a sprite sheet of smoke puffs 0:12:58.482,0:13:00.482 to a material we can assign it to the 0:13:00.482,0:13:04.149 texture sheet animation module of the particle system 0:13:04.149,0:13:06.232 and we get instant animation of our 0:13:06.232,0:13:08.232 sprites for the particle emission. 0:13:16.122,0:13:18.935 When our rockets hit an enemy or part of the environment 0:13:18.935,0:13:20.935 the rocket itself is destroyed and 0:13:20.935,0:13:22.935 an explosion is spawned. 0:13:22.935,0:13:24.935 The explosion is simply a sprite game object 0:13:24.935,0:13:27.731 that animates through a sprite sheet that we have created. 0:13:27.731,0:13:30.311 Yet again using sorting layers to render this 0:13:30.311,0:13:33.699 at the lowest layer order of our foreground objects. 0:13:36.174,0:13:38.174 When adding sprite-based animation like this 0:13:38.174,0:13:40.174 we setup the sprites themselves by 0:13:40.174,0:13:42.174 selecting the file in our Project Panel 0:13:42.174,0:13:44.576 and choosing the Sprite Mode Multiple. 0:13:44.576,0:13:46.576 This gives us access to the sprite editor 0:13:46.576,0:13:49.757 which allows us to slice manually or automatically. 0:13:49.757,0:13:52.406 Once happy with the selection of sprites from our file 0:13:52.406,0:13:54.406 we simply hit Apply and Unity 0:13:54.406,0:13:56.765 generates the sprites as children of that file 0:13:56.765,0:13:58.765 to be used in our project. 0:13:59.707,0:14:01.693 So that's our rocket in a nutshell. 0:14:01.693,0:14:03.693 We will discuss the mechanics of killing the enemies 0:14:03.693,0:14:06.533 later in this video in the section about enemies. 0:14:07.102,0:14:09.448 Let's return to the player character now and look at 0:14:09.448,0:14:12.194 how we handle health and taking damage. 0:14:12.194,0:14:14.194 Health is stored as a float and 0:14:14.194,0:14:16.194 with each interaction with a tagged enemy 0:14:16.190,0:14:18.548 we call the TakeDamage function. 0:14:18.548,0:14:20.548 This is only allowed to occur after the 0:14:20.548,0:14:22.548 repeatDamagePeriod has passed 0:14:22.548,0:14:25.347 to avoid the player being killed very quickly. 0:14:26.524,0:14:29.136 To allow the player to escape enemies more easily 0:14:29.136,0:14:31.136 and to show the player that they are being hurt 0:14:31.136,0:14:33.136 we make the act of taking damage 0:14:33.136,0:14:34.847 repel the character physically. 0:14:34.847,0:14:37.540 To achieve this the TakeDamage function briefly 0:14:37.540,0:14:39.540 stops the player from jumping 0:14:39.540,0:14:42.125 and finds a vector from the enemy to the player 0:14:42.125,0:14:44.125 and repels him in that direction 0:14:44.125,0:14:46.125 by adding a physics force. 0:14:46.125,0:14:48.684 The hurtForce variable is exposed in the Inspector 0:14:48.684,0:14:51.323 as public so that it can be tweaked 0:14:51.323,0:14:53.323 to adjust this element of game play without 0:14:53.323,0:14:55.323 returning to the script. 0:14:55.323,0:14:57.323 In addition to repelling the player, 0:14:57.323,0:14:59.810 we of course subtract from the player's health. 0:14:59.810,0:15:02.209 and update the player's health bar. 0:15:02.209,0:15:04.624 To signify the decrease in health we subtract 0:15:04.624,0:15:06.885 from the width of the bar and use a colour lerp 0:15:06.885,0:15:09.825 to transition it's colour between green and red, 0:15:09.825,0:15:12.640 both by finding the percentage that the current health is 0:15:12.640,0:15:14.640 of the full health amount. 0:15:14.640,0:15:17.873 The health bar simply comprises of two sprites, 0:15:17.873,0:15:19.965 one for the outline of the bar and the other 0:15:19.965,0:15:21.744 for the bar itself. 0:15:21.744,0:15:23.744 This was again designed in Photoshop and then 0:15:23.744,0:15:25.954 the two separate elements were exported. 0:15:25.954,0:15:27.954 In the import settings for these sprites 0:15:27.954,0:15:30.470 we set their pivot to the middle left of the graphic 0:15:30.470,0:15:34.053 so that when it scales down it shrinks towards the left. 0:15:48.573,0:15:50.573 These two sprites are placed under an empty 0:15:50.573,0:15:52.573 parent game object which has a simple script 0:15:52.573,0:15:54.573 on it which makes it follow the player. 0:15:54.573,0:15:56.621 We do this by setting the position to the 0:15:56.621,0:15:58.621 same as the player object's position 0:15:58.621,0:16:00.621 plus an offset that we've made public to allow 0:16:00.621,0:16:02.621 for adjustment in the Inspector. 0:16:16.215,0:16:18.215 When the player has 0 health remaining 0:16:18.215,0:16:20.215 we allow him to fall through the level by 0:16:20.215,0:16:22.629 setting his colliders to triggers, 0:16:22.629,0:16:24.629 and we move him to the very front of rendering 0:16:24.629,0:16:28.194 by placing his sprite renderers on the UI Sorting layer, 0:16:28.194,0:16:31.594 one we've made to render in front of everything in the game. 0:16:31.594,0:16:34.223 We have 2 animations for when the player dies. 0:16:34.223,0:16:37.252 1 called Death, where he loses his hat and gun 0:16:37.252,0:16:38.631 and another called Falling. 0:16:38.631,0:16:40.631 We naturally transition in to Falling once 0:16:40.631,0:16:44.002 the Death animation completes by using the Exit Time 0:16:44.002,0:16:47.239 as our transition condition in the animator. 0:16:50.778,0:16:52.778 Finally, to stop the player moving the character 0:16:52.778,0:16:55.278 or shooting during the Death sequence 0:16:55.278,0:16:58.340 we disable the PlayerControl and Gun scripts. 0:16:58.340,0:17:00.731 Because the Die function is made as public 0:17:00.731,0:17:03.332 we can call it from elsewhere, such as if the player 0:17:03.332,0:17:05.040 falls in to the water. 0:17:05.040,0:17:07.733 To reset the game once the player does hit the water 0:17:07.733,0:17:09.733 we have a KillTrigger object, which simply 0:17:09.733,0:17:12.463 comprises of a trigger collider and a script. 0:17:12.463,0:17:15.012 For most of the game the purpose of the Remover script 0:17:15.012,0:17:17.012 is to remove our enemy objects that fall in 0:17:17.012,0:17:19.789 to the river, and instantiate a splash animation 0:17:19.789,0:17:21.442 and sound effect. 0:17:21.442,0:17:24.001 However, when the player is detected by this trigger 0:17:24.001,0:17:27.092 we call the Die function in the PlayerHealth script 0:17:27.092,0:17:29.092 and also disable CameraTracking 0:17:29.092,0:17:31.092 whilst moving the player off screen 0:17:31.092,0:17:34.527 and calling a co-routiene that pauses for 2 seconds 0:17:34.527,0:17:36.527 and then reloads the level. 0:17:37.079,0:17:39.079 But let's not dwell on the death of the player, 0:17:39.079,0:17:41.079 let's look at his survival and the tools that we give 0:17:41.079,0:17:42.481 him to do that. 0:17:42.481,0:17:44.481 Our game features 2 airdropped crates that 0:17:44.481,0:17:47.124 assist the player, 1 containing a bomb, 0:17:47.124,0:17:49.911 the other a med kit to boost health. 0:17:50.411,0:17:52.963 These crate drops are made up of 2 parts. 0:17:52.963,0:17:55.695 The crate itself and a parachute. 0:17:58.046,0:18:01.311 These 2 elements are nested beneath an empty parent object 0:18:01.311,0:18:03.768 to allow us to animate them as a group. 0:18:03.768,0:18:05.768 We position the 2 sprites so that the parachute's 0:18:05.768,0:18:08.476 centre is at the centre of the parent. 0:18:09.045,0:18:11.907 This way the animation can swing left and right 0:18:11.907,0:18:15.307 as if the entire parachuting crate is floating to the ground. 0:18:15.307,0:18:17.307 We then simply add a rigidbody to cause 0:18:17.307,0:18:19.307 gravity to pull the object down 0:18:19.307,0:18:21.307 and add colliders to the crate so that 0:18:21.307,0:18:23.307 we can detect when it lands and when 0:18:23.307,0:18:24.962 the player picks up the crate. 0:18:24.962,0:18:26.962 Upon landing we transition to a second 0:18:26.962,0:18:30.513 animation state which scales the parachute down. 0:18:30.513,0:18:33.308 Like other parts of our game, the animator handles 0:18:33.308,0:18:34.916 the states of the object. 0:18:34.916,0:18:36.916 We can see that by default it plays the 0:18:36.916,0:18:38.916 floatDown animation state 0:18:38.916,0:18:40.916 but then switches to a landing state 0:18:40.916,0:18:43.472 when the trigger Land is set to true. 0:18:43.972,0:18:47.383 In our script we do this using an onTriggerEnter function, 0:18:47.383,0:18:49.732 which detects the ground via a tag. 0:18:49.732,0:18:52.822 We also detatch the crate itself from the parent object 0:18:52.822,0:18:55.098 and give it a rigidbody of it's own 0:18:55.098,0:18:57.490 so that it can interact with the environment 0:18:57.490,0:19:00.624 resting realistically on a slope if it lands on one. 0:19:00.624,0:19:03.672 Let's focus on the bomb first of all. 0:19:03.672,0:19:05.672 Picking up the bomb crate is handled on the 0:19:05.672,0:19:08.475 BombPickup script, attached to the crate. 0:19:08.475,0:19:11.057 We pickup the crate by destroying it and adding to 0:19:11.057,0:19:13.057 the count of bombs that the player has 0:19:13.057,0:19:15.057 in the script attached to the player called 0:19:15.057,0:19:16.739 LayBombs 0:19:17.557,0:19:19.557 The LayBombs script simply checks if 0:19:19.557,0:19:21.557 the player is carrying a bomb 0:19:21.557,0:19:23.557 and then instantiates an instance 0:19:23.557,0:19:25.557 of the Bomb prefab. 0:19:27.424,0:19:29.952 The Bomb prefab has a timed fuse 0:19:29.952,0:19:32.147 which waits by using an yield within the 0:19:32.147,0:19:34.147 BombDetonation co-routiene 0:19:34.147,0:19:36.147 before calling the Explode function. 0:19:36.799,0:19:39.545 The Explode function performs several actions. 0:19:39.545,0:19:41.545 First it resets the bombLaid variable 0:19:41.545,0:19:43.797 to allow another bomb to be deployed, 0:19:43.797,0:19:45.797 it tells the pickup spawner it is allowed to 0:19:45.797,0:19:47.797 spawn a new crate drop and kills 0:19:47.797,0:19:49.797 enemies within a defined blast radian. 0:19:50.518,0:19:53.058 Let's take a look at how this last part works. 0:19:53.058,0:19:55.058 Because bombs are lethal to enemies regardless of 0:19:55.058,0:19:57.180 their remaining hit points we use the 0:19:57.180,0:19:59.976 Physics.OverlapCircleAll to collect all objects 0:19:59.976,0:20:03.470 tagged Enemy within a certain radius of the bomb. 0:20:03.470,0:20:06.612 We then run a foreach loop for every enemy found 0:20:06.612,0:20:10.663 setting their health to 0 finding a vector from where the bomb was 0:20:10.663,0:20:12.663 to where the enemy is, in order to apply 0:20:12.663,0:20:15.542 a force in the direction of that vector. 0:20:16.304,0:20:18.538 Once the foreach loop is complete 0:20:18.538,0:20:21.381 we play and instantiate visual effects, 0:20:21.381,0:20:23.381 play an audio clip for the explosion 0:20:23.381,0:20:25.907 and of course destroy the bomb itself. 0:20:26.875,0:20:29.252 The visual of the explosion is twofold. 0:20:29.252,0:20:31.252 The main part is a simple circle that appears 0:20:31.252,0:20:33.583 briefly and is then destroyed 0:20:33.583,0:20:35.583 and the second part is a particle system of 0:20:35.583,0:20:37.583 stars that reuses the same sprites 0:20:37.583,0:20:39.583 as our rocket explosion. 0:20:42.265,0:20:44.265 For efficiency we keep this particle 0:20:44.265,0:20:46.265 system in the scene at all times 0:20:46.265,0:20:48.265 and when it is required we use code 0:20:48.265,0:20:51.735 to move the system to the desired position and play it. 0:20:52.511,0:20:54.511 This keeps the particle system in memory 0:20:54.511,0:20:56.511 and makes the game more efficient. 0:20:57.011,0:20:59.011 It's worth noting that we can do this 0:20:59.011,0:21:01.011 because we know we will only have 1 0:21:01.011,0:21:04.668 single explosion in the scene at any one time 0:21:04.668,0:21:07.794 as the player can only throw 1 bomb at a time. 0:21:07.794,0:21:09.794 This is why keeping our particle system in the 0:21:09.794,0:21:11.794 scene and replaying it is more 0:21:11.794,0:21:14.936 efficient than creating instances and then removing them. 0:21:15.714,0:21:17.618 With the rocket explosion however, 0:21:17.618,0:21:19.618 we can have many at once so we do 0:21:19.618,0:21:21.618 need to spawn and remove them. 0:21:22.118,0:21:24.118 Now let's take a look at what happens when our player 0:21:24.118,0:21:26.118 kills an enemy and scores points. 0:21:26.618,0:21:28.436 This is done in 2 parts, 0:21:28.436,0:21:31.668 a scoring animation that plays showing 100 points earned 0:21:31.668,0:21:33.668 and the score UI at the top of the screen 0:21:33.668,0:21:35.528 that increments. 0:21:35.528,0:21:38.303 The score animation is made up to 2 number sprites, 0:21:38.303,0:21:40.193 a 1 and a 0. 0:21:40.193,0:21:42.872 We place this in the scene under an empty parent object 0:21:42.872,0:21:46.036 and animated them using a simple destroyer script to 0:21:46.036,0:21:49.186 remove them from the scene when the animation is complete. 0:21:49.186,0:21:51.186 We call the destroyer function in the script 0:21:51.186,0:21:53.186 by placing an animation event 0:21:53.186,0:21:55.186 at the end of the timeline. 0:22:06.142,0:22:09.703 The ScoreUI itself is a simple GUI text component 0:22:09.703,0:22:11.703 with a custom font and script that manages 0:22:11.703,0:22:13.703 the score for the player. 0:22:13.703,0:22:16.759 The Score variable is public, meaning that we can address it 0:22:16.759,0:22:18.980 from the Enemy script when they are killed 0:22:18.980,0:22:20.980 and add 100 points to the value. 0:22:20.980,0:22:22.980 Speaking of the enemies, let's take a look 0:22:22.980,0:22:24.980 at them more in depth now. 0:22:25.480,0:22:28.260 In our game we have 2 types of alien enemy, 0:22:28.260,0:22:30.854 a green slug-like monster and a smarter 0:22:30.854,0:22:32.854 alien that brought his ship with him for 0:22:32.854,0:22:34.563 protection during the invasion. 0:22:34.563,0:22:36.563 These characters share the same script 0:22:36.563,0:22:38.563 as the behaviour is very similar 0:22:38.563,0:22:40.881 and we allow for differing movement speeds 0:22:40.881,0:22:42.881 and amounts of hit points by setting 0:22:42.881,0:22:45.765 these as public variables in the Inspector. 0:22:46.638,0:22:49.093 Each enemy has it's own Walk animation. 0:22:49.093,0:22:51.093 The slug has a moving tail, whist the 0:22:51.093,0:22:54.444 ship-based enemy rocks back and forth as it approaches. 0:22:55.994,0:22:57.994 For the slug we used the sprite importer 0:22:57.994,0:22:59.994 to define the tail section of the graphic 0:22:59.994,0:23:01.994 as a separate sprite element, 0:23:01.994,0:23:04.438 meaning that we could animate it individually 0:23:04.438,0:23:07.475 and avoid having to scale the entire sprite. 0:23:07.475,0:23:09.475 By setting the pivot to the right 0:23:09.475,0:23:12.124 we are able to animate the tail expanding and contracting 0:23:12.124,0:23:14.124 from that point. 0:23:16.475,0:23:19.918 For added character we then move the eyelid up and down 0:23:19.918,0:23:21.918 and we use the Z value to sort the sprites 0:23:21.918,0:23:24.859 amongst one another, the eye being below the eyelid 0:23:24.859,0:23:26.859 so that we could animate it over the top. 0:23:28.865,0:23:31.268 The second enemy's animation was much simpler 0:23:31.268,0:23:34.046 and just meant that we rotated it back and forth. 0:23:35.798,0:23:37.798 For the mechanics of moving the enemies 0:23:37.798,0:23:41.229 we drive them by setting the velocity of the rigidbody. 0:23:41.229,0:23:43.889 When they encounter an obstacle such as a wall 0:23:43.889,0:23:47.826 they detect this by using a Physics.OverlapPoint function, 0:23:47.826,0:23:51.317 which checks for a point in space overlapping a collider. 0:23:51.317,0:23:53.854 Our walls, the towers at each side of the level, 0:23:53.854,0:23:55.854 are tagged as obstacles. 0:23:55.850,0:23:59.161 When this function detects them it calls the Flip function, 0:23:59.161,0:24:01.767 it reverses the X scale of the enemy 0:24:01.767,0:24:04.070 sending them moving in a different direction. 0:24:04.070,0:24:06.070 To kill the enemies, each time a rocket collides 0:24:06.070,0:24:09.036 with them it's script calls the Hurt function on 0:24:09.036,0:24:11.036 the particular enemy that it's hit. 0:24:14.962,0:24:16.962 In this function we subtract 1 from the 0:24:16.962,0:24:19.213 hit points of the particular enemy. 0:24:19.213,0:24:21.213 We then keep tabs on the enemy's health 0:24:21.213,0:24:23.213 inside the fixed update function. 0:24:23.213,0:24:27.124 If it drops to 0 we call the Death function. 0:24:31.229,0:24:33.916 When they die we perform a number of functions. 0:24:33.916,0:24:35.916 Firstly we disable all sprite renderers 0:24:35.916,0:24:37.916 as our 2D characters are made up of a 0:24:37.916,0:24:39.916 number of sprite objects that are animated. 0:24:40.941,0:24:42.941 This is because we simply want to swap out the 0:24:42.941,0:24:44.941 animated elements for a single sprite 0:24:44.941,0:24:46.941 of the dead character 0:24:47.745,0:24:49.745 We do this with the main sprite renderer by 0:24:49.745,0:24:51.745 setting it to use the sprite assigned to 0:24:51.745,0:24:54.165 the deadEnemy variable. 0:24:54.165,0:24:56.165 We then add to the score using the public 0:24:56.165,0:24:58.165 variable in the Score script 0:24:58.165,0:25:00.744 and we add some visual flare to the enemy's death 0:25:00.744,0:25:03.534 by adding torque to spin them as they die. 0:25:04.448,0:25:06.448 Because we need the enemies to fall through the 0:25:06.448,0:25:08.881 environment and land in the river when they die 0:25:08.881,0:25:10.881 we find all colliders on the object 0:25:10.881,0:25:13.589 and set their IsTrigger parameter to true. 0:25:13.589,0:25:15.139 This means that they will pass through the 0:25:15.139,0:25:17.417 environment colliders. 0:25:17.417,0:25:20.054 We then choose from an array of death audio clips 0:25:20.054,0:25:22.054 and play one of them back, before creating 0:25:22.054,0:25:25.470 an instance of the Score animation we showed you earlier. 0:25:27.876,0:25:29.876 To remove the dead enemy from the scene 0:25:29.876,0:25:31.876 we rely on the killTrigger object 0:25:31.876,0:25:34.762 It performs the same function as discussed earlier 0:25:34.762,0:25:36.762 as any non-player object touching it 0:25:36.762,0:25:39.950 will cause a splash animation and remove that object. 0:25:39.950,0:25:41.950 The sound effect of them hitting the water is 0:25:41.950,0:25:43.950 an audio clip attached to the animated 0:25:43.950,0:25:45.950 splash which plays on awake 0:25:45.950,0:25:47.950 so that when we create an instance of the animated 0:25:47.950,0:25:50.634 object we hear the sound right away. 0:25:55.153,0:25:57.153 To finish the game level re decorated the 0:25:57.153,0:25:59.153 background with a number of moving props 0:25:59.153,0:26:02.302 in order to make our game environment feel more dynamic. 0:26:02.302,0:26:05.703 We added flying swans, plus buses and taxis that drive 0:26:05.703,0:26:07.125 along the river bank. 0:26:07.125,0:26:10.634 First was the swan, which was created from a sprite sheet, 0:26:10.634,0:26:12.634 drawn in Photoshop and imported using 0:26:12.634,0:26:14.634 the Multiple Sprite Mode import setting 0:26:14.634,0:26:16.051 in the Inspector. 0:26:16.051,0:26:18.800 By choosing this approach Unity automates choosing 0:26:18.800,0:26:20.800 each frame in the sheet and importing 0:26:20.800,0:26:22.800 it as a separate sprite under the parent 0:26:22.800,0:26:24.579 hierarchy of the asset. 0:26:24.579,0:26:27.279 Because this is a linear set of animation frames 0:26:27.279,0:26:29.279 we could simply drag all of these sprites in to the 0:26:29.279,0:26:32.346 scene to let Unity animate them for us. 0:26:32.346,0:26:35.317 Et voila, our animated swan is ready to add 0:26:35.317,0:26:37.759 as a background element. 0:26:37.759,0:26:40.165 The swan was then given a rigidbody2D 0:26:40.165,0:26:42.165 so that we can use velocity to send it 0:26:42.165,0:26:43.369 across the screen. 0:26:43.369,0:26:47.334 As with the bus and the cab, the swan is saved as a prefab. 0:26:49.257,0:26:51.257 For the bus and taxi prefabs we 0:26:51.257,0:26:53.257 simply separated the bodies and wheels of 0:26:53.257,0:26:55.257 the vehicles in the sprite importer 0:26:55.257,0:26:58.392 and made a simple bobbing animation. 0:26:58.392,0:27:00.793 Applying a 2d rigidbody to these as well, 0:27:00.793,0:27:02.793 we were able to drive them across the screen 0:27:02.793,0:27:04.376 using velocity. 0:27:07.279,0:27:10.271 For all 3 props, the bus, taxi and the swan 0:27:10.271,0:27:12.271 we created a script we could reuse 0:27:12.271,0:27:14.271 which is in charge of spawning them. 0:27:14.271,0:27:16.616 The BackgroundPropsSpawner script 0:27:16.616,0:27:19.838 also handles the frequency, a speed to give them 0:27:19.838,0:27:21.838 and where on screen to spawn them. 0:27:21.838,0:27:24.521 This meant that we could make 3 creator objects 0:27:24.521,0:27:26.521 with the same script on. 0:27:26.521,0:27:28.521 Changing which prefab will be spawned 0:27:28.521,0:27:30.521 and what properties to give it. 0:27:30.521,0:27:33.854 Take a look at the comments in the script to learn more. 0:27:33.854,0:27:36.172 Finally, for more background dynamism, 0:27:36.172,0:27:40.409 we added rolling clouds, panning river details and fog. 0:27:41.323,0:27:44.525 We did this by adding 2 instances of the background sprite 0:27:44.525,0:27:48.004 to a parent object and simply used animation to slowly 0:27:48.004,0:27:50.004 pan them across the screen. 0:27:50.004,0:27:52.652 Because this animation loops our animation will 0:27:52.652,0:27:54.652 continue indefinitely. 0:27:59.185,0:28:01.031 And that's how we made our game. 0:28:01.031,0:28:03.031 We hope this overview has given you some idea of 0:28:03.031,0:28:05.516 how we create 2D games in Unity, 0:28:05.516,0:28:07.516 and we'll be creating more simply projects and 0:28:07.516,0:28:08.971 tutorials in the future. 0:28:08.971,0:28:11.689 We look forward to your feedback on Unity4.3 0:28:11.689,0:28:13.689 and we can't wait to see the great 2D titles 0:28:13.689,0:28:14.959 that you'll come up with. 0:28:14.959,0:28:16.487 Thanks for watching.