< Return to Video

TANKS! Unity Tutorial - Phase 7 of 8 - Game Managers

  • 0:00 - 0:03
    Phase 7 - Managers.
  • 0:04 - 0:07
    Okay, so in this particular section
  • 0:08 - 0:10
    we're going to create the game manager
  • 0:10 - 0:11
    and the idea is that by the end of it
  • 0:11 - 0:13
    we will have rounds with tanks
  • 0:13 - 0:15
    where you can drive around and fire
  • 0:15 - 0:17
    and destroy another tank and at the
  • 0:17 - 0:19
    end of it you have a UI that
  • 0:19 - 0:21
    explains that you have won that round,
  • 0:21 - 0:23
    and then after several rounds have been won
  • 0:23 - 0:25
    that you've won the game.
  • 0:26 - 0:28
    There is it turning red.
  • 0:28 - 0:30
    And you get this text at the end,
  • 0:30 - 0:32
    Player (number) wins the round!
  • 0:32 - 0:34
    And you'll notice also that we've colored
  • 0:34 - 0:36
    the UI to match the color
  • 0:36 - 0:38
    of the tank.
  • 0:38 - 0:40
    So we're going to start by creating
  • 0:40 - 0:43
    the spawn points for each tank.
  • 0:43 - 0:45
    So for that we just need a
  • 0:45 - 0:48
    position reference in the world,
  • 0:48 - 0:50
    so we're going to use an empty game object
  • 0:50 - 0:52
    for that, it's very simple, we're just
  • 0:52 - 0:54
    going to go to the hierarchy and we're going to
  • 0:54 - 0:56
    choose Create Empty.
  • 0:57 - 1:00
    I'm going to rename this one SpawnPoint1.
  • 1:03 - 1:05
    Then I'm going to duplicate it.
  • 1:05 - 1:07
    Control-D or Command-D
  • 1:07 - 1:09
    depending on your platform, and call it
  • 1:09 - 1:11
    SpawnPoint2.
  • 1:11 - 1:13
    And I'll give you some positions for those.
  • 1:14 - 1:19
    So SpawnPoint1 is (-3, 0, 30).
  • 1:21 - 1:25
    With a rotation of (0, 180, 0).
  • 1:26 - 1:28
    It's going to be a lot quicker to read it off the
  • 1:28 - 1:30
    slider because I've got both spawn points on at once.
  • 1:31 - 1:34
    So SpawnPoint1 position (-3, 0, 30)
  • 1:34 - 1:39
    Rotation 180 in the Y axis, 0 in the other two.
  • 1:39 - 1:43
    SpawnPoint2 (13, 0, -5)
  • 1:43 - 1:48
    ensuring a rotation of SpawnPoint2 is (0, 0, 0).
  • 1:48 - 1:50
    And naturally this is one of those things
  • 1:50 - 1:52
    that is not going to make a huge difference.
  • 1:52 - 1:54
    If you decide you want to move those spawn points somewhere
  • 1:54 - 1:56
    else in your game feel free to go ahead and do that.
  • 1:57 - 1:59
    Obviously you want to keep the Y axis
  • 1:59 - 2:01
    positioned at 0 at all times
  • 2:01 - 2:03
    because that's where you want the tanks to start.
  • 2:03 - 2:06
    Because we're dealing with these spawn points which are
  • 2:06 - 2:08
    effectively empty game objects,
  • 2:08 - 2:10
    something that just has a transform component
  • 2:10 - 2:12
    it's very difficult to see them in the scene.
  • 2:13 - 2:15
    So you have to select the translate tool to
  • 2:15 - 2:17
    be able to see their handles,
  • 2:17 - 2:18
    so SpawnPoint1 is here,
  • 2:18 - 2:20
    SpawnPoint2 is over here.
  • 2:20 - 2:22
    Now there's a quick way to rectify that
  • 2:22 - 2:24
    which is to select the SpawnPoint
  • 2:24 - 2:26
    and give it what we call a gizmo.
  • 2:26 - 2:28
    So a gizmo is a 2D representation
  • 2:28 - 2:30
    of something in the scene view.
  • 2:31 - 2:33
    So if you reselect SpawnPoint1.
  • 2:34 - 2:36
    And then at the top of the inspector
  • 2:36 - 2:38
    there's this little cube icon.
  • 2:38 - 2:42
    If you click down you can choose from a number of gizmos.
  • 2:42 - 2:44
    You can specify your own if you bring in
  • 2:44 - 2:46
    a texture in Unity, you can set that as the gizmo,
  • 2:46 - 2:47
    which is super handy.
  • 2:47 - 2:50
    But for this we're just going to select a blue background.
  • 2:50 - 2:52
    So that's going to then print the name
  • 2:53 - 2:55
    SpawnPoint1 just like that.
  • 2:56 - 2:58
    And then we'll do the same for SpawnPoint2
  • 2:58 - 3:00
    we're going to choose red.
  • 3:00 - 3:02
    So that's going to match the color of our tanks
  • 3:02 - 3:04
    that we're spawning as well, so SpawnPoint2 is red,
  • 3:04 - 3:06
    SpawnPoint1 is blue.
  • 3:10 - 3:13
    Okay, so that's where my two spawn points are.
  • 3:14 - 3:16
    So we just, design-wise, decided
  • 3:16 - 3:18
    to put them either side of a building so the
  • 3:18 - 3:20
    players have to at least drive around to start
  • 3:20 - 3:21
    shooting in the game.
  • 3:21 - 3:22
    So that's gizmos.
  • 3:22 - 3:24
    The next thing we need to do is create
  • 3:24 - 3:25
    a screen space canvas.
  • 3:25 - 3:27
    So when we first put in a UI
  • 3:27 - 3:29
    element in to the game, a slider for the health,
  • 3:30 - 3:32
    I mentioned that ordinarily our
  • 3:32 - 3:35
    UI is over the entire screen.
  • 3:35 - 3:37
    So that's what we're going to do now.
  • 3:37 - 3:39
    So in the hierarchy I'm just going to choose the
  • 3:39 - 3:41
    Create menu, I'm going to choose UI,
  • 3:42 - 3:44
    and Canvas.
  • 3:45 - 3:47
    And yet again it's going to appear huge,
  • 3:47 - 3:49
    and it should look like that if you've done it right.
  • 3:49 - 3:51
    And you can't really get it wrong because that's the default.
  • 3:53 - 3:55
    Then what we're going to do is rename this
  • 3:55 - 3:57
    MessageCanvas, so F2 on PC,
  • 3:57 - 3:59
    or Return on Mac,
  • 3:59 - 4:01
    just rename it MessageCanvas.
  • 4:02 - 4:04
    Now we want to work with this canvas a little
  • 4:04 - 4:06
    bit and add a text element that's going to be
  • 4:06 - 4:08
    the basis of our messaging at the end
  • 4:08 - 4:09
    of each round.
  • 4:09 - 4:11
    So what I'm going to do is,
  • 4:11 - 4:13
    first off I'm going to set the scene view to 2D mode.
  • 4:13 - 4:15
    So at the top there's a little button here
  • 4:16 - 4:18
    by the scene tab that says 2D, click on that.
  • 4:19 - 4:21
    It's going to constrain to a particular axis.
  • 4:22 - 4:24
    Then what I'm going to do is to click on
  • 4:24 - 4:26
    my MessageCanvas and you can
  • 4:26 - 4:28
    either hover over the scene view
  • 4:28 - 4:31
    and press F on the keyboard to frame,
  • 4:31 - 4:33
    or you can go to Edit - Frame Selected.
  • 4:35 - 4:37
    Then you can just use your scroll wheel
  • 4:37 - 4:39
    or gesture on your trackpad if that's what you use,
  • 4:40 - 4:42
    to kind of frame that in the scene view.
  • 4:42 - 4:44
    Then what we're going to do is actually add a
  • 4:44 - 4:47
    text field, so I'm going to right-click on my MessageCanvas,
  • 4:47 - 4:49
    so that I am immediately creating something
  • 4:49 - 4:51
    under that parent object.
  • 4:51 - 4:54
    And I'm going to choose UI Text
  • 4:55 - 4:57
    What you should see then is you have something called
  • 4:57 - 5:00
    New Text, it's a new text field,
  • 5:00 - 5:02
    it's left aligned and it's kind of sat in
  • 5:02 - 5:03
    the middle of our canvas.
  • 5:03 - 5:05
    It should look like that.
  • 5:05 - 5:07
    So basically with this thing we want it
  • 5:07 - 5:09
    to be nice huge text
  • 5:09 - 5:11
    and we want it to be stretched over most of the
  • 5:11 - 5:14
    screen except for a border around the edge.
  • 5:14 - 5:16
    So depending on what we put in to it we will use
  • 5:16 - 5:18
    Best Fit on the text which will scale it
  • 5:18 - 5:20
    if there's too much information on the screen,
  • 5:20 - 5:22
    and will ultimately fit it in to this canvas.
  • 5:22 - 5:25
    So on the Rect Transform for the text
  • 5:25 - 5:27
    the anchors for X and Y
  • 5:27 - 5:30
    should have a minimum of 0.1
  • 5:31 - 5:33
    and a maximum of 0.9.
  • 5:35 - 5:36
    So it should look like this.
  • 5:37 - 5:40
    So note that it's X, Y across,
  • 5:40 - 5:43
    and then X, Y across again.
  • 5:43 - 5:45
    So Min is the first two values, Max is the second,
  • 5:45 - 5:48
    so 0.1, 0.1, 0.9, 0.9.
  • 5:49 - 5:52
    Then what we're going to do is reset
  • 5:52 - 5:53
    all of these values.
  • 5:53 - 5:57
    So the anchors are basically where those
  • 5:57 - 6:00
    edges start from, so if I put those all to 0
  • 6:00 - 6:04
    and I say that X and Y should have 0.1
  • 6:04 - 6:06
    it's going to take that as a proportion
  • 6:06 - 6:07
    of the screen that we've got.
  • 6:07 - 6:09
    So you should now see that your screen looks
  • 6:09 - 6:11
    like this, it's got this border
  • 6:11 - 6:13
    around the outside and our text
  • 6:13 - 6:16
    is basically starting up in the upper left there.
  • 6:17 - 6:20
    Okay, so we've made a new
  • 6:20 - 6:22
    MessageCanvas, we've added a Text
  • 6:22 - 6:24
    new game object to it.
  • 6:24 - 6:26
    And on the rect transform the anchors for
  • 6:26 - 6:28
    X and Y have a minimum of 0.1
  • 6:28 - 6:29
    and a maximum of 0.9,
  • 6:29 - 6:33
    just creating this pad around the outside.
  • 6:33 - 6:35
    Obviously it varies depending on width and height
  • 6:35 - 6:37
    because of the aspect ratio
  • 6:37 - 6:39
    being wider than it is tall.
  • 6:39 - 6:43
    I'll reset all of those left, right, top, bottom to 0.
  • 6:44 - 6:46
    So then we'll actually work with the text component.
  • 6:46 - 6:48
    With that Text game object still selected
  • 6:48 - 6:50
    we're going to scroll down to our Text
  • 6:50 - 6:52
    component which is here.
  • 6:53 - 6:55
    So obviously the main characteristic of text
  • 6:55 - 6:57
    is what it actually says,
  • 6:57 - 6:59
    so I'm going to write in TANKS!
  • 7:00 - 7:02
    You can do that or I'm sure you can name the game
  • 7:02 - 7:04
    something hilariously different.
  • 7:04 - 7:06
    So feel free to do that.
  • 7:06 - 7:08
    And then the font that we've included for you guys,
  • 7:08 - 7:10
    which is a free for use font,
  • 7:10 - 7:13
    is one called BowlbyOne-Regular.
  • 7:13 - 7:15
    So next to the Font field just
  • 7:15 - 7:17
    use the circle select to change from the default
  • 7:17 - 7:19
    Arial to that one.
  • 7:20 - 7:22
    And then because this entire
  • 7:22 - 7:24
    block here is that text field
  • 7:24 - 7:27
    we want to set the alignment under the Paragraph section
  • 7:28 - 7:30
    to centre and middle.
  • 7:32 - 7:34
    So that'll place it right in the centre of the screen.
  • 7:35 - 7:36
    Then finally what we're going to do is
  • 7:36 - 7:38
    enable Best Fit.
  • 7:40 - 7:44
    And set the maximum size to 60, 60.
  • 7:45 - 7:47
    And the color to White.
  • 7:50 - 7:52
    So the font is BowlbyOne-Regular.
  • 7:52 - 7:54
    I've enabled Best Fit which will give me
  • 7:54 - 7:57
    a Min and Max size, I set the maximum to 60.
  • 7:58 - 8:00
    And then I set my color to White
  • 8:01 - 8:04
    just by dragging up in this color panel.
  • 8:07 - 8:09
    It should look like this if you've got it right.
  • 8:09 - 8:11
    Okay, so this might be tricky
  • 8:11 - 8:13
    to see so what we're going to do is just add
  • 8:13 - 8:15
    a drop shadow to it, nice and simple.
  • 8:15 - 8:17
    And for that we have a separate component.
  • 8:17 - 8:19
    So if you click the Add Component button
  • 8:19 - 8:22
    and just type in Shadow that will jump to that
  • 8:22 - 8:24
    very simply and you can hit Return.
  • 8:24 - 8:26
    And for the shadow we're going to
  • 8:26 - 8:30
    set the color, so first off we're going to choose
  • 8:30 - 8:32
    a kind of brown color to go with the sand.
  • 8:32 - 8:37
    So that is 114, 71, 40,
  • 8:38 - 8:40
    and the alpha remains the same,
  • 8:40 - 8:42
    it should be 128.
  • 8:43 - 8:45
    Then because that's only just poking out from
  • 8:45 - 8:47
    just behind the tank's actual text
  • 8:47 - 8:51
    I'm going to set the Effect Distance to -3 in X and Y.
  • 8:53 - 8:54
    It should look like that.
  • 8:54 - 8:56
    If you want to get artistic at this point, feel free.
  • 8:57 - 8:59
    And finally, once we've designed that
  • 8:59 - 9:01
    I'm just going to save my scene really quick
  • 9:01 - 9:03
    and then I'm going to disable 2D mode
  • 9:03 - 9:05
    because I don't want to look at this stuff any more
  • 9:05 - 9:08
    I want to go back to actually messing with my levels
  • 9:08 - 9:10
    so I'm going to uncheck 2D mode on the scene view
  • 9:11 - 9:13
    and then I'm going to select my level
  • 9:13 - 9:15
    art and I'm going to frame that
  • 9:15 - 9:17
    and then zoom back in to where I was.
  • 9:18 - 9:21
    So one more time, I was on my MessageCanvas
  • 9:21 - 9:23
    in 2D mode, framed,
  • 9:24 - 9:26
    and I'm just going to reselect my level art,
  • 9:26 - 9:28
    hover, press F to frame,
  • 9:28 - 9:30
    when not in 2D mode and zoom in.
  • 9:33 - 9:35
    We've added out text component
  • 9:35 - 9:37
    and we've set the text to say TANKS!
  • 9:37 - 9:39
    or something otherwise hilarious.
  • 9:40 - 9:42
    We have used circle select to choose our font.
  • 9:42 - 9:44
    That font is BowlbyOne-Regular.
  • 9:45 - 9:47
    It's a free font that we took from Google.
  • 9:47 - 9:48
    Thank you Google.
  • 9:48 - 9:51
    We've set the alignment to centre and middle.
  • 9:51 - 9:53
    So that it sits right in the centre of
  • 9:53 - 9:55
    where we've set it up.
  • 9:55 - 9:56
    We've enabled Best fit.
  • 9:56 - 9:58
    So basically Best Fit will allow that
  • 9:58 - 10:01
    to scale up to the maximum size.
  • 10:01 - 10:03
    So if we end up putting a lot of text in
  • 10:03 - 10:05
    to this text field then it will be between
  • 10:05 - 10:07
    60 and 10, which is the default
  • 10:07 - 10:09
    minimum if the amount of text forces it to
  • 10:09 - 10:11
    be smaller those are the things it'll be between
  • 10:11 - 10:13
    before it starts actually clipping over the
  • 10:13 - 10:14
    edge of the rectangle.
  • 10:14 - 10:16
    Then we set the color to White.
  • 10:17 - 10:19
    And we added a shadow component
  • 10:19 - 10:22
    to the text and we set the Effect color to
  • 10:22 - 10:26
    be brown and (-3, -3) for the Distance.
  • 10:26 - 10:28
    So that's back to the left and down a little.
  • 10:28 - 10:30
    And then we disabled 2D mode to go back
  • 10:30 - 10:32
    to the level itself.
  • 10:33 - 10:35
    Then we need to get back
  • 10:35 - 10:37
    to actually framing our tank and
  • 10:37 - 10:39
    worrying about how the camera will behave
  • 10:39 - 10:41
    when there's more than one tank.
  • 10:41 - 10:43
    So what I'm going to do is select my
  • 10:43 - 10:45
    CameraRig game object.
  • 10:45 - 10:47
    Now what you'll notice with the camera rig
  • 10:47 - 10:49
    is that we now have something missing.
  • 10:49 - 10:51
    So before we dragged out single tank
  • 10:51 - 10:54
    on and dropped it on to the targets array,
  • 10:54 - 10:56
    the thing at the bottom here, this thing.
  • 10:57 - 10:59
    Now it has a size of 1 because
  • 10:59 - 11:01
    we've already populated that field,
  • 11:01 - 11:03
    but this is missing because we've deleted
  • 11:03 - 11:05
    our tank so it can't find it any more.
  • 11:05 - 11:07
    But that's fine because we don't actually want this
  • 11:07 - 11:10
    to be there at all, we want the script to handle it for us.
  • 11:10 - 11:12
    So what I'm going to do is to
  • 11:12 - 11:14
    go to my CameraControl script,
  • 11:14 - 11:16
    I'm going to set my size back to 0,
  • 11:16 - 11:18
    so it doesn't exist any more
  • 11:19 - 11:21
    and then I'm going to double click on my CameraControl script
  • 11:21 - 11:23
    to go back to editing it.
  • 11:23 - 11:25
    So you may remember when we first came across
  • 11:25 - 11:29
    this there was that HideInInspector bit at the top?
  • 11:30 - 11:32
    And now comes the time to
  • 11:32 - 11:36
    uncomment that bit so that this Targets field
  • 11:36 - 11:38
    is no longer seen in the inspector.
  • 11:38 - 11:40
    So we're not deleting that part,
  • 11:40 - 11:43
    we're just removing the / and * either side of it.
  • 11:43 - 11:45
    So it should look like this.
  • 11:46 - 11:49
    So when you save your script and return to the editor
  • 11:50 - 11:54
    you'll notice that the camera control no longer shows that bit.
  • 11:56 - 11:58
    And compiled, there we go.
  • 11:58 - 12:00
    Okay, so your Targets array should disappear
  • 12:00 - 12:03
    it's still there, it's still accessible via the script,
  • 12:03 - 12:05
    it's just not visible for you to drag and drop stuff
  • 12:05 - 12:07
    on to, which is exactly what we needed.
  • 12:07 - 12:09
    Then we are ready to actually create
  • 12:09 - 12:12
    our game manager, so I'm going to save my scene
  • 12:12 - 12:15
    and I'm going to use the hierarchy Create button
  • 12:15 - 12:17
    to create an empty
  • 12:18 - 12:21
    and I'm going to name it GameManager.
  • 12:24 - 12:26
    So we're just using this as
  • 12:26 - 12:30
    a thing that can host our GameManager script,
  • 12:30 - 12:32
    we could really attach this to anything,
  • 12:32 - 12:34
    we could attach it to the level art or
  • 12:34 - 12:36
    something that we know is always going to be in
  • 12:36 - 12:39
    the scene but for our purposes it just makes sense
  • 12:39 - 12:41
    to have a dedicated game object we can
  • 12:41 - 12:44
    select and go back and set everything up on.
  • 12:44 - 12:47
    So our GameManager is going to be an independent object.
  • 12:47 - 12:51
    So in the Scripts Managers folder you will
  • 12:51 - 12:54
    find two files, one of them is the GameManager,
  • 12:54 - 12:56
    one of them is the TankManager, and we'll come on
  • 12:56 - 12:59
    to explain what the tank manager does shortly.
  • 12:59 - 13:01
    For now I'm going to just grab my
  • 13:01 - 13:05
    GameManager and drop it on to my GameManager object.
  • 13:05 - 13:07
    So grab the GameManager script,
  • 13:07 - 13:09
    drop it on to the GameManager object.
  • 13:09 - 13:12
    So let's actually do things the other way round
  • 13:12 - 13:14
    this time, we're going to populate these variables
  • 13:14 - 13:16
    and then we'll look at the script and see how it works
  • 13:16 - 13:18
    because there's a fair bit to it.
  • 13:19 - 13:21
    So we have a number of rounds to win
  • 13:21 - 13:23
    and as we said earlier there are 5 rounds to win.
  • 13:23 - 13:25
    There's a start and end delay to
  • 13:25 - 13:28
    each round which will allow the players to actually
  • 13:28 - 13:30
    read the text that's on the screen.
  • 13:30 - 13:33
    And then there is a reference to our CameraControl,
  • 13:33 - 13:35
    so remember we said that this script would
  • 13:35 - 13:37
    tell the camera where the tanks were and,
  • 13:37 - 13:39
    instantiate them and whatnot. So it needs
  • 13:39 - 13:41
    a reference, so that's the first thing we're going to setup.
  • 13:42 - 13:44
    So the CameraRig has that
  • 13:44 - 13:47
    cameraControl script attached to it,
  • 13:47 - 13:50
    so this is expecting something of type Camera Control.
  • 13:50 - 13:52
    So that component is attached to the camera rigs
  • 13:52 - 13:54
    so if I just drag and drop my CameraRig
  • 13:55 - 13:57
    on to that, then that will assign it.
  • 13:57 - 13:59
    Then, under Message Canvas,
  • 13:59 - 14:01
    I have my text game object.
  • 14:01 - 14:03
    that's my Message Text, I'm going to drag and
  • 14:03 - 14:05
    drop that on to assign it too.
  • 14:05 - 14:07
    And finally my Tank prefab,
  • 14:08 - 14:10
    let's zoom out a little,
  • 14:10 - 14:12
    is in my Prefabs folder, so I'm going to select Prefabs,
  • 14:13 - 14:16
    and I'm going to grab and drop my tank on there.
  • 14:19 - 14:21
    Then you will notice conspicuously
  • 14:21 - 14:23
    there is an array at the bottom called Tanks.
  • 14:25 - 14:29
    Which if you expand has size.
  • 14:29 - 14:32
    So as we know there are 2 tanks in our game.
  • 14:32 - 14:34
    So the size needs to be 2 so there
  • 14:34 - 14:36
    are 2 items in this array
  • 14:36 - 14:38
    Player1 Tank, Player2 Tank.
  • 14:38 - 14:40
    If you expand that once you've typed in
  • 14:40 - 14:44
    to it and hit return you will see there's Element 0 and Element 1.
  • 14:44 - 14:46
    So just a reminder, any array always starts
  • 14:46 - 14:48
    at 0, so that's why you're seeing
  • 14:48 - 14:50
    instead of 1 and 2, it's 0 and 1.
  • 14:51 - 14:53
    So the two things that we actually need here are
  • 14:53 - 14:55
    just the color that we want it to be,
  • 14:55 - 14:57
    so this color will apply to
  • 14:57 - 14:59
    the tank itself and
  • 14:59 - 15:01
    it'll also apply to the name
  • 15:01 - 15:04
    of the tank or the name of player1 and player2
  • 15:04 - 15:05
    in the UI itself.
  • 15:05 - 15:07
    So this color will get used for both of those things.
  • 15:08 - 15:10
    I'm going to setup red and blue for this.
  • 15:10 - 15:13
    So Element 0, I'm going to click on the color block.
  • 15:14 - 15:16
    So that big black square there, click on that
  • 15:16 - 15:18
    to bring up the color picker
  • 15:18 - 15:20
    and then the color I'm going to use there is
  • 15:20 - 15:24
    (40, 100, 178).
  • 15:24 - 15:26
    So shade of blue like that.
  • 15:28 - 15:30
    You'll notice that this conspicuously matches
  • 15:30 - 15:34
    the name tag gizmo that we gave Spawn Point 1.
  • 15:34 - 15:36
    Funny that.
  • 15:36 - 15:38
    So we will drag on SpawnPoint1
  • 15:38 - 15:39
    as the Spawn Point.
  • 15:40 - 15:43
    Then Element 1 will have a different color.
  • 15:44 - 15:48
    And that is a red which is 229,
  • 15:48 - 15:50
    I'm going to recap these in a moment.
  • 15:50 - 15:52
    (229, 46, 40).
  • 15:54 - 15:57
    (229, 46, 40) R, G and B.
  • 15:59 - 16:01
    And you guessed it, SpawnPoint2 is
  • 16:01 - 16:03
    the spawn point to drop on.
  • 16:04 - 16:06
    We've expanded our Tanks array so the
  • 16:06 - 16:08
    GameManager will create these tanks and color them
  • 16:08 - 16:10
    and also color the UI for us.
  • 16:10 - 16:12
    We've assigned all of our references,
  • 16:12 - 16:14
    like the text and the camera rig.
  • 16:15 - 16:17
    And then the colors we've used are
  • 16:17 - 16:20
    blue of (42, 100, 178).
  • 16:21 - 16:23
    That's for SpawnPoint1.
  • 16:23 - 16:26
    And then color of red (229, 46, 40).
  • 16:26 - 16:28
    for SpawnPoint2,
  • 16:28 - 16:30
    which should also be dragged on.
  • 16:30 - 16:33
    Okay, so let's talk about our GameManager.
  • 16:34 - 16:36
    The GameManager is in charge
  • 16:36 - 16:38
    of the game, weirdly enough,
  • 16:38 - 16:40
    the clue is in the name,
  • 16:40 - 16:42
    but the way that that works is pretty much what you're seeing here,
  • 16:42 - 16:44
    so it's in charge of initialising the game,
  • 16:44 - 16:47
    it needs to spawn as many tanks
  • 16:47 - 16:49
    as we've told it to, in this case 2.
  • 16:49 - 16:51
    And it needs to setup the camera targets,
  • 16:51 - 16:53
    so it needs to say 'hey camera control, these are
  • 16:53 - 16:55
    the tanks that I've spawned and you need to
  • 16:55 - 16:57
    focus in on them when the game starts'.
  • 16:58 - 17:00
    Then it needs to run the states of the game.
  • 17:00 - 17:02
    So we're going to look at the code in
  • 17:02 - 17:04
    the GameManager shortly and you'll see
  • 17:04 - 17:08
    that it's basically a simple sort of state machine that's running
  • 17:08 - 17:10
    round starting what happens during
  • 17:10 - 17:12
    round playing and what needs to be decided
  • 17:12 - 17:13
    when the round ends.
  • 17:13 - 17:16
    And all these things link in to the Tank Manager,
  • 17:16 - 17:18
    which is a separate script.
  • 17:19 - 17:21
    So the Tank Manager handles
  • 17:21 - 17:23
    shooting and movement for the tanks,
  • 17:23 - 17:26
    and also visual elements, I.E. the UI.
  • 17:27 - 17:29
    So what you need to understand is
  • 17:29 - 17:31
    that each tank gets assigned
  • 17:31 - 17:33
    it's own tank manager, and that
  • 17:33 - 17:35
    tank manager is then in charge of
  • 17:35 - 17:39
    turning off input, control, and shooting.
  • 17:39 - 17:43
    So every time that tank gets spawned in the world
  • 17:43 - 17:44
    it doesn't know what it's got to do but it has
  • 17:44 - 17:46
    it's tank manager there to sort it out.
  • 17:46 - 17:48
    So obviously this game is extendable
  • 17:48 - 17:50
    so we've put this kind of third one there to
  • 17:50 - 17:52
    kind of mean 'and so on'
  • 17:52 - 17:54
    as we populate that array with more tanks
  • 17:54 - 17:55
    it can do more things.
  • 17:56 - 17:58
    So shall we have a quick look at
  • 17:58 - 18:00
    the TankManager script?
  • 18:00 - 18:02
    Because that is the first one
  • 18:02 - 18:04
    that we need to understand.
  • 18:06 - 18:08
    Double click on the icons to open both those scripts.
  • 18:09 - 18:12
    And make sure you're looking at the TankManager.
  • 18:13 - 18:15
    So the TankManager is already complete
  • 18:15 - 18:17
    and we'll go through that briefly now
  • 18:17 - 18:19
    so you can understand what it's doing,
  • 18:19 - 18:21
    what it's role is and how it interacts
  • 18:21 - 18:23
    with the GameManager.
  • 18:23 - 18:25
    Most of the scripts that we're dealing with
  • 18:25 - 18:27
    today and in fact all of them other than
  • 18:27 - 18:29
    this one are mono behaviours.
  • 18:29 - 18:32
    So after it says public class and then the
  • 18:32 - 18:34
    name of the class you've got a colon and then MonoBehaviour.
  • 18:36 - 18:38
    CameraControl : MonoBehaviour.
  • 18:38 - 18:40
    So what that means is that
  • 18:40 - 18:43
    this script you can drop on to a game object
  • 18:43 - 18:45
    and it will have functions
  • 18:45 - 18:47
    that are called back such as Awake, Start,
  • 18:47 - 18:49
    Update, Fixed Update, those sorts of things.
  • 18:50 - 18:52
    That's all part of mono behaviour.
  • 18:53 - 18:55
    But this one does not have that.
  • 18:55 - 18:57
    It's not inheriting from anything before that.
  • 18:58 - 19:00
    So everything that you see in TankManager
  • 19:00 - 19:02
    it it's own thing.
  • 19:02 - 19:04
    We've also go this attribute at the top,
  • 19:04 - 19:06
    Serializable, so what that's doing is
  • 19:06 - 19:08
    saying to Unity
  • 19:08 - 19:10
    'when you have an instance of this
  • 19:10 - 19:12
    you can show it in the inspector'.
  • 19:12 - 19:14
    Most of the time you don't need that because
  • 19:14 - 19:17
    by default fields are serializable.
  • 19:18 - 19:20
    But when you've got a class that you make yourself
  • 19:20 - 19:22
    you need to mark it as serializable
  • 19:22 - 19:24
    so that it'll show up in the inspector.
  • 19:25 - 19:27
    Okay, so let's have a look at the public variables.
  • 19:27 - 19:29
    So we already know the first two,
  • 19:29 - 19:31
    we've got the color, which is the color
  • 19:31 - 19:33
    the player is going to be when it's spawned,
  • 19:33 - 19:35
    the tank and it's name.
  • 19:36 - 19:38
    And we've got a transform representing the
  • 19:38 - 19:40
    spawn point so that's obviously where
  • 19:40 - 19:42
    and in what direction it's going to be spawned.
  • 19:42 - 19:44
    So very crucially, what you're actually seeing
  • 19:44 - 19:47
    here is the result of what you just
  • 19:47 - 19:49
    filled in in the inspector.
  • 19:49 - 19:51
    So in the inspector we have this thing called Tanks
  • 19:51 - 19:53
    so each of these elements is
  • 19:53 - 19:56
    effectively those two things,
  • 19:56 - 19:58
    these are individual tank managers and those are the
  • 19:58 - 20:00
    only things that are down in the inspector.
  • 20:01 - 20:04
    That's because the Tanks array in the Game Manager
  • 20:04 - 20:06
    is an array of tank managers.
  • 20:07 - 20:09
    So it's showing those
  • 20:09 - 20:11
    two because we've told it to but the rest
  • 20:11 - 20:13
    we're saying 'hide those from the inspector'.
  • 20:13 - 20:16
    so if I jump over to Game Manager really quickly.
  • 20:18 - 20:20
    so there's an array of TankManagers
  • 20:20 - 20:23
    so these classes called Tanks,
  • 20:23 - 20:26
    so that's why you're seeing that in the inspector.
  • 20:27 - 20:29
    Okay, so the rest of these public
  • 20:29 - 20:32
    fields we've got HideInInspector to stop it from
  • 20:32 - 20:34
    showing up because we don't want people to
  • 20:34 - 20:36
    be able to adjust those.
  • 20:36 - 20:38
    So first is the PlayerNumber, so that's going to filter
  • 20:38 - 20:40
    through to the shooting Script and the Movement script
  • 20:41 - 20:42
    to tell each of those scripts
  • 20:42 - 20:44
    what input it needs, because you'll remember
  • 20:44 - 20:47
    they're based on the PlayerNumber.
  • 20:47 - 20:50
    Next we've got m_ColoredPlayerText.
  • 20:50 - 20:52
    So you'll notice that when we
  • 20:52 - 20:54
    showed that little video the text
  • 20:54 - 20:56
    that came up was in the color of the player.
  • 20:57 - 21:00
    So the way you do that is you use
  • 21:00 - 21:02
    HTML-like rich text
  • 21:02 - 21:04
    and we'll show you how to do that in a moment,
  • 21:04 - 21:06
    but that's just a variable to store that.
  • 21:06 - 21:09
    Next we've got a game object which is
  • 21:09 - 21:11
    storing the instance of the tank.
  • 21:11 - 21:13
    So if we need to
  • 21:13 - 21:15
    turn anything on or off we need to
  • 21:15 - 21:17
    get that referenced through the instance.
  • 21:17 - 21:19
    And the number of wins that the
  • 21:19 - 21:21
    tank currently has, so when it
  • 21:21 - 21:23
    gets enough wins it'll win the game.
  • 21:23 - 21:25
    Next we've got a few private references
  • 21:25 - 21:29
    so we've got references to the TankMovement and TankShooting scripts
  • 21:29 - 21:32
    so we can turn those on and off when we need to.
  • 21:32 - 21:34
    And a reference to the Canvas game object
  • 21:34 - 21:37
    so that we can turn the UI on and off.
  • 21:38 - 21:40
    Next we've got a public function called Setup.
  • 21:40 - 21:42
    So this is public because it's going to be called by
  • 21:42 - 21:45
    the GameManager when it first creates these tanks.
  • 21:46 - 21:48
    Seeing as the tank has been created
  • 21:48 - 21:50
    it's going to find the references to
  • 21:50 - 21:52
    the Movement and Shooting scripts
  • 21:52 - 21:55
    by saying that the Instance, get component from the instance.
  • 21:56 - 21:58
    So set the instance, get the components there.
  • 22:00 - 22:02
    Next, a little bit more obtuse,
  • 22:03 - 22:05
    we've got the Canvas game object
  • 22:05 - 22:07
    so what it's going is it's got the instance,
  • 22:07 - 22:09
    it's finding a component of type
  • 22:09 - 22:11
    Canvas in it's children,
  • 22:11 - 22:13
    because you'll remember all of the UI is
  • 22:13 - 22:15
    underneath a canvas, so we're finding that
  • 22:15 - 22:17
    canvas in the children,
  • 22:18 - 22:20
    and then we're getting the game object that that's on.
  • 22:20 - 22:22
    That's what that bit is doing there.
  • 22:23 - 22:25
    Next we're setting the PlayerNumber on the
  • 22:25 - 22:27
    Movement and Shooting scripts.
  • 22:28 - 22:33
    And then there's the HTML-like rich text.
  • 22:33 - 22:34
    So this looks a little bit scary and confusing,
  • 22:34 - 22:36
    but basically what we're doing is taking bits
  • 22:36 - 22:39
    of the text and then putting stuff in between them.
  • 22:39 - 22:41
    So for example,
  • 22:41 - 22:43
    if you saw in the video earlier we showed,
  • 22:43 - 22:45
    at the end it says
  • 22:45 - 22:46
    'Player 1 - X amount of wins'
  • 22:46 - 22:49
    'Player 2 - X number of wins'.
  • 22:49 - 22:52
    So what we're doing with this is we're just
  • 22:52 - 22:54
    adding bits to a string.
  • 22:54 - 22:56
    So this is a string here, in inverted commas,
  • 22:56 - 22:58
    and then we add to it something that's
  • 22:58 - 23:00
    converting a piece of code
  • 23:00 - 23:02
    to a particular color by using
  • 23:02 - 23:04
    this thing called ColorUtility
  • 23:04 - 23:06
    ToHtmlStringRGB, very long winded thing but
  • 23:06 - 23:08
    it basically takes in a color,
  • 23:08 - 23:10
    and will then color whatever
  • 23:10 - 23:13
    the text is after that, and the thing it's coloring is Player.
  • 23:14 - 23:16
    So if you've seen HTML before you'll know that
  • 23:16 - 23:19
    HTML tags fit inside angled brackets.
  • 23:19 - 23:21
    So it starts here, it then says
  • 23:21 - 23:23
    the color that I should color it is
  • 23:24 - 23:25
    this thing that takes in the PlayerColor,
  • 23:25 - 23:28
    so that will result in a color reference.
  • 23:28 - 23:30
    Now we finish that tag
  • 23:30 - 23:32
    and the piece of text its actually coloring
  • 23:32 - 23:33
    is the word Player.
  • 23:33 - 23:35
    Then we put in a space.
  • 23:36 - 23:38
    Then we put in the PlayerNumber
  • 23:39 - 23:41
    And then we finish coloring.
  • 23:41 - 23:43
    So all of that stuff is saying
  • 23:43 - 23:45
    'Player 1 in particular color
  • 23:45 - 23:47
    by using this rich text'.
  • 23:48 - 23:50
    It looks a bit lengthy but once you piece
  • 23:50 - 23:52
    through it it makes sense.
  • 23:52 - 23:54
    And like I said, have a look at the completed scripts,
  • 23:54 - 23:56
    it will have all the comments in there to tell you
  • 23:56 - 23:57
    exactly what we're doing.
  • 23:57 - 24:01
    So the next line is getting an array of mesh renderers.
  • 24:01 - 24:03
    So mesh renderers are the things
  • 24:03 - 24:05
    that actually show up your
  • 24:05 - 24:07
    3D objects in the scene.
  • 24:07 - 24:09
    So the tank is made up of
  • 24:09 - 24:11
    a series of mesh renderers, like one for the
  • 24:11 - 24:14
    tracks, one for the chassis, one for the turret, etcetera.
  • 24:14 - 24:16
    I'm just going to show that real quick.
  • 24:16 - 24:18
    So I've just dragged in my prefab
  • 24:18 - 24:20
    just to demonstrate but you'll see there's this mesh renderer
  • 24:20 - 24:23
    component and if I toggle things on and off
  • 24:23 - 24:25
    they disappear because they're not being rendered any more.
  • 24:26 - 24:28
    That's just what a mesh renderer is doing.
  • 24:29 - 24:31
    Okay we're making an array of mesh renderers
  • 24:31 - 24:35
    called Renderers and we're setting that to
  • 24:35 - 24:37
    all of the components in Children
  • 24:37 - 24:38
    that are mesh renderers.
  • 24:38 - 24:42
    So the instance, get the components in the children
  • 24:42 - 24:44
    that are mesh renderers and return them.
  • 24:44 - 24:46
    And then what we do is we loop through all of
  • 24:46 - 24:50
    those renderers and set their material's color
  • 24:51 - 24:52
    to the player's color.
  • 24:52 - 24:55
    So all that's doing is it's finding all the mesh renderers,
  • 24:55 - 24:57
    getting the color and changing it to the player color
  • 24:57 - 24:59
    that we chose.
  • 24:59 - 25:01
    Then we've got just a few more public functions
  • 25:01 - 25:03
    that are going to be called by the Game Manager.
  • 25:03 - 25:05
    We've got DisableControl which
  • 25:05 - 25:07
    turns off the script and
  • 25:07 - 25:09
    turns off the canvas and we've got
  • 25:09 - 25:11
    EnableControl that turns on the script
  • 25:11 - 25:13
    and turns on the canvas.
  • 25:13 - 25:14
    Finally we've got Reset.
  • 25:14 - 25:16
    So what Reset does is
  • 25:16 - 25:18
    it sets the
  • 25:18 - 25:20
    instance back to it's spawn point.
  • 25:21 - 25:23
    It turns it off and then
  • 25:23 - 25:25
    it turns it back on again and the reason it
  • 25:25 - 25:27
    does that is that all of
  • 25:27 - 25:29
    the tank's apart from the winner
  • 25:29 - 25:31
    will be off, but we need to
  • 25:31 - 25:33
    reset all of them so we need to turn
  • 25:33 - 25:35
    everything off first before
  • 25:35 - 25:37
    we can turn it back on again.
  • 25:37 - 25:39
    Okay, so that's all there is to TankManager.
  • 25:40 - 25:42
    Let's see about the GameManager.
  • 25:42 - 25:44
    So just to jump back to this slide real quick.
  • 25:44 - 25:46
    As we've said the Game Manager is
  • 25:46 - 25:48
    using an array of TankManagers,
  • 25:48 - 25:50
    so when we look at the GameManager in a second
  • 25:50 - 25:52
    we're going to see that at the start
  • 25:52 - 25:54
    it's going to use the TankManagers to spawn those.
  • 25:54 - 25:56
    So those were the instances that you just saw
  • 25:56 - 25:58
    referenced inside TankManager.
  • 25:59 - 26:01
    And then we're going to get in to actually
  • 26:01 - 26:03
    looping through things.
  • 26:03 - 26:05
    So let's take a look at that.
  • 26:06 - 26:08
    So if you switch over to the GameManager script you should
  • 26:08 - 26:11
    see the stuff that we're looking at right now.
  • 26:11 - 26:13
    Either that or you can look at the screen.
  • 26:13 - 26:15
    So there are three blocks of comments in this one.
  • 26:15 - 26:18
    There's one at lines 19 and 21.
  • 26:19 - 26:21
    I'm just going to remove those.
  • 26:22 - 26:28
    There is one at line 66 to line 74.
  • 26:30 - 26:32
    And then there's a really long one
  • 26:32 - 26:35
    which is line 108
  • 26:36 - 26:39
    all the way down to 152.
  • 26:41 - 26:43
    Cool, so apologies, we had to comment those
  • 26:43 - 26:45
    out otherwise you would have seen some warnings
  • 26:45 - 26:47
    and queries in the console that
  • 26:47 - 26:50
    kind of make it awkward for us to teach you stuff,
  • 26:50 - 26:52
    so we just commented those out.
  • 26:53 - 26:55
    Okay, so we've already gone over the
  • 26:55 - 26:57
    public variables, I won't bore you by doing it again.
  • 26:57 - 26:59
    The private variables,
  • 26:59 - 27:02
    so we've got an integer which stores the current round number.
  • 27:02 - 27:04
    So obviously as it counts up then you get
  • 27:04 - 27:06
    to display what the current round number
  • 27:06 - 27:07
    is when it starts.
  • 27:07 - 27:11
    Then we've got these two WaitForSeconds things.
  • 27:11 - 27:16
    So in coroutines you can put
  • 27:16 - 27:18
    a delay in your function course.
  • 27:18 - 27:20
    What is a coroutine James?
  • 27:20 - 27:22
    I think we'll cover that shortly.
  • 27:22 - 27:23
    Good idea.
  • 27:23 - 27:25
    But basically these WaitForSeconds things
  • 27:25 - 27:27
    are what a coroutine is looking for a
  • 27:27 - 27:29
    delay so we've got a start delay
  • 27:29 - 27:31
    and an end delay.
  • 27:31 - 27:33
    We'll change those in to these WaitForSeconds
  • 27:33 - 27:35
    classes so we can use them.
  • 27:36 - 27:39
    So basically we have a little pause within a function,
  • 27:39 - 27:41
    but they need to be converted to a type that is called
  • 27:41 - 27:43
    WaitForSeconds and you'll see why shortly when
  • 27:43 - 27:44
    we explain coroutines.
  • 27:44 - 27:46
    Okay then the last two things we've got,
  • 27:46 - 27:48
    two instances of TankManagers,
  • 27:48 - 27:50
    so they're referring to specific tanks
  • 27:50 - 27:52
    that are the RoundWinner and the GameWinner.
  • 27:52 - 27:54
    And we'll use those for the
  • 27:54 - 27:57
    message at the end of each round.
  • 27:58 - 28:00
    So next we've got this start function,
  • 28:00 - 28:02
    which is setting up those WaitForSeconds.
  • 28:02 - 28:04
    So we've got a StartDelay and an EndDelay,
  • 28:04 - 28:06
    which are just numbers in seconds
  • 28:06 - 28:08
    and then we're creating new WaitForSeconds
  • 28:08 - 28:10
    for the start and the end.
  • 28:11 - 28:14
    Then we've got SpawnAllTanks function
  • 28:14 - 28:16
    and SetCameraTargets function.
  • 28:16 - 28:18
    We'll cover those now and then come back
  • 28:18 - 28:20
    that StartCoroutine thing at the end.
  • 28:20 - 28:22
    So SpawnAllTanks.
  • 28:22 - 28:24
    All that's doing is it's going to loop through
  • 28:24 - 28:26
    the TankManagers.
  • 28:27 - 28:29
    For each TankManager it's going to
  • 28:29 - 28:31
    set the instance belonging to that TankManager
  • 28:33 - 28:35
    to an instantiated prefab,
  • 28:35 - 28:37
    so we're calling Instantiate(m_TankPrefab,
  • 28:38 - 28:41
    and then we're spawning it at the spawn point of the tanks.
  • 28:41 - 28:43
    With the same rotation.
  • 28:43 - 28:45
    So this may look confusing but it's basically a long
  • 28:45 - 28:47
    line that we've moved on to a new
  • 28:47 - 28:49
    line because it doesn't make any difference and it's easier
  • 28:49 - 28:51
    to fit on a projector.
  • 28:51 - 28:53
    So we're just instantiating
  • 28:53 - 28:55
    a tank per instance as required.
  • 28:57 - 28:59
    Okay, so now we've created the tank
  • 28:59 - 29:01
    we want to set it's player number,
  • 29:01 - 29:03
    and since this loop is going from 0
  • 29:03 - 29:05
    upwards that doesn't really
  • 29:05 - 29:07
    work as nicely as starting from
  • 29:07 - 29:10
    1 so we're just saying that the PlayerNumber is i + 1,
  • 29:10 - 29:12
    so it starts at 0 so
  • 29:12 - 29:14
    the PlayerNumber would start at 1,
  • 29:14 - 29:15
    and so on.
  • 29:15 - 29:17
    Otherwise when you start the game you'd get
  • 29:17 - 29:19
    'Player 01,
  • 29:19 - 29:22
    Player 1 failed', you don't want that.
  • 29:22 - 29:24
    so you need to just add 1
  • 29:24 - 29:26
    in a minimum of Player1, Player2 and so on.
  • 29:27 - 29:29
    And then finally for each tank we're
  • 29:29 - 29:31
    going to call that Setup function which is the first
  • 29:31 - 29:33
    function that we covered in TankManagers.
  • 29:33 - 29:35
    Just a quick reminder,
  • 29:35 - 29:37
    TankManagers - Setup.
  • 29:37 - 29:39
    So it's the thing that's in charge of
  • 29:39 - 29:42
    movement, shooting and coloring and whatnot.
  • 29:46 - 29:49
    SetCameraTargets, we're creating an array of
  • 29:49 - 29:51
    transforms called Targets
  • 29:51 - 29:53
    and we're setting it to be the same length as
  • 29:53 - 29:55
    the TankManagers array.
  • 29:55 - 29:57
    Then we're going to loop through this Targets array
  • 29:59 - 30:01
    and we're going to set
  • 30:01 - 30:03
    each target equal to
  • 30:05 - 30:08
    the TankManager's instances transform.
  • 30:08 - 30:10
    So each tank's instance
  • 30:10 - 30:12
    that transform.
  • 30:13 - 30:15
    And then finally we can set the
  • 30:15 - 30:17
    CameraControl's targets to
  • 30:17 - 30:19
    this Targets array that we just created.
  • 30:19 - 30:21
    so we're just looking at the TankManager
  • 30:21 - 30:23
    and saying 'here's all the positions
  • 30:23 - 30:25
    of the tanks you've just created,
  • 30:25 - 30:28
    and we'll just assign them to the CameraControl script'.
  • 30:29 - 30:31
    Okay, so the last thing that
  • 30:31 - 30:33
    the Start function did was
  • 30:33 - 30:36
    it did something called Start Coroutine
  • 30:36 - 30:38
    and then it had a function within
  • 30:38 - 30:40
    it's parameters, which is a bit weird.
  • 30:42 - 30:44
    So let's find out what that's all about.
  • 30:46 - 30:48
    So just to jump back to the slides,
  • 30:48 - 30:50
    so we've just been talking about Start
  • 30:50 - 30:52
    and what actually happens there, and we say that
  • 30:52 - 30:54
    it starts the GameLoop to continue.
  • 30:54 - 30:56
    So it's starting the GameLoop coroutines.
  • 30:56 - 30:58
    But we haven't talked about these yet, we're talked about functions
  • 30:58 - 31:00
    and how you can use those.
  • 31:00 - 31:02
    We need to talk about coroutines.
  • 31:02 - 31:05
    So the GameLoop
  • 31:05 - 31:07
    is going to start the round.
  • 31:07 - 31:09
    Obviously you're going to start the round, people are going
  • 31:09 - 31:11
    to start playing, driving around.
  • 31:11 - 31:13
    It's then going to wait.
  • 31:13 - 31:15
    And then they're going to be playing, so this is when
  • 31:15 - 31:17
    they're actually firing, shooting each other, running around,.
  • 31:18 - 31:20
    Then it's going to wait.
  • 31:21 - 31:23
    And then the round is going to end.
  • 31:23 - 31:25
    Ordinarily in functions, when you run a function
  • 31:25 - 31:27
    all the commands just go straight through
  • 31:27 - 31:29
    and something happens or you'll loop through
  • 31:29 - 31:31
    something but it's instantaneous.
  • 31:31 - 31:33
    But often in programming we need to
  • 31:33 - 31:36
    to kind of pause and do what we call Yield
  • 31:36 - 31:38
    and wait for a certain number of seconds or
  • 31:38 - 31:40
    wait for a certain condition to be valid.
  • 31:40 - 31:42
    And that's where coroutines come in.
  • 31:44 - 31:46
    So an ordinary function might look like
  • 31:46 - 31:49
    this - void, a non-return type and then
  • 31:49 - 31:51
    the name of the function ()
  • 31:52 - 31:55
    and then some commands within that.
  • 31:56 - 31:58
    Whereas a coroutine
  • 32:00 - 32:02
    has, first off you'll notice a different
  • 32:02 - 32:04
    return type, instead of void
  • 32:04 - 32:06
    we have this thing called IEnumerator.
  • 32:06 - 32:08
    As if the word coroutine wasn't weird enough
  • 32:08 - 32:11
    you now have something else to worry about,
  • 32:11 - 32:14
    IEnumberator, but don't be afraid of that,
  • 32:14 - 32:16
    it's just the return type.
  • 32:16 - 32:18
    And you'll also notice within this we have the
  • 32:18 - 32:20
    word yield in the middle of it.
  • 32:20 - 32:22
    So
  • 32:23 - 32:26
    what we can do is start some basic
  • 32:26 - 32:28
    commands or anything that we want to happen
  • 32:28 - 32:30
    straight away like any old function
  • 32:30 - 32:32
    but then we can stop at this point called yield.
  • 32:33 - 32:35
    At the point where you come in to contact
  • 32:35 - 32:37
    with yield what happens is
  • 32:37 - 32:39
    execution exits that function.
  • 32:40 - 32:42
    It goes away.
  • 32:42 - 32:45
    Then it waits for a certain period of time
  • 32:45 - 32:47
    or some condition to be true.
  • 32:47 - 32:49
    And then after that period of time
  • 32:49 - 32:51
    or that condition it comes back
  • 32:51 - 32:53
    in again at the same point that it yielded.
  • 32:54 - 32:56
    And then it will continue on with the coroutine.
  • 32:57 - 33:00
    So instead of just going straight through
  • 33:00 - 33:02
    and doing everything instantly
  • 33:02 - 33:04
    you put in a little pause in the middle of your
  • 33:04 - 33:06
    function, which could be very useful.
  • 33:07 - 33:09
    And it becomes really useful when you
  • 33:09 - 33:11
    start putting things like While Loops in
  • 33:12 - 33:14
    So what you can do
  • 33:14 - 33:16
    is have a while loop like this
  • 33:16 - 33:18
    with a yield instruction in the middle.
  • 33:19 - 33:20
    So if you haven't heard of while loops,
  • 33:20 - 33:22
    it's kind of like if you think of an if statement of
  • 33:22 - 33:24
    checking a condition a while loop is just there
  • 33:24 - 33:26
    to say 'whilst this thing is still true,
  • 33:26 - 33:28
    then we're going to do what's in those brackets'.
  • 33:29 - 33:31
    Okay, so in this coroutine
  • 33:32 - 33:34
    the first part of the function would start normally,
  • 33:34 - 33:36
    then it would hit the while loop,
  • 33:36 - 33:39
    so let's suppose that the condition is true.
  • 33:39 - 33:41
    It goes in to the while while loop and hits that yield.
  • 33:41 - 33:43
    Then it leaves again,
  • 33:44 - 33:46
    waits for some period of time,
  • 33:46 - 33:48
    and then comes back in to the yield
  • 33:48 - 33:50
    and continues with that while loop.
  • 33:50 - 33:52
    Whilst within a loop we've exited
  • 33:52 - 33:55
    and then come back in again after a period of time.
  • 33:56 - 33:59
    So supposing that that condition is still true,
  • 33:59 - 34:02
    we'll then go back in to the same while loop.
  • 34:02 - 34:04
    So let's say for example,
  • 34:04 - 34:06
    this might come up, we say that
  • 34:06 - 34:08
    the condition for that while loop is while there is
  • 34:08 - 34:10
    more than 1 tank left
  • 34:10 - 34:11
    keep doing this loop.
  • 34:11 - 34:13
    And then let's say that the yield was
  • 34:13 - 34:15
    come back next frame.
  • 34:16 - 34:18
    So then what we'd have is a function that wouldn't
  • 34:18 - 34:21
    finish until there was
  • 34:21 - 34:23
    only 1 tank left.
  • 34:24 - 34:26
    So you'd say while there
  • 34:26 - 34:28
    is not 1 tank left
  • 34:28 - 34:30
    do this, come back next frame.
  • 34:30 - 34:33
    Oh there's still not 1 tank left, come back next frame.
  • 34:33 - 34:35
    Oh there's still not 1 tank left, come back next frame.
  • 34:35 - 34:38
    Until there was, and then the function would finish.
  • 34:38 - 34:40
    Could be quite useful.
  • 34:40 - 34:42
    You remember the start function calls
  • 34:42 - 34:44
    StartCoroutine?
  • 34:44 - 34:47
    The coroutine that it's starting is the GameLoop.
  • 34:47 - 34:49
    So let's have a quick look at the GameLoop.
  • 34:49 - 34:51
    To see what's going on there.
  • 34:51 - 34:53
    GameLoop is saying
  • 34:53 - 34:56
    yield return StartCoroutine(RoundStarting());
  • 34:57 - 34:59
    So do you remember when it says yield it
  • 34:59 - 35:01
    waits for whatever it's got to the right
  • 35:01 - 35:03
    of it to finish before it continues on.
  • 35:04 - 35:07
    So when it's saying yield return StartCoroutine
  • 35:07 - 35:09
    it's waiting for that coroutine to finish
  • 35:09 - 35:12
    before it goes on to the next one.
  • 35:12 - 35:14
    So what's going to happen here is it's going to do
  • 35:14 - 35:17
    RoundStarting, wait for RoundStarting to finish,
  • 35:17 - 35:19
    then come back in, then it's going to do RoundPlaying,
  • 35:19 - 35:22
    wait for RoundPlaying to finish, then it's going to come back
  • 35:22 - 35:24
    etcetera for RoundEnding.
  • 35:24 - 35:26
    Finally we're going to check if there is a GameWinner
  • 35:26 - 35:29
    so if GameWinner is not equal to null.
  • 35:30 - 35:32
    So if there is a GameWinner then load
  • 35:32 - 35:35
    the current level, Application.LoadLevel
  • 35:35 - 35:38
    loadedLevel, that's just reloading this current level.
  • 35:38 - 35:40
    If there isn't a GameWinner then it's going to call StartCoroutine
  • 35:40 - 35:42
    and notice that there is no
  • 35:42 - 35:44
    yield return on that bit.
  • 35:44 - 35:46
    So it's not going to wait and then come back
  • 35:46 - 35:49
    in we're just going to call that then the
  • 35:49 - 35:51
    function will finish and there will be another GameLoop running.
  • 35:52 - 35:54
    So now we're getting to the point where we're looking
  • 35:54 - 35:58
    at how the GameManager and TankManagers interplay.
  • 35:58 - 36:01
    So this slide is going to kind of populate over time
  • 36:01 - 36:03
    but the way that we're going to do this is we're going to
  • 36:03 - 36:05
    animate in each point, we're going to talk about it and then
  • 36:05 - 36:07
    we're going to fill in that part of the script, so hopefully
  • 36:07 - 36:09
    we can kind of step you guys through it and it
  • 36:09 - 36:10
    will make sense.
  • 36:10 - 36:13
    So we've just talked about the GameLoop.
  • 36:14 - 36:17
    So the GameLoop starts off with
  • 36:17 - 36:19
    the RoundStarting.
  • 36:20 - 36:21
    So the first thing that needs to happen
  • 36:21 - 36:23
    in the RoundStarting is we need to reset
  • 36:23 - 36:25
    all the tanks, so we need to
  • 36:25 - 36:27
    set them up at their positions on the spawn points,
  • 36:27 - 36:30
    we need to enable their controls
  • 36:30 - 36:32
    and all these kind of things.
  • 36:32 - 36:34
    So the way that we do that is to parse to the
  • 36:34 - 36:36
    TankManager and 'hey, can you reset everything
  • 36:36 - 36:38
    and reposition everything?' and that's what the
  • 36:38 - 36:40
    TankManager does, so every tank remember has a
  • 36:40 - 36:44
    TankManager assigned to it and we do that.
  • 36:44 - 36:46
    We start off our GameLoop, we reset the tanks,
  • 36:46 - 36:48
    and the TankManager's in charge of resetting
  • 36:48 - 36:51
    things so De/Reactivating
  • 36:51 - 36:53
    and setting the positions back where they should be.
  • 36:53 - 36:55
    And we start off by disabling
  • 36:55 - 36:57
    all the tank controls.
  • 36:57 - 36:59
    And we have in the TankManager DisableControl()
  • 36:59 - 37:01
    so we can't move,
  • 37:01 - 37:03
    shoot and the UI is off.
  • 37:03 - 37:05
    When the game starts you'll see Round 1
  • 37:05 - 37:07
    and the tanks are there but they don't have
  • 37:07 - 37:09
    their Health UI just yet.
  • 37:10 - 37:12
    Then we do three more things
  • 37:12 - 37:14
    to start the round, we need to setup the camera position
  • 37:14 - 37:16
    and the size, so in other words
  • 37:16 - 37:18
    we take an average of the two tank's positions
  • 37:18 - 37:20
    and we setup the zoom using the size.
  • 37:21 - 37:23
    We increment the round number so it will,
  • 37:23 - 37:26
    if it's 0 we make it Round 1.
  • 37:26 - 37:28
    And then we setup the Message UI which will
  • 37:28 - 37:31
    say either Round 1 or whatever is appropriate.
  • 37:31 - 37:33
    So let's go and actually look at
  • 37:33 - 37:35
    that in the script now.
  • 37:37 - 37:39
    So currently RoundStarting just
  • 37:39 - 37:41
    has this yield return m_StartWait
  • 37:41 - 37:43
    so all it's going to do is wait for
  • 37:43 - 37:46
    3 seconds and then do nothing else.
  • 37:47 - 37:49
    So what we want to do is put in a
  • 37:49 - 37:50
    little bit of code before that.
  • 37:50 - 37:53
    First off we said we wanted to reset all of the tanks.
  • 37:53 - 37:55
    So before the yield return
  • 37:57 - 37:59
    put a couple of lines so you've got some space and
  • 37:59 - 38:02
    we've got a function called ResetAllTanks.
  • 38:04 - 38:06
    So put a call to that.
  • 38:07 - 38:10
    Next we'll put DisableTankControl
  • 38:10 - 38:12
    because we don't want people to be able to
  • 38:12 - 38:15
    control their tanks while the round is actually starting.
  • 38:15 - 38:17
    We want to wait for the RoundPlaying for them to be
  • 38:17 - 38:19
    able to control everything.
  • 38:20 - 38:22
    Then you remember we wanted to make sure that
  • 38:22 - 38:24
    the camera is set to that
  • 38:24 - 38:26
    exact size and position.
  • 38:26 - 38:28
    We don't want it to smoothly transition
  • 38:28 - 38:30
    to that, we want to set it.
  • 38:30 - 38:32
    So on the camera control,
  • 38:32 - 38:40
    so m_CameraControl.SetStartPositionAndSize()
  • 38:41 - 38:43
    So all that's doing is on the camera
  • 38:43 - 38:45
    control calling the function.
  • 38:46 - 38:48
    Next we want to increment the round number
  • 38:48 - 38:50
    because a new round has just started.
  • 38:51 - 38:54
    So that's m_RoundNumber++;
  • 38:54 - 38:57
    All that does is just add 1 to that round number.
  • 38:58 - 39:00
    And now we've got the incremented round number
  • 39:00 - 39:02
    we can set the message text
  • 39:02 - 39:04
    to be something appropriate like
  • 39:04 - 39:06
    Round and then the round number.
  • 39:06 - 39:13
    So m_MessageText.text because it's the text part of the text
  • 39:13 - 39:15
    component, well named isn't it?
  • 39:18 - 39:23
    And we're going to set that to Round + m_RoundNumber
  • 39:23 - 39:25
    Now it's very crucial here that you put
  • 39:25 - 39:28
    Round and then a space inside your string,
  • 39:28 - 39:30
    otherwise it will say, it will just say
  • 39:30 - 39:32
    Round1 like that on the screen, which you don't want.
  • 39:32 - 39:34
    So make sure you put a space in the string
  • 39:34 - 39:36
    and then we're adding on the actual number
  • 39:36 - 39:38
    on to the end of that, and it will
  • 39:38 - 39:40
    parse it straight in to the UI text.
  • 39:40 - 39:42
    Okay, so let's save the script
  • 39:42 - 39:45
    there and give that a test, see how that all works.
  • 39:45 - 39:48
    Okay, so I'm going to save my script, switch back to Unity.
  • 39:50 - 39:52
    And I'm going to press Play.
  • 39:56 - 39:59
    Okay, so this isn't working as well as I thought it might.
  • 40:00 - 40:02
    Interestingly it's just counting up the rounds.
  • 40:02 - 40:04
    Why would that be James?
  • 40:05 - 40:07
    Probably we need to actually
  • 40:07 - 40:09
    enable the control in, like,
  • 40:09 - 40:11
    the RoundPlaying bit, that'll probably do it.
  • 40:11 - 40:13
    Okay, so what we've done so far is
  • 40:13 - 40:15
    to say 'we want to start the round', and all that
  • 40:15 - 40:17
    RoundStart knows how to do is
  • 40:17 - 40:21
    to setup the UI, setup the tanks and then just be like
  • 40:21 - 40:23
    'okay, well I'm going to wait,
  • 40:23 - 40:25
    oh hey, there's a new round, I'll wait now,
  • 40:25 - 40:26
    oh hey, there's a new round'.
  • 40:26 - 40:28
    It doesn't actually let us play the game, because we didn't do that
  • 40:28 - 40:30
    bit yes, so I'm going to stop play
  • 40:30 - 40:32
    and jump back in to my code.
  • 40:33 - 40:36
    Okay so RoundPlaying, we've got this
  • 40:36 - 40:38
    yield return null there
  • 40:38 - 40:40
    so what yield return null means
  • 40:40 - 40:42
    is 'come back the next frame',
  • 40:42 - 40:44
    that's all it's doing there.
  • 40:44 - 40:46
    So just to jump back to the slide.
  • 40:47 - 40:49
    As we've said before, we've done RoundStarting
  • 40:49 - 40:51
    and those are the things that happen
  • 40:51 - 40:53
    TankManager is taking care of the
  • 40:53 - 40:55
    Resetting and DisablingControl so that's all good.
  • 40:55 - 40:58
    But RoundPlaying, so what do we do in RoundPlaying?
  • 40:58 - 41:00
    Well we need to enable the TankControl when we
  • 41:00 - 41:03
    played just now we noticed you couldn't drive or shoot.
  • 41:04 - 41:06
    So EnableControl is in TankManager.
  • 41:06 - 41:08
    It can move, it can shoot and it sets up the UI.
  • 41:09 - 41:11
    And the thing it needs to do is empty that message.
  • 41:11 - 41:13
    So as soon as we start playing we don't want to see
  • 41:13 - 41:15
    the word Round 1 on the screen, we want to scrub that out.
  • 41:15 - 41:17
    So we don't disable the UI or do anything
  • 41:17 - 41:20
    else we just empty the message string.
  • 41:20 - 41:23
    And then as James was saying earlier with the coroutine
  • 41:23 - 41:26
    we just keep waiting until there's one tank left.
  • 41:26 - 41:28
    Let's see how we write that.
  • 41:29 - 41:31
    So at the start as it said on the slide
  • 41:31 - 41:33
    we want to enable TankControl
  • 41:33 - 41:36
    so you can actually play the game.
  • 41:36 - 41:38
    So we've got a function that does that
  • 41:38 - 41:40
    and all this function does is loops
  • 41:40 - 41:43
    through all the tanks and calls their EnableControl.
  • 41:43 - 41:45
    So nothing really to it.
  • 41:46 - 41:48
    Next we want to empty that
  • 41:48 - 41:52
    message text, so m_MessageText.text
  • 41:53 - 41:57
    = string.Empty so that's just a blank string.
  • 42:00 - 42:02
    Naturally you could also just
  • 42:02 - 42:04
    do that if you wanted to,
  • 42:04 - 42:05
    but we're not doing it that way, we're going to go with
  • 42:05 - 42:07
    the string.Empty.
  • 42:09 - 42:11
    Okay, so it's looking good so far
  • 42:11 - 42:13
    but now all it's going to do
  • 42:13 - 42:16
    is it's going to enable the TankControl,
  • 42:16 - 42:18
    blank the string and then wait
  • 42:18 - 42:20
    at one frame and then
  • 42:20 - 42:22
    go on to the round ending.
  • 42:22 - 42:24
    So we don't want that, what we want is to
  • 42:24 - 42:27
    use that while loop that we saw earlier.
  • 42:27 - 42:29
    So for a while loop it's
  • 42:29 - 42:32
    while( and then the condition
  • 42:32 - 42:34
    within the ).
  • 42:34 - 42:36
    So we've got a function that's
  • 42:36 - 42:38
    OneTankLeft which returns true if the
  • 42:38 - 42:40
    there is one tank left, or less.
  • 42:42 - 42:44
    Yeah, there is a condition where it can be a draw,
  • 42:44 - 42:45
    you'll see.
  • 42:46 - 42:48
    Yeah, so this will keep
  • 42:48 - 42:50
    doing whatever is within the brackets
  • 42:51 - 42:53
    as long as there is
  • 42:53 - 42:55
    not one tank left.
  • 42:55 - 42:57
    So the thing that needs to go in there is
  • 42:57 - 42:59
    our yield return null.
  • 42:59 - 43:01
    What I should be doing with my while loop
  • 43:01 - 43:03
    is placing it around yield return null.
  • 43:05 - 43:07
    Like that.
  • 43:09 - 43:11
    Adding lots of lines for no reason.
  • 43:11 - 43:13
    There we go.
  • 43:13 - 43:15
    So until that's true it's just going to keep
  • 43:15 - 43:17
    going away one frame and waiting for it to become true.
  • 43:18 - 43:20
    Okay, we'll save that,
  • 43:20 - 43:22
    switch back to Unity,
  • 43:22 - 43:24
    and I'm going to hit Play and see what happens.
  • 43:27 - 43:29
    Okay, I've just muted my audio for the sake of everyone
  • 43:29 - 43:31
    So I knew it, I can drive around.
  • 43:31 - 43:33
    That's pretty cool,
  • 43:33 - 43:35
    I can shoot stuff.
  • 43:36 - 43:39
    Okay, so this is maybe a point to, you know,
  • 43:39 - 43:41
    hook up with a neighbour and start
  • 43:41 - 43:43
    shooting at each other, but,
  • 43:43 - 43:45
    what you'll also notice is that
  • 43:45 - 43:49
    that's great, now I can move around,
  • 43:49 - 43:51
    but I've got no idea who won that round or what happened.
  • 43:51 - 43:53
    I'll just keep infinitely adding new rounds and
  • 43:53 - 43:57
    keep playing in an endless war,
  • 43:57 - 44:00
    which I think we all know is wrong.
  • 44:04 - 44:06
    So we need to have a RoundEnding,
  • 44:06 - 44:08
    we need something to happen, we need some logic
  • 44:08 - 44:10
    to say 'what's going to happen when one tank
  • 44:10 - 44:12
    kills the other tank?'
  • 44:12 - 44:14
    So back to our slides.
  • 44:17 - 44:19
    RoundEnding is our next coroutine
  • 44:19 - 44:21
    within the overall loop.
  • 44:22 - 44:24
    So the first thing we need to do is
  • 44:24 - 44:26
    really disable the controls.
  • 44:26 - 44:28
    It's kind of great to be driving around and
  • 44:28 - 44:30
    showboating once you've won the game, but,
  • 44:30 - 44:34
    yeah, it's a little bit jazzy for my tastes.
  • 44:34 - 44:36
    So really we're going to disable the Tank Controls
  • 44:36 - 44:38
    you're going to stop dead, the camera is going to
  • 44:38 - 44:40
    focus in on where you are, it kind of puts a
  • 44:40 - 44:42
    nice pause in the game as well.
  • 44:42 - 44:44
    And then we're going to clear the existing
  • 44:44 - 44:46
    RoundWinner, so if we've already had a
  • 44:46 - 44:48
    round played we want to clear out that winner
  • 44:48 - 44:50
    and decide who's just won this round.
  • 44:51 - 44:53
    We want to check to see if any of
  • 44:53 - 44:55
    the round winner's have 5
  • 44:55 - 44:58
    rounds won and therefore are them game winner.
  • 44:58 - 45:00
    And then we want to put that in to the
  • 45:00 - 45:02
    Message UI and say 'okay, well first off
  • 45:02 - 45:05
    this person just won the round,
  • 45:05 - 45:07
    this tank has this many kills, this tank has
  • 45:07 - 45:09
    this many kills'.
  • 45:09 - 45:11
    Or we're going to say 'hey, this person
  • 45:11 - 45:13
    won the entire game'.
  • 45:14 - 45:16
    So let's have a look at how that works.
  • 45:17 - 45:20
    So back in our code the next coroutine,
  • 45:20 - 45:23
    remember IEnumerator means coroutine.
  • 45:24 - 45:27
    And we've currently got a yield that's got the EndWait.
  • 45:27 - 45:29
    So before we wait
  • 45:29 - 45:31
    we need to do a bunch of stuff.
  • 45:31 - 45:33
    Like we said, we're going to disable TankControl,
  • 45:34 - 45:36
    so we'll call that DisableTankControl function.
  • 45:37 - 45:40
    Next we said we need to clear out our RoundWinner
  • 45:40 - 45:42
    before we can check for another one.
  • 45:42 - 45:44
    So what we're going to do is
  • 45:44 - 45:48
    set m_RoundWinner to equal null.
  • 45:49 - 45:50
    So that's just saying
  • 45:50 - 45:53
    'for this round we don't know who's won yet,
  • 45:53 - 45:54
    we'll need to check'.
  • 45:54 - 45:56
    So the RoundWinners remember are
  • 45:56 - 45:58
    TankManagers, so it's referring to a
  • 45:58 - 46:01
    particular tank, same for the GameWinner.
  • 46:01 - 46:03
    It's referring to a particular tank via
  • 46:03 - 46:05
    it's TankManager.
  • 46:07 - 46:10
    So once we're not sure if there's a RoundWinner
  • 46:10 - 46:12
    we then can check, so we say that
  • 46:12 - 46:19
    m_RoundWinner = GetRoundWinner.
  • 46:21 - 46:23
    So what that's going to do is
  • 46:23 - 46:25
    it will assume that there is one
  • 46:25 - 46:27
    or fewer tanks left,
  • 46:27 - 46:29
    and then go through all of them until it finds
  • 46:29 - 46:31
    one that's active and return it.
  • 46:31 - 46:32
    Shall we have a look at that function?
  • 46:32 - 46:34
    Yeah we can have a quick look at that.
  • 46:34 - 46:36
    So if you scroll down, it's around
  • 46:36 - 46:38
    130 for me but it might be a bit different for you.
  • 46:38 - 46:40
    But what you'll see is GetRoundWinner.
  • 46:40 - 46:42
    And it's going to go through all of the tanks.
  • 46:43 - 46:45
    So it's looking for the array, looking for everyone
  • 46:45 - 46:47
    in the array, IE the length of the array.
  • 46:48 - 46:50
    And then if it finds a TankManager
  • 46:50 - 46:52
    who's instance if active
  • 46:52 - 46:54
    So it's activeSelf is true.
  • 46:54 - 46:57
    And it's going to return that tanks.
  • 46:58 - 47:00
    If it gets all the way through the array
  • 47:00 - 47:03
    and hasn't found anything,
  • 47:03 - 47:05
    then it's going to return null, so if it's not found
  • 47:05 - 47:08
    anything that's active it's going to return null,
  • 47:08 - 47:10
    that means there's going to be a draw.
  • 47:11 - 47:13
    And that happens if both tanks manage
  • 47:13 - 47:15
    to blow themselves up at the same time.
  • 47:16 - 47:18
    It is possible, I've seen it, maybe once.
  • 47:20 - 47:22
    Okay, so now after we've found our RoundWinner
  • 47:23 - 47:25
    we're going to check whether it is null or not.
  • 47:26 - 47:29
    So if that RoundWinner is not equal to null.
  • 47:31 - 47:33
    So ! for not equal to.
  • 47:37 - 47:39
    Then what we can do is add
  • 47:39 - 47:41
    to that round winner's number of wins.
  • 47:42 - 47:49
    So m_RoundWinner.m_Wins
  • 47:49 - 47:51
    or m_Wins
  • 47:51 - 47:53
    ++ just to iterate it once.
  • 47:55 - 47:57
    So the RoundWinner remember links to the TankManager
  • 47:57 - 47:59
    for that tank so it says 'hey, this tank,
  • 47:59 - 48:01
    the number of wins that tank's got, lets add 1 to it'.
  • 48:02 - 48:05
    Okay next, after we've added 1
  • 48:05 - 48:08
    to somebodies number of rounds that they've won
  • 48:08 - 48:10
    they might have won the entire game.
  • 48:10 - 48:13
    So now we can check if there is a GameWinner.
  • 48:14 - 48:17
    So m_GameWinner = GetGameWinner.
  • 48:20 - 48:22
    Yeah, let's just take a look at GetGameWinner.
  • 48:23 - 48:26
    So yet again it's very similar to GetRoundWinner,
  • 48:26 - 48:29
    instead of checking if it's found something that's active
  • 48:29 - 48:31
    we're just saying 'hey, has this particular
  • 48:31 - 48:35
    tank in the list of tanks in the array,
  • 48:35 - 48:37
    is the number of wins equal to the
  • 48:37 - 48:39
    number of rounds required to win the entire game?
  • 48:39 - 48:41
    If so, return that particular tank
  • 48:41 - 48:44
    that's got the right number of wins.
  • 48:44 - 48:46
    If not return null'.
  • 48:48 - 48:50
    Once we've found a GameWinner we want
  • 48:50 - 48:54
    to get a message based on whether there is
  • 48:54 - 48:56
    no RoundWinner, no GameWinner,
  • 48:56 - 48:58
    whether there is a GameWinner, etcetera.
  • 48:59 - 49:01
    So we've got a function for doing that and
  • 49:02 - 49:04
    what we're doing is creating a string called message
  • 49:04 - 49:07
    and setting it equal to the EndMessageReturn.
  • 49:08 - 49:10
    And then once we've got that message
  • 49:10 - 49:14
    setting the MessageText's text to that message.
  • 49:14 - 49:17
    So if we wanted to do anything else with the message in-between
  • 49:17 - 49:18
    then we could do that here.
  • 49:18 - 49:20
    We're not actually going to do anything so we're just
  • 49:20 - 49:22
    setting the text straight away.
  • 49:22 - 49:25
    So we're calling this EndMessage function.
  • 49:25 - 49:27
    So EndMessage is how we actually
  • 49:27 - 49:30
    calculating what to do at this point so,
  • 49:30 - 49:31
    or what to write on the screen,
  • 49:31 - 49:33
    so I'm going to scroll down and look at this
  • 49:33 - 49:37
    very confusing looking set of strings and text.
  • 49:38 - 49:40
    So like before we have this
  • 49:40 - 49:42
    way of coloring text
  • 49:42 - 49:44
    and we had that function further up which
  • 49:44 - 49:46
    uses rich text.
  • 49:46 - 49:48
    So we've got a bunch of different things
  • 49:48 - 49:50
    that it could do, so by default what we
  • 49:50 - 49:52
    do is we say 'okay well let's just have
  • 49:52 - 49:54
    a default condition', and that default condition
  • 49:54 - 49:56
    is that there's a draw.
  • 49:56 - 49:58
    Because when there's a draw we don't really need to increment
  • 49:58 - 50:00
    anything at all so we don't worry about it at all.
  • 50:00 - 50:02
    So we're just going to put in DRAW! as our
  • 50:02 - 50:04
    default text for EndMessage.
  • 50:05 - 50:08
    Then we decide if something different that a draw has happened.
  • 50:08 - 50:12
    So we check 'hey, is RoundWinner not null?'
  • 50:12 - 50:14
    I.E. is there a RoundWinner?
  • 50:15 - 50:17
    Then we're going to send something to the message.
  • 50:17 - 50:19
    So the message this time will be
  • 50:19 - 50:21
    RoundWinner with colored text saying
  • 50:22 - 50:26
    'hey, Player 1 WINS THE ROUND!'.
  • 50:28 - 50:32
    So then we have something added on to the message
  • 50:32 - 50:34
    so remember message is our overall
  • 50:34 - 50:36
    piece of text that we're going to put in to that text field.
  • 50:37 - 50:39
    So we just keep adding stuff to it in order
  • 50:39 - 50:41
    to create a paragraph of different
  • 50:41 - 50:43
    things within the overall message.
  • 50:43 - 50:46
    The message as a string then gets added
  • 50:47 - 50:49
    all of these, so these \n
  • 50:49 - 50:50
    just means go to a new line.
  • 50:50 - 50:52
    So we're just spacing out this text, it's having
  • 50:53 - 50:55
    'this person won the round, move down a couple of lines,
  • 50:55 - 50:57
    then start writing something else'.
  • 50:58 - 51:01
    Then once we've moved down four new lines
  • 51:01 - 51:03
    we have a for loop.
  • 51:04 - 51:06
    So with that for loop we're going through
  • 51:06 - 51:09
    all of the tanks that are available
  • 51:09 - 51:11
    and within those we're adding to the
  • 51:11 - 51:13
    message some information.
  • 51:14 - 51:17
    So quite simply what we're doing here is adding on
  • 51:17 - 51:20
    that particular tank colored with PlayerText
  • 51:21 - 51:23
    then a colon
  • 51:24 - 51:26
    and a space, so it might be
  • 51:26 - 51:28
    Player 1:
  • 51:28 - 51:31
    and then the number of wins that are found for that tank.
  • 51:31 - 51:33
    So it looks at the TankManager and it says 'how many wins
  • 51:33 - 51:36
    have you got so far?' Print that as a number,
  • 51:36 - 51:38
    then put in a space and the word WINS.
  • 51:39 - 51:42
    Then put in a new line and do it again
  • 51:42 - 51:44
    for the next tank in the loop.
  • 51:44 - 51:48
    So you will have Player 1: this many wins,
  • 51:49 - 51:51
    Player 2, and so on.
  • 51:53 - 51:55
    Then what we're doing after that is saying
  • 51:55 - 51:57
    'hey, is there a GameWinner?'
  • 51:57 - 51:59
    Because if there's a GameWinner we don't want
  • 51:59 - 52:01
    it to do any of the stuff above, we don't want to actually
  • 52:01 - 52:03
    write all of this stuff in, so instead
  • 52:03 - 52:06
    of saying 'hey message +='
  • 52:06 - 52:08
    we're just clearing it out by saying =,
  • 52:08 - 52:10
    we're saying the message is going to be
  • 52:10 - 52:12
    exactly this thing and in that instance,
  • 52:12 - 52:14
    we check the GameWinner,
  • 52:14 - 52:16
    color it with the right text and we say
  • 52:16 - 52:18
    'space WINS THE GAME'
  • 52:18 - 52:20
    so it might be Player 1, it might be Player 2,
  • 52:20 - 52:22
    WINS THE GAME, that's the only message you'll
  • 52:22 - 52:24
    see on the screen, you won't see the number of
  • 52:24 - 52:26
    other wins that were won or anything like that,
  • 52:26 - 52:28
    we clear it out, put it in.
  • 52:28 - 52:30
    That's whoever won the game.
  • 52:31 - 52:32
    Then we return that message
  • 52:32 - 52:34
    so whenever we call EndMessage
  • 52:34 - 52:37
    we return that piece of text depending on
  • 52:37 - 52:39
    what's just happened in the round.
  • 52:40 - 52:42
    So when we're using EndMessage
  • 52:43 - 52:45
    back up in RoundEnding
  • 52:45 - 52:46
    that's what we're doing.
  • 52:46 - 52:48
    And finally the piece of text after it
  • 52:48 - 52:51
    gets assigned to the component's text field,
  • 52:51 - 52:53
    message, there
  • 52:54 - 52:56
    And I'm going to just jump back on to my slide
  • 52:56 - 52:58
    really quick, what we're going to do now
  • 52:58 - 52:59
    is save the script,
  • 52:59 - 53:01
    but we need you to pair up with someone
  • 53:01 - 53:06
    and fight because it's a tank game and that's how it works.
  • 53:06 - 53:08
    So remember you've got WASD,
  • 53:08 - 53:10
    for one player, and spacebar to fire.
  • 53:10 - 53:13
    Then you've got arrow keys and return for the other player.
  • 53:16 - 53:18
    So save your scene, grab a neighbour and
  • 53:18 - 53:19
    give it a test.
  • 53:20 - 53:22
    Okay, so we're going to do the same.
Title:
TANKS! Unity Tutorial - Phase 7 of 8 - Game Managers
Description:

more » « less
Video Language:
English
Duration:
55:57

English subtitles

Revisions