< Return to Video

TANKS! Unity Tutorial - Phase 6 of 8 - Firing Shells

  • 0:07 - 0:10
    Okay, so in this phase we're going to add a particular
  • 0:11 - 0:14
    point at which we want these shells to be created.
  • 0:14 - 0:16
    We call that a fire transform
  • 0:16 - 0:18
    and we call it that because it's just an empty
  • 0:18 - 0:20
    game object that just has a transform component on it
  • 0:20 - 0:23
    and we put that in front of the barrel of the gun.
  • 0:23 - 0:25
    Then we're going to use UI, we're going to use
  • 0:25 - 0:27
    the slider yet again, we're going to sort of
  • 0:27 - 0:29
    re-appropriate it to create this effect,
  • 0:29 - 0:32
    we're going to put a canvas in front of our tank
  • 0:32 - 0:34
    and we're going to use a slider as a thing that
  • 0:34 - 0:36
    defines this arrow that shows you how much
  • 0:36 - 0:38
    force you're putting in to a shot.
  • 0:39 - 0:41
    And it's going to vary, so depending on how long
  • 0:41 - 0:43
    you hold down the shot it's going to
  • 0:43 - 0:45
    fire over different distances.
  • 0:48 - 0:51
    First thing is to select our tank.
  • 0:52 - 0:54
    And as we stated before there's a number of different
  • 0:54 - 0:55
    ways to do anything in Unity.
  • 0:55 - 0:59
    Making a new object is yet another one of those.
  • 0:59 - 1:01
    So you can click on the Create
  • 1:01 - 1:03
    menu on the hierarchy, you can click the
  • 1:03 - 1:05
    Game Object menu, but if you want to do
  • 1:05 - 1:08
    things directly and parent them at the same time
  • 1:08 - 1:11
    you can right click on existing game objects.
  • 1:11 - 1:13
    So I want to create a child object of
  • 1:13 - 1:16
    a tank so I right click on my tank
  • 1:16 - 1:19
    and I go to Create Empty.
  • 1:20 - 1:22
    That places a new empty game object
  • 1:22 - 1:24
    on to my tank, I'm just going to
  • 1:24 - 1:27
    rename this FireTransform.
  • 1:30 - 1:32
    And then I'm going to give you a position and rotation
  • 1:32 - 1:35
    to put it exactly in front of the gun barrel
  • 1:35 - 1:38
    and then rotate it the right way.
  • 1:38 - 1:43
    So the position for this is (0, 1.7, 1.35)
  • 1:45 - 1:48
    and then the rotation is (350, 0, 0).
  • 1:51 - 1:53
    Yet again it's easier to see on the slides
  • 1:53 - 1:55
    so I'm just going to switch there.
  • 1:55 - 1:59
    So position (0, 1,7, 1.35).
  • 1:59 - 2:02
    Rotation (350, 0, 0).
  • 2:03 - 2:06
    So just to unobstruct that a little bit.
  • 2:06 - 2:08
    The position of the FireTransform, we don't want it to be
  • 2:08 - 2:11
    left or right so the exposition is of course going to be 0.
  • 2:12 - 2:14
    Because the barrel is in the middle of the tank.
  • 2:14 - 2:16
    We want it to be up a little bit, so that's why it's
  • 2:16 - 2:19
    1.7 up in the Y axis.
  • 2:19 - 2:21
    And we want it to be in front of the tank, not at the
  • 2:21 - 2:23
    back or anywhere else so that's why it's a little bit
  • 2:23 - 2:25
    forward in the Z axis.
  • 2:25 - 2:27
    So if you've done it right it should look something like this.
  • 2:27 - 2:29
    Just in front of it at roughly the same angle
  • 2:29 - 2:31
    as the artwork implies.
  • 2:32 - 2:34
    And just forward so we're not creating
  • 2:34 - 2:36
    the shell so that it's going to
  • 2:36 - 2:39
    intersect the collider and detonate straight away.
  • 2:40 - 2:42
    That would be bad.
  • 2:45 - 2:47
    As I said this requires a little bit of
  • 2:47 - 2:49
    UI work in order to get the arrow
  • 2:49 - 2:51
    to show the player how much they're
  • 2:51 - 2:53
    firing their shell by.
  • 2:53 - 2:55
    So we're going to right click on our canvas now.
  • 2:57 - 2:59
    So if you reselect the canvas that we've got on the tank,
  • 3:01 - 3:05
    and then right click, we're going to create a UI slider.
  • 3:06 - 3:08
    So right click on the existing canvas, we don't want to make
  • 3:08 - 3:10
    a new canvas, we can use the same one that we've got.
  • 3:10 - 3:12
    Create a UI Slider.
  • 3:16 - 3:18
    And we can rename this straight away
  • 3:18 - 3:20
    to AimSlider.
  • 3:21 - 3:23
    So I'm just going to zoom out and show you what this looks like.
  • 3:23 - 3:25
    Yet again it's our old friend the slider.
  • 3:26 - 3:28
    Not aware of what we want to do with it at all.
  • 3:29 - 3:32
    We're going to, basically make this a small
  • 3:32 - 3:34
    strip that's going to exist in front of the tank.
  • 3:34 - 3:36
    And we're going to hold down
  • 3:36 - 3:38
    in order to increase the value
  • 3:38 - 3:40
    on that slider and therefore increase
  • 3:40 - 3:42
    the amount to which the arrow is shown.
  • 3:42 - 3:44
    So what we want to do is
  • 3:44 - 3:47
    alt-click on AimSlider on the arrow
  • 3:47 - 3:49
    to expand everything, so remember when we did this
  • 3:49 - 3:53
    on the canvas before we alt-click the arrow left of it's name
  • 3:53 - 3:55
    to expand everything at once.
  • 3:57 - 3:59
    Then as before we need to get rid
  • 3:59 - 4:01
    of the Handle Slide Area because
  • 4:01 - 4:03
    we don't want to be dragging this around,
  • 4:03 - 4:06
    it's just based on the Fire button in the game.
  • 4:06 - 4:08
    So I'm going to select Handle Slide Area and
  • 4:08 - 4:11
    delete it, therefore deleting the handle as well.
  • 4:11 - 4:13
    So command-backspace on mac, delete on pc.
  • 4:15 - 4:17
    And then we also don't need the Background
  • 4:17 - 4:19
    of this slider because we just want it to be
  • 4:19 - 4:21
    invisible when they're not firing and then just
  • 4:21 - 4:23
    emerge as soon as they start firing.
  • 4:23 - 4:25
    So I'm going to select the background.
  • 4:25 - 4:27
    And delete it.
  • 4:27 - 4:29
    You should be left with Aim Slider,
  • 4:29 - 4:31
    Fill Area and Fill.
  • 4:34 - 4:36
    A quick reminder, so we right-clicked on our
  • 4:36 - 4:38
    Canvas, that's our existing canvas that we
  • 4:38 - 4:40
    used for the Health slider and we
  • 4:40 - 4:42
    added a new object to it, so when you're working
  • 4:42 - 4:44
    with the UI system be aware that you
  • 4:44 - 4:47
    invariably will just create just one canvas
  • 4:47 - 4:49
    and many things within it.
  • 4:49 - 4:51
    So it's the same for screen space UI as it is
  • 4:51 - 4:53
    with our world UI that we're doing.
  • 4:54 - 4:56
    So then we've renamed it AimSlider and
  • 4:56 - 4:58
    we've expanded everything
  • 4:58 - 5:00
    and removed the Background and
  • 5:00 - 5:02
    Handle Slide Area game objects.
  • 5:04 - 5:06
    Then we need to make this not intractable.
  • 5:06 - 5:08
    Yet again it's just something that's controlled
  • 5:08 - 5:10
    by a script, we're not going to be dragging on screen
  • 5:10 - 5:12
    with a mouse or anything like that.
  • 5:12 - 5:14
    So I'm going to reselect my AimSlider
  • 5:15 - 5:17
    and look at the Slider component in the inspector on the right.
  • 5:19 - 5:21
    I'm going to uncheck Intractable and
  • 5:21 - 5:23
    because I don't want it to animate during any
  • 5:23 - 5:25
    interaction because we don't want any interaction
  • 5:26 - 5:27
    we set Transition to None
  • 5:27 - 5:29
    and that's going to remove all of those transition
  • 5:29 - 5:30
    properties for you.
  • 5:31 - 5:33
    Then finally we're going to set
  • 5:33 - 5:35
    this up based on the bottom being
  • 5:35 - 5:37
    near the barrel of the tank and then the top
  • 5:37 - 5:39
    being furthest away from the tank.
  • 5:39 - 5:42
    So the Direction as we call it
  • 5:42 - 5:44
    we'll say is 'Bottom to Top'.
  • 5:46 - 5:48
    Then we're going to set the Min and Max
  • 5:48 - 5:50
    values from 15 to 30.
  • 5:54 - 5:57
    And we can leave our Minimum Value at 15.
  • 5:57 - 5:59
    So we want it to start off and then
  • 5:59 - 6:03
    draw this thing out to a certain amount,
  • 6:03 - 6:05
    and you'll see that once we start doing it.
  • 6:08 - 6:10
    So we don't want it intractable,
  • 6:10 - 6:12
    there's no transition, it needs to render
  • 6:12 - 6:14
    from bottom to top once we've setup
  • 6:14 - 6:16
    the position for it, which you'll see shortly.
  • 6:16 - 6:18
    And we have minimum and maximum
  • 6:18 - 6:20
    values for that slider.
  • 6:20 - 6:23
    Okay, so then yet again we need to
  • 6:23 - 6:25
    setup this slider in context
  • 6:25 - 6:26
    of it's parent.
  • 6:26 - 6:29
    So the parent of this slider is the canvas.
  • 6:29 - 6:31
    Yet again it's a quick way
  • 6:31 - 6:34
    to get things roughly in the right size
  • 6:34 - 6:36
    is to just stretch them over their parent
  • 6:36 - 6:38
    then you can start resizing them and stretching them
  • 6:38 - 6:39
    to where you want them to be.
  • 6:39 - 6:41
    So that's exactly what we're going to do right now.
  • 6:41 - 6:43
    So what we're going to do is multi-select
  • 6:43 - 6:47
    the AimSlider and the Fill Area, just those two.
  • 6:50 - 6:52
    Then if you look at the rect transform
  • 6:52 - 6:54
    yet again we have these anchor presets.
  • 6:54 - 6:56
    So just to remind you these are ways of
  • 6:56 - 6:59
    stretching out where that UI element will exist
  • 6:59 - 7:01
    and also you can position them at the same
  • 7:01 - 7:05
    time using alt, which is exactly what we'll do.
  • 7:05 - 7:07
    So if we select that anchor preset
  • 7:07 - 7:09
    and hold down alt, you can see if I
  • 7:09 - 7:12
    tap alt now we are stretching and positioning.
  • 7:13 - 7:15
    So I'm going to right-click the lower right
  • 7:15 - 7:17
    stretch option there.
  • 7:20 - 7:22
    Then what you'll see is it's getting roughly in the right
  • 7:22 - 7:25
    place now and it's now based under our tank.
  • 7:26 - 7:28
    Then I'm going to expand my Fill Area
  • 7:28 - 7:30
    if I haven't already so I can see the fill.
  • 7:32 - 7:35
    So with the Fill selected, that's the image that we want
  • 7:35 - 7:37
    to actually project, so we've made an arrow for
  • 7:37 - 7:39
    you guys in Photoshop that's just
  • 7:39 - 7:42
    got a gradient fade to the bottom of it.
  • 7:42 - 7:44
    And we've already sliced that up
  • 7:44 - 7:46
    in the sprite editor in Unity,
  • 7:46 - 7:48
    just to show you that really quick.
  • 7:48 - 7:50
    It looks like this.
  • 7:51 - 7:53
    There's our AimArrow,
  • 7:53 - 7:55
    and with the sprite editor what you can do is basically
  • 7:55 - 7:57
    define which areas are going
  • 7:57 - 7:59
    to be sliced and stretched.
  • 7:59 - 8:01
    So what you'll notice is we've got this entire
  • 8:01 - 8:03
    area at the top, which is fine,
  • 8:03 - 8:05
    and then the outer area
  • 8:05 - 8:07
    is defined as well, but in the middle we've got
  • 8:07 - 8:10
    this small space in which we can stretch.
  • 8:11 - 8:13
    That's already setup for you guys,
  • 8:13 - 8:14
    you don't need to worry about that,
  • 8:14 - 8:16
    I just wanted to show it to you.
  • 8:16 - 8:18
    So with that Fill game object
  • 8:18 - 8:21
    we're going to setup it's visual area.
  • 8:22 - 8:24
    So the first thing I'm going to do is
  • 8:24 - 8:26
    to remove this value of 10 from the Height.
  • 8:26 - 8:28
    So I don't want it to be any distance
  • 8:28 - 8:30
    from it's parent at all so I'm just going to
  • 8:30 - 8:33
    zero that out totally, set the height to 0.
  • 8:33 - 8:35
    Then on the Fill game object
  • 8:35 - 8:38
    there's also the actual image itself.
  • 8:38 - 8:40
    So you'll see an image component.
  • 8:40 - 8:42
    In Source Image I'm going to choose
  • 8:42 - 8:43
    that Aim Arrow,
  • 8:43 - 8:46
    So click to the right of Source Image
  • 8:46 - 8:48
    it currently has this default UI sprite thing we don't want.
  • 8:49 - 8:51
    Click on Aim Arrow there.
  • 8:52 - 8:54
    So you won't be able to see anything just yet,
  • 8:54 - 8:55
    we haven't quite finished it.
  • 8:56 - 9:00
    Okay, so we've selected AimSlider Fill Area and we've
  • 9:00 - 9:03
    stretched them over the canvas, the parent,
  • 9:03 - 9:04
    that's what we've done there,
  • 9:04 - 9:07
    remember alt-click to stretch them out.
  • 9:07 - 9:09
    And then we've expanded that Fill Area
  • 9:09 - 9:11
    and selected the Fill and
  • 9:11 - 9:13
    we've set the height to 0
  • 9:13 - 9:15
    to remove any offset from the parent Rect.
  • 9:15 - 9:17
    So when I say the parent Rect I'm just referring to
  • 9:17 - 9:19
    whatever's directly above it, in this case
  • 9:19 - 9:20
    it's the Fill Area.
  • 9:20 - 9:22
    And then on the Fill game object we've
  • 9:22 - 9:24
    used circle select to choose the Aim Arrow.
  • 9:25 - 9:27
    So we're going to go back to the Aim Slider right now
  • 9:27 - 9:29
    and what you should see is that
  • 9:29 - 9:32
    if you select the rect tool,
  • 9:32 - 9:33
    so the 5th one at the top here.
  • 9:33 - 9:36
    So these tool by the way are Q, W, E, R, T
  • 9:36 - 9:39
    if you're on a QWERTY keyboard
  • 9:39 - 9:42
    then that's how you can just switch between those tools.
  • 9:42 - 9:44
    So the fifth one there is the tool you want.
  • 9:44 - 9:46
    That will help you see these dots
  • 9:46 - 9:47
    and allow you to drag things out.
  • 9:48 - 9:50
    So what I'm going to do is just
  • 9:50 - 9:53
    move my scene view around so
  • 9:53 - 9:55
    you can of course drag around with the
  • 9:55 - 9:57
    first hand tool, but if you're on another tool,
  • 9:57 - 10:00
    such as the rect tool you can hold down alt
  • 10:00 - 10:02
    to orbit around what you're looking at.
  • 10:04 - 10:06
    So if I alt and then drag around I can see what I'm doing.
  • 10:06 - 10:08
    I'm just doing this to get myself some kind
  • 10:08 - 10:09
    of overhead view.
  • 10:09 - 10:10
    Another way to do that of course is
  • 10:10 - 10:13
    to click on the Y spoke
  • 10:13 - 10:15
    of the gizmo in the top right there,
  • 10:15 - 10:17
    and then tap the centre cube to
  • 10:17 - 10:19
    change in to a totally flat view overhead.
  • 10:20 - 10:22
    Because what I'm trying to do is this,
  • 10:22 - 10:24
    and I'll show you it quickly and then we'll go back through it.
  • 10:24 - 10:26
    I'm going to drag the outer bounds in
  • 10:26 - 10:29
    so that they're roughly on the edge of the tank.
  • 10:29 - 10:31
    I'm going to drag it a little bit longer
  • 10:31 - 10:33
    and then I'm going to drag it up so that it's
  • 10:33 - 10:35
    snapped on the front of the tank.
  • 10:36 - 10:38
    Something like that.
  • 10:38 - 10:40
    Then I'm going to orbit around so that I'm in
  • 10:40 - 10:42
    an orthographic isometric view right now.
  • 10:43 - 10:45
    And then I'm going to drag with my
  • 10:45 - 10:47
    translate tool I'll drag back
  • 10:47 - 10:50
    in the Z axis just to bring the up a little bit.
  • 10:50 - 10:52
    So it's just slightly off the ground, like that.
  • 10:53 - 10:55
    I'm going to go back a few steps and
  • 10:55 - 10:56
    run that by you again.
  • 10:57 - 10:59
    So once more,
  • 10:59 - 11:01
    with my rect tool I'm just dragging
  • 11:01 - 11:03
    in the bounds, so remember we're on
  • 11:03 - 11:05
    the Aim Slider, make sure you've
  • 11:05 - 11:07
    got the Aim Slider selected.
  • 11:07 - 11:09
    Drag in the left and right edges.
  • 11:10 - 11:13
    Make it a little bit taller, drag it forward,
  • 11:13 - 11:15
    this doesn't need to be precise by the way,
  • 11:15 - 11:16
    it can just be a design choice,
  • 11:16 - 11:18
    so you might have a slightly
  • 11:18 - 11:20
    more extended arrow than anyone else
  • 11:20 - 11:22
    does on their tank, but as long as that
  • 11:22 - 11:24
    slider is going from between those two values it'll
  • 11:24 - 11:26
    function the same as everybody else's game.
  • 11:27 - 11:28
    And then all I've done to bring that up
  • 11:28 - 11:31
    off the ground, because the rect tool
  • 11:31 - 11:33
    deals with 2D specifically we have to
  • 11:33 - 11:35
    jump back to the translate tool,
  • 11:35 - 11:37
    drag the blue arrow backwards to
  • 11:37 - 11:39
    bring it up off the ground and you should
  • 11:39 - 11:41
    end up with something that looks like this.
  • 11:45 - 11:47
    Of course save your scene throughout.
  • 11:47 - 11:49
    Just to make sure you're up to date.
  • 11:50 - 11:52
    And if you do want the exact same
  • 11:52 - 11:54
    values that we intend you to use
  • 11:54 - 11:56
    I'll give you those values now.
  • 11:56 - 11:58
    Though I've just done this by hand, but if you wanted
  • 11:58 - 12:00
    to just type them in to the inspector
  • 12:00 - 12:09
    our values would be 1, -9, -1, 1 and 3.
  • 12:13 - 12:15
    It would look something like that.
  • 12:18 - 12:22
    So remember this is the Aim Slider, 1, -9, -1, 1, 3.
  • 12:24 - 12:26
    And as before, because it's a slider
  • 12:26 - 12:28
    and the slider is controlling how the
  • 12:28 - 12:30
    image will behave, if I drag
  • 12:30 - 12:32
    my value on the slider you'll see
  • 12:32 - 12:35
    that my arrow is doing what it should do.
  • 12:38 - 12:39
    So you can test it out that way.
  • 12:39 - 12:41
    Make sure you leave it back on the lowest
  • 12:41 - 12:43
    possible value to the left with that slider
  • 12:43 - 12:45
    once you've tested it out.
  • 12:46 - 12:48
    We have our Aim Slider setup
  • 12:48 - 12:50
    and we're ready to start actually
  • 12:50 - 12:52
    firing shells, which is exactly what
  • 12:52 - 12:54
    we need for this tank shooter,
  • 12:54 - 12:56
    otherwise it will just be a tank,
  • 12:58 - 13:00
    something.
  • 13:00 - 13:03
    Okay, so, in our Scripts folder
  • 13:04 - 13:07
    if you pop that open you'll find something called Tank.
  • 13:07 - 13:09
    We've been in there before, this time we need
  • 13:09 - 13:12
    TankShooting, and we're going to just
  • 13:12 - 13:15
    drag and drop that on to the Tank game object.
  • 13:15 - 13:18
    So I can basically collapse my tank right now,
  • 13:18 - 13:20
    just click on the arrow next to it's name,
  • 13:21 - 13:23
    and then I'm going to drag TankShooting
  • 13:23 - 13:25
    and drop it on to the Tank.
  • 13:26 - 13:28
    I'm just going to collapse my
  • 13:28 - 13:31
    other components so that you can see it more easily now.
  • 13:32 - 13:34
    So we have our TankShooting
  • 13:34 - 13:36
    there and we're ready to start editing it.
  • 13:36 - 13:38
    You'll see there's a number of different
  • 13:38 - 13:40
    public variables which we're ready to populate
  • 13:40 - 13:42
    but we'll talk about those in context of the script
  • 13:42 - 13:44
    that way when we come back and populate them
  • 13:44 - 13:46
    they have some meaning.
  • 13:46 - 13:49
    So if you double click on TankShooting to open it
  • 13:49 - 13:51
    we are ready to edit.
  • 13:51 - 13:53
    So like we've had before,
  • 13:53 - 13:55
    there are some
  • 13:55 - 13:57
    blocked comments that we need to get rid of
  • 13:57 - 13:59
    before we can continue.
  • 13:59 - 14:00
    Yeah, let's do that first.
  • 14:00 - 14:04
    So on line 17 and line 37
  • 14:04 - 14:09
    there should a /* and a */
  • 14:10 - 14:12
    Easy for you to say!
  • 14:14 - 14:16
    Okay, so that's all the comments done.
  • 14:17 - 14:19
    Let's go through those public variables
  • 14:19 - 14:20
    and find out what they mean.
  • 14:21 - 14:23
    So like we had with the
  • 14:23 - 14:25
    TankMovement script, we have a PlayerNumber
  • 14:25 - 14:28
    because we need some input in this class
  • 14:28 - 14:30
    so we need to know which input axis
  • 14:30 - 14:32
    we need to reference.
  • 14:32 - 14:35
    In this case it's going to be fire1 for player1,
  • 14:35 - 14:37
    fire2 for player2, etcetera.
  • 14:38 - 14:40
    So that's why we need that.
  • 14:40 - 14:42
    We need a reference to the Shell
  • 14:42 - 14:44
    prefab that we're going to instantiate
  • 14:44 - 14:46
    so we've got that rigidbody Shell there.
  • 14:47 - 14:49
    So remember this isn't a reference to the rigidbody,
  • 14:50 - 14:52
    because we only want to affect things
  • 14:52 - 14:55
    about that rigidbody we can just refer to that as the prefab.
  • 14:57 - 14:59
    Okay, and we need a reference to that
  • 14:59 - 15:01
    place that we're going to
  • 15:01 - 15:03
    fire the shells from, that FireTransform,
  • 15:03 - 15:05
    so that's what that references there.
  • 15:06 - 15:08
    Obviously we need a reference to the slider
  • 15:08 - 15:10
    to make it grow and shrink.
  • 15:11 - 15:13
    We need a reference to the second audio
  • 15:13 - 15:15
    source on the tank, the one that's going to play the
  • 15:15 - 15:17
    sound effects for shooting.
  • 15:17 - 15:19
    So that's what that audio source is there for.
  • 15:19 - 15:21
    And we need to know what clips that audio
  • 15:21 - 15:23
    source is going to play so we need a reference to
  • 15:23 - 15:25
    those two audio clips,
  • 15:25 - 15:27
    one for charging up the shot and
  • 15:27 - 15:29
    one for actually firing it.
  • 15:29 - 15:32
    And so now we've got a few float variables.
  • 15:33 - 15:36
    We've got the minimum and maximum launch force/
  • 15:36 - 15:38
    You'll remember the values of the slider we gave you
  • 15:38 - 15:40
    were 15 for minimum and 30 for maximum?
  • 15:41 - 15:43
    So that is going to correlate like we did
  • 15:43 - 15:46
    with the health we did from 0 to 100 for health,
  • 15:46 - 15:49
    we're doing 15 to 30 for the LaunchForce.
  • 15:50 - 15:52
    If you want to change the LaunchForce, change them both
  • 15:52 - 15:54
    here and on the slider.
  • 15:54 - 15:56
    We don't recommend you do that because it starts
  • 15:56 - 15:59
    bumping in to things like the tank if you go too fast,
  • 15:59 - 16:01
    that sort of stuff.
  • 16:01 - 16:03
    Let them discover it on their own!
  • 16:04 - 16:05
    You can try tweaking stuff,
  • 16:05 - 16:07
    we won't be upset, but yeah,
  • 16:07 - 16:09
    we've found these to be good values for now.
  • 16:10 - 16:13
    So the last public float is how long is
  • 16:13 - 16:15
    it going to take to get from the minimum launch force
  • 16:15 - 16:17
    to the maximum launch force?
  • 16:17 - 16:19
    So about 3/4 of a second to go from
  • 16:19 - 16:21
    minimum charge where you're just,
  • 16:21 - 16:23
    just shooting the shells, just about
  • 16:23 - 16:24
    to really firing them across the screen,
  • 16:24 - 16:26
    takes about 3/4 of a second.
  • 16:26 - 16:28
    Based on that time and how much
  • 16:28 - 16:30
    charge we need to build up
  • 16:30 - 16:33
    we're going to calculate how fast that needs to go.
  • 16:34 - 16:36
    And that's going to be called the ChargeSpeed, and that's our
  • 16:36 - 16:38
    third private variable down there,
  • 16:38 - 16:41
    but the ones before that, if you remember the
  • 16:41 - 16:43
    input axis are strings
  • 16:43 - 16:45
    so input buttons are also strings,
  • 16:45 - 16:48
    so we've got one for the fire button there,
  • 16:48 - 16:51
    which we'll store based on the PlayerNumber.
  • 16:51 - 16:53
    And we need to keep track of how
  • 16:53 - 16:55
    much we've charged up the shot so far,
  • 16:55 - 16:57
    so that's the CurrentLaunchForce,
  • 16:57 - 16:59
    how much have we built up so far.
  • 16:59 - 17:02
    And the last one is whether or not we've fired yet.
  • 17:02 - 17:04
    Because we don't want to fire multiple times,
  • 17:04 - 17:06
    we want to do it once per button press.
  • 17:07 - 17:10
    So the next function we've got there is OnEnable,
  • 17:10 - 17:12
    so that's when the tank is turned back
  • 17:12 - 17:14
    on after being killed.
  • 17:14 - 17:16
    We're setting the CurrentLaunchForce back to the minimum
  • 17:16 - 17:19
    and we're setting the AimSlider's value back to the minimum.
  • 17:19 - 17:21
    So when you're alive you're not already charging a shot,
  • 17:21 - 17:23
    you just start again.
  • 17:23 - 17:25
    Then we've got the Start function.
  • 17:25 - 17:28
    So again this is called right at the start, only once,
  • 17:28 - 17:30
    OnEnable might be called multiple times if you die
  • 17:30 - 17:33
    multiple times but Start will only be called once
  • 17:33 - 17:35
    so we're calculating the Fire button, and that's
  • 17:35 - 17:41
    equal to the string Fire plus a number based on the PlayerNumber.
  • 17:41 - 17:44
    So Fire1for Player1, Fire2 for Player2, etcetera.
  • 17:44 - 17:47
    Just a quick reminder, in the input settings,
  • 17:47 - 17:49
    those are the things I was talking about earlier,
  • 17:49 - 17:52
    so Fire1 there, we just take the PlayerNumber
  • 17:52 - 17:54
    and put it on the end and it then references this
  • 17:54 - 17:57
    which gives us, in this instance, the spacebar.
  • 17:59 - 18:01
    So the last thing we're doing in Start there
  • 18:01 - 18:04
    is calculating the ChargeSpeed,
  • 18:04 - 18:06
    so if you remember Speed equals Distance over Time,
  • 18:06 - 18:08
    this is the same thing,
  • 18:08 - 18:10
    the distance that we've got to cover is from
  • 18:10 - 18:12
    the minimum to the maximum LaunchForce
  • 18:12 - 18:14
    and the time we've got to do that is the ChargeTime.
  • 18:14 - 18:16
    So Speed is the distance we've got to cover
  • 18:16 - 18:19
    over the time, that's how we're calculating that.
  • 18:19 - 18:21
    So next we've got the Update function.
  • 18:21 - 18:23
    Now the Update, what it needs to do is
  • 18:23 - 18:25
    take care of all the inputs,
  • 18:25 - 18:27
    so when the button is being pressed for the
  • 18:27 - 18:29
    first frame, when it's being held down,
  • 18:29 - 18:31
    and when it's being released,
  • 18:31 - 18:33
    it also needs to take care of the account when
  • 18:33 - 18:35
    you've held it for too long and you've reached the
  • 18:35 - 18:37
    maximum and then you need to fire.
  • 18:38 - 18:40
    So to do that we're going to have a
  • 18:40 - 18:42
    series of if else statements to make sure we're
  • 18:42 - 18:43
    catching all the cases.
  • 18:44 - 18:46
    But the first thing we need to do is make sure that
  • 18:46 - 18:49
    the AimSlider's default value, so every frame we're
  • 18:49 - 18:51
    going to set the default value of the AimSlider
  • 18:52 - 18:54
    back to the MinimumLaunchForce.
  • 18:54 - 18:56
    So by default AimSlider is
  • 18:56 - 18:59
    invisible at it's most minimum value.
  • 19:00 - 19:02
    And then if we decide that it needs
  • 19:02 - 19:04
    to be at a different value we can set it then.
  • 19:06 - 19:09
    The first if statement that we're going to write is
  • 19:09 - 19:22
    if(m_CurrentLaunchForce >= m_MaxLaunchForce
  • 19:26 - 19:32
    and, so that's &&, we have not yet fired,
  • 19:32 - 19:35
    so !m_Fired
  • 19:36 - 19:40
    So that's the case, we have charged up to the maximum,
  • 19:40 - 19:42
    and we've not yet fired so we need to do
  • 19:42 - 19:45
    something about that, so what we're going to do is we're going to
  • 19:45 - 19:47
    write all of these if statements so we can take care of the
  • 19:47 - 19:49
    cases and then come back at the end
  • 19:49 - 19:52
    and go through what we actually need to do in those cases.
  • 19:52 - 19:54
    So I'm just going to put in a single line comment
  • 19:54 - 19:56
    just to remind you what you're doing, you can write that
  • 19:56 - 19:58
    in or not, it's up to you.
  • 19:58 - 20:01
    So at the maximum amount of charge but not yet fired.
  • 20:01 - 20:04
    So after that we have an else if statement,
  • 20:04 - 20:11
    else if( and in this case we're dealing with when the button is first pressed
  • 20:11 - 20:13
    so when the button is first pressed
  • 20:13 - 20:17
    Input.GetButtonDown is returned true.
  • 20:17 - 20:20
    So you get ButtonDown is when it's first pressed.
  • 20:20 - 20:22
    And the button that we want to
  • 20:22 - 20:26
    check is the Fire button, so m_FireButton.
  • 20:31 - 20:35
    Okay, and if we have not reached the maximum charge
  • 20:35 - 20:38
    and we've not just pressed the button,
  • 20:38 - 20:40
    then we might be holding the button,
  • 20:40 - 20:45
    so the next else if statement is Input.GetButton
  • 20:46 - 20:49
    So that's saying 'is the button currently held?'
  • 20:50 - 20:53
    But we need to check if it's currently held
  • 20:53 - 20:55
    that we haven't fired already,
  • 20:55 - 20:58
    because we might have hit the maximum launch force
  • 20:58 - 21:01
    and then not fired it, so we need to check for that.
  • 21:04 - 21:07
    And the last else if statement
  • 21:07 - 21:10
    is, you might have guessed it, if you've released the button.
  • 21:11 - 21:18
    So in this case it would be else if(Input.GetButtonUp(m_FireButton)
  • 21:18 - 21:21
    and again we need to check that we've not yet fired.
  • 21:25 - 21:27
    So you might have noticed that all of them are
  • 21:27 - 21:29
    checking that we've not yet fired, apart from when we've
  • 21:29 - 21:33
    first pressed the button, and that's because when we first press the button
  • 21:33 - 21:35
    of course we haven't fired, we've just pressed the button.
  • 21:36 - 21:38
    Okay, so let's go back through
  • 21:38 - 21:40
    those and think about what we
  • 21:40 - 21:42
    actually need to do then.
  • 21:43 - 21:45
    So in the first case we've
  • 21:45 - 21:46
    gone beyond the MaxCharge
  • 21:46 - 21:48
    and we've not yet fired.
  • 21:48 - 21:50
    So what we really need to do is fire,
  • 21:50 - 21:52
    but we don't want to do it beyond the maximum charge,
  • 21:52 - 21:54
    we want to do it at the maximum.
  • 21:54 - 21:57
    So what we'll do is we'll set the CurrentLaunchForce
  • 21:57 - 21:59
    to the MaxLaunchForce
  • 22:00 - 22:02
    so that it's not over the top,
  • 22:02 - 22:04
    and we'll call the Fire function, which is a function
  • 22:04 - 22:05
    which we'll write in a little bit.
  • 22:05 - 22:07
    Then if we've just pressed the button
  • 22:07 - 22:09
    for the first time
  • 22:09 - 22:11
    then we know that we have not yet fired.
  • 22:12 - 22:16
    So m_Fired is false, we've not fired yet.
  • 22:18 - 22:20
    And we also know if we just press the button
  • 22:20 - 22:22
    that the LaunchForce should be at it's minimum.
  • 22:23 - 22:27
    So we'll set CurrentLaunchForce equal to MinLaunchForce.
  • 22:27 - 22:29
    Also when we've just pressed the button
  • 22:29 - 22:32
    we want to start playing a sound effect that
  • 22:32 - 22:34
    related to charging up, so,
  • 22:34 - 22:37
    what we'll do is set the ShootingAudio clip
  • 22:38 - 22:40
    to the ChargingClip, so
  • 22:40 - 22:45
    m_ShootingAudio.clip = ChargingClip
  • 22:46 - 22:52
    And we'll play that audio clip, so m_ShootingAudio.Play
  • 22:55 - 22:57
    Okay, so the next one is if the
  • 22:57 - 23:00
    button is being held, so if the button is being held we
  • 23:00 - 23:02
    don't want to fire but we do want to
  • 23:02 - 23:05
    update how much the charge has gained.
  • 23:06 - 23:08
    So what we're going to do is set the
  • 23:08 - 23:13
    CurrentLaunchForce to itself plus ChargeSpeed times delta time.
  • 23:14 - 23:17
    So to do that we do +=
  • 23:18 - 23:21
    m_ChargeSpeed * Time.deltaTime
  • 23:23 - 23:26
    So remember that +=, what it's doing is is saying
  • 23:26 - 23:28
    'add this to it's current value'.
  • 23:30 - 23:34
    It's saying 'set this to itself plus a little bit extra'.
  • 23:36 - 23:39
    With that new CurrentLaunchForce that we've just increased
  • 23:40 - 23:42
    we'll set the AimSlider's value
  • 23:42 - 23:44
    to the CurrentLaunchForce.
  • 23:45 - 23:47
    So similar to the HealthUI that we did before
  • 23:47 - 23:49
    we're effectively setting the value
  • 23:49 - 23:51
    and then refreshing the actual visual
  • 23:51 - 23:53
    element of it by setting the slider's value.
  • 23:53 - 23:57
    Okay? And the last case that we need to deal with
  • 23:57 - 24:01
    is if you've released the button you fire, that's it!
  • 24:02 - 24:05
    So we'll just quickly go over that.
  • 24:05 - 24:07
    First off we're resetting the value
  • 24:07 - 24:09
    to a default value and then we'll
  • 24:09 - 24:13
    only change the AimSlider based on the button being held.
  • 24:13 - 24:14
    Or pressed, or released.
  • 24:14 - 24:15
    Yes.
  • 24:15 - 24:18
    If the CurrentLaunchForce is greater than the maximum
  • 24:18 - 24:21
    we'll set it back to the maximum and then fire based on that.
  • 24:21 - 24:24
    If the button is being pressed for the first time
  • 24:25 - 24:28
    then we have not yet fired, so fire gets set to False.
  • 24:28 - 24:31
    And then CurrentLaunchForce gets set back to our minimum.
  • 24:31 - 24:34
    We also play the correct clip for that situation.
  • 24:35 - 24:37
    If the button is being held
  • 24:37 - 24:40
    and we've not yet fired, so that's GetButton for held,
  • 24:41 - 24:44
    then we'll increase the LaunchForce
  • 24:44 - 24:47
    by the ChargeSpeed multiplied by Time.deltaTime.
  • 24:48 - 24:51
    And we will set the AimSlider's value appropriately.
  • 24:51 - 24:55
    Finally, if we've released the button then we'll fire.
  • 24:57 - 24:59
    Why don't you set any other audio conditions?
  • 24:59 - 25:01
    That's a good question, the question if you didn't hear was
  • 25:01 - 25:03
    'why don't we set other audio conditions?'
  • 25:03 - 25:05
    So basically the way this works is we have an audio
  • 25:05 - 25:07
    clip that's kind of incremental,
  • 25:08 - 25:09
    a kind of charging sound,
  • 25:09 - 25:11
    and what happens with that is that when we write the
  • 25:11 - 25:13
    Fire function in a moment we're going to
  • 25:13 - 25:16
    play a different clip, so what we do is interrupt it
  • 25:16 - 25:18
    effectively with the sound of it firing.
  • 25:18 - 25:20
    So that's effectively cutting it off
  • 25:20 - 25:23
    and replacing the clip with another, and that will take care of
  • 25:23 - 25:25
    the rest of the audio in that scenario.
  • 25:26 - 25:28
    That's a good question.
  • 25:28 - 25:30
    Okay, so let's move on to the Fire function.
  • 25:32 - 25:34
    So what we need to do here is instantiate
  • 25:34 - 25:37
    the shell and give it a velocity
  • 25:38 - 25:39
    based on how much we've charged up.
  • 25:39 - 25:41
    So the first thing, when we've fired
  • 25:41 - 25:44
    of course Fired = True.
  • 25:44 - 25:46
    So that's going to deal with all the logic
  • 25:46 - 25:48
    above that we've just put in.
  • 25:48 - 25:50
    And the next thing we need to do is actually
  • 25:50 - 25:53
    instantiate a shell, so we're going to use that
  • 25:53 - 25:55
    instantiate function again,
  • 25:55 - 25:57
    but we're going to use it's return type.
  • 25:57 - 26:00
    So we're going to say that a rigidbody
  • 26:00 - 26:03
    called ShellInstance is equal to
  • 26:03 - 26:05
    Instantiate, the thing that we're going to instantiate
  • 26:05 - 26:07
    is the shell,
  • 26:07 - 26:09
    so m_Shell,
  • 26:09 - 26:12
    we're going to instantiate it at the FireTransform's position
  • 26:12 - 26:18
    so m_FireTransform.position
  • 26:19 - 26:21
    And we're going to instantiate it at the
  • 26:21 - 26:24
    FireTransform's rotation as well.
  • 26:24 - 26:27
    So it's m_FireTransform.rotation.
  • 26:28 - 26:30
    So that's the last parameter that we've got there.
  • 26:31 - 26:35
    But instantiate actually returns something just
  • 26:35 - 26:38
    an object, it doesn't return a rigidbody naturally.
  • 26:38 - 26:40
    So in order to assign it a rigidbody
  • 26:41 - 26:44
    what we do is we say as Rigidbody at the end.
  • 26:44 - 26:46
    And what that'll do is it'll say
  • 26:46 - 26:48
    'I've created an object, can I treat this as a rigidbody?
  • 26:48 - 26:50
    Well it's got a rigidbody component,
  • 26:50 - 26:52
    so yes, and I'll return that'.
  • 26:52 - 26:54
    So effectively this is doing two things at once,
  • 26:54 - 26:57
    we're instantiating and we're placing the rigidbody in to the scene
  • 26:57 - 26:59
    and we're also assigning it to a variable that we can
  • 26:59 - 27:01
    give a velocity.
  • 27:01 - 27:03
    Okay, so let's do that.
  • 27:04 - 27:06
    So ShellInstance is a rigidbody
  • 27:06 - 27:09
    so it has a velocity, now a velocity has
  • 27:09 - 27:11
    a type of vector3
  • 27:11 - 27:13
    so what we're going to do is
  • 27:13 - 27:17
    give it a direction, which is the FireTransform's forward direction,
  • 27:17 - 27:20
    and a magnitude, which is the CurrentLaunchForce.
  • 27:21 - 27:30
    So we'll do m_CurrentLaunchForce * m_FireTransform.forward
  • 27:30 - 27:34
    So all that's saying is 'in the forward direction of the FireTransform
  • 27:34 - 27:37
    with an amount equal to the CurrentLaunchForce.
  • 27:38 - 27:40
    So that's launched the shell,
  • 27:40 - 27:42
    all successfully, but we do need to change the
  • 27:42 - 27:44
    audio that's playing as we were just mentioning earlier.
  • 27:45 - 27:49
    So ShootingAudio.Clip gets set to the fireClip.
  • 27:50 - 27:53
    And that will automatically stop the audio source from playing.
  • 27:53 - 27:56
    So we need to play the audio source with the new clip.
  • 27:56 - 28:00
    So m_ShootingAudio.Play.
  • 28:00 - 28:01
    And the last thing we need to do,
  • 28:01 - 28:04
    well we don't need to, this is more of a safety catch,
  • 28:04 - 28:06
    is we're setting the CurrentLaunchForce
  • 28:07 - 28:09
    equal to the MinLaunchForce.
  • 28:09 - 28:12
    So that's just making sure that if
  • 28:12 - 28:14
    some button press sneaks in there
  • 28:14 - 28:16
    then we're not going to launch it twice with
  • 28:17 - 28:19
    maximum velocity or something.
  • 28:19 - 28:21
    That is the bottom of that script so do save,
  • 28:21 - 28:23
    switch back to the editor, have a look at
  • 28:23 - 28:26
    the console for any errors that you might have.
  • 28:29 - 28:31
    Cool, okay, wonderful.
  • 28:32 - 28:34
    Let's hope that I got it right!
  • 28:35 - 28:36
    Which I did.
  • 28:36 - 28:38
    Okay, so reselect the Tank and we need to
  • 28:38 - 28:40
    populate this, so as many of you
  • 28:40 - 28:42
    are probably discovering as you're running ahead and
  • 28:42 - 28:44
    trying to press play and hoping to shoot things
  • 28:44 - 28:46
    it won't work just yet, because we haven't
  • 28:46 - 28:49
    assigned those public variables that we need to.
  • 28:50 - 28:52
    So on TankShooting we need to assign
  • 28:52 - 28:54
    a few things, so our shell you'll remember
  • 28:54 - 28:57
    is a prefab, so delve in to the Prefabs folder
  • 28:57 - 29:00
    in to project and grab your Shell prefab
  • 29:00 - 29:03
    and drop it on to where it says Non (Rigidbody).
  • 29:03 - 29:05
    That will assign it there.
  • 29:05 - 29:07
    Then the Fire Transform is a child of
  • 29:07 - 29:09
    the Tank, if you expand the Tank
  • 29:10 - 29:12
    you will find FireTransform.
  • 29:13 - 29:15
    Drag and drop that on.
  • 29:15 - 29:17
    Likewise with the Aim Slider,
  • 29:17 - 29:19
    the AimSlider is the game object to assign there.
  • 29:20 - 29:23
    And then Shooting Audio is the slightly trickier one.
  • 29:23 - 29:25
    I'm grabbing the second audio source
  • 29:25 - 29:27
    so the title, make sure you collapse
  • 29:27 - 29:29
    and it's a lot easier to do,
  • 29:29 - 29:31
    grab the title of that component,
  • 29:31 - 29:34
    drop it on to the variable Shooting Audio.
  • 29:34 - 29:37
    So grab the component name, drop it on there.
  • 29:37 - 29:40
    And the last two should be fairly self explanatory,
  • 29:40 - 29:42
    they're just two audio clips, ChargingClip,
  • 29:42 - 29:44
    use the circle select
  • 29:44 - 29:46
    ShotCharging.
  • 29:47 - 29:49
    You can use circle select whilst the window is still open
  • 29:49 - 29:51
    to just switch to assigning something else.
  • 29:52 - 29:56
    I'm just going to select that and ShotFiring for the second one.
  • 29:57 - 29:59
    So it should be assigned and it should look like that.
  • 29:59 - 30:02
    Okay, so what I would like you to notice
  • 30:03 - 30:05
    is that with the tank we've added
  • 30:05 - 30:07
    a few things to the tank since we last
  • 30:07 - 30:09
    updated the prefab, and as we know when
  • 30:09 - 30:11
    we don't update a prefab we have
  • 30:11 - 30:13
    things that are in grey and not in blue
  • 30:13 - 30:15
    to indicate that they're part of the
  • 30:15 - 30:18
    prefab version that's saved in the project.
  • 30:18 - 30:20
    So with the Tank selected I would like you
  • 30:20 - 30:22
    to hit Apply at the top of the inspector
  • 30:22 - 30:25
    to update that prefab, it's very important
  • 30:25 - 30:27
    that the version in the project
  • 30:27 - 30:29
    is the finished version that we've made so far.
  • 30:30 - 30:33
    So hit Apply at the top of the inspector
  • 30:33 - 30:36
    then all of the child objects underneath that,
  • 30:36 - 30:38
    so remember you can alt-click the arrow to expand all,
  • 30:38 - 30:40
    they should all be in blue right now.
  • 30:40 - 30:42
    So Apply with the tank selected.
  • 30:44 - 30:47
    Okay, so the tank is now finished.
  • 30:47 - 30:48
    But we don't want it to stay in the scene.
  • 30:48 - 30:50
    We do want to just make sure it works,
  • 30:50 - 30:52
    So I'm just going to hit Play.
  • 30:53 - 30:55
    I'm just going to turn my volume down, or off.
  • 30:55 - 30:56
    Actually I'm going to leave it on so you can see
  • 30:56 - 30:58
    how it's meant to sound like.
  • 31:02 - 31:04
    The keen-eared among you will notice that the mix
  • 31:04 - 31:08
    is terrible, you can't really hear the charging and the shooting,
  • 31:08 - 31:10
    we'll fix that at the end with audio mixing,
  • 31:10 - 31:12
    so that's all going to sound great by the time we're finished
  • 31:12 - 31:14
    so don't worry about that.
  • 31:14 - 31:16
    But for now you should just be able to drive
  • 31:16 - 31:18
    the tank around, charge up a shot,
  • 31:18 - 31:20
    or do small shots.
  • 31:21 - 31:23
    Or you can so what Mike likes to refer to as
  • 31:23 - 31:26
    as death lotus, this move.
  • 31:28 - 31:30
    But once you've done that the tank is complete.
  • 31:30 - 31:32
    Once you've hit apply we're going to get rid
  • 31:32 - 31:35
    of it out of the scene, it's finished, it's ready
  • 31:35 - 31:37
    to be used by the game manager.
  • 31:37 - 31:39
    So I'm going to select my tank,
  • 31:39 - 31:41
    make sure you've updated, saved your prefab.
  • 31:42 - 31:44
    Command-backspace to delete it,
  • 31:44 - 31:47
    or delete on PC, save your scene once you've got rid of your tank.
Title:
TANKS! Unity Tutorial - Phase 6 of 8 - Firing Shells
Description:

more » « less
Video Language:
English
Duration:
31:50

English subtitles

Revisions