text: - Обучение
  - Tanks tutorial
  - Shell Creation
  Shell Creation
  Проверено с версией:: 5.2
  -
  Сложность: Средняя
  Phase 5 teaches you how to create a Shell for the tank, creating a radius for explosion.
  Shell Creation
  Средняя Tanks tutorial
  Транскрипты
  - 00:01 - 00:04
  In this phase we're going to create
  - 00:04 - 00:06
  this shell prefab, it looks like this
  - 00:06 - 00:08
  and has a number of different components,
  - 00:08 - 00:11
  it's got a collider, a rigidbody, it has a light component,
  - 00:12 - 00:15
  and the idea with this is that obviously we'll
  - 00:15 - 00:18
  fire it from the tank, but to demonstrate what it does,
  - 00:18 - 00:20
  it has an overlapped sphere
  - 00:20 - 00:23
  this is a kind of sphere of damage that it can
  - 00:24 - 00:26
  give to any of the tanks that i lands near.
  - 00:26 - 00:28
  So in this video what I'm doing is slowly moving it
  - 00:28 - 00:30
  closer to the tank and what you should notice is that
  - 00:30 - 00:33
  that health is getting reduced by more
  - 00:33 - 00:35
  the closer that that bullet happens to be.
  - 00:36 - 00:38
  Or at least it will do in a moment.
  - 00:38 - 00:40
  Off we go, moving it closer.
  - 00:40 - 00:42
  The closer it is the more damage that will be applied.
  - 00:42 - 00:44
  Obviously if you hit a tank dead-on then
  - 00:44 - 00:46
  that will be a huge amount of damage.
  - 00:48 - 00:50
  That's the shell that we're going to make and then in the next
  - 00:50 - 00:52
  phase after that we'll handle the actual shooting,
  - 00:52 - 00:54
  but first off we're going to handle the damage,
  - 00:54 - 00:56
  or the thing that's going to parse damage to
  - 00:56 - 00:58
  the TankHealth script that we did before.
  - 00:58 - 01:00
  What I would like everyone to do is look in
  - 01:00 - 01:02
  the Models folder, in this folder
  - 01:02 - 01:05
  you will find a model called Shell.
  - 01:06 - 01:09
  If you select it it will look like this in the inspector.
  - 01:09 - 01:11
  A little note, if you want to inspect something,
  - 01:11 - 01:13
  drag around it, you can just drag in that preview window
  - 01:13 - 01:15
  at the bottom of the inspector.
  - 01:15 - 01:18
  So what we'll do is drag that in to the hierarchy.
  - 01:18 - 01:20
  If we drag and drop that model from
  - 01:20 - 01:22
  the project to the hierarchy.
  - 01:23 - 01:25
  Move your cursor over the scene view,
  - 01:25 - 01:27
  press F to frame selected
  - 01:27 - 01:29
  and you'll notice it's at the origin, roughly,
  - 01:29 - 01:31
  so it's near to 0.
  - 01:31 - 01:33
  So all I'm going to do is just to drag mine
  - 01:33 - 01:35
  up slightly so it's somewhere I can
  - 01:35 - 01:37
  see it and work on it, something like that is fine.
  - 01:39 - 01:41
  Remember because we're creating a prefab that
  - 01:41 - 01:43
  we're going to fire with the tank this isn't something that's
  - 01:43 - 01:45
  going to be in the scene when the game starts
  - 01:45 - 01:47
  just like the tank, so we don't need to worry about
  - 01:47 - 01:49
  where it's positioned for now.
  - 01:52 - 01:54
  So because we are making
  - 01:54 - 01:56
  this something that's going to interact with other objects
  - 01:56 - 01:59
  it needs to have a collider.
  - 01:59 - 02:01
  We'll use primitive colliders because they're
  - 02:01 - 02:04
  nice and performant, and given the shape of this
  - 02:04 - 02:06
  we'll use a capsule collider.
  - 02:06 - 02:08
  So with that shell still selected
  - 02:08 - 02:11
  in the inspector we'll hit the Add Component button
  - 02:11 - 02:13
  and I'm just going to type Caps
  - 02:13 - 02:15
  for Capsule and then
  - 02:15 - 02:17
  click on it to confirm, or hit Return.
  - 02:18 - 02:19
  With that capsule collider,
  - 02:20 - 02:22
  because when you are firing things
  - 02:22 - 02:25
  like a projectile as we are.
  - 02:26 - 02:28
  We don't want things to be bouncing off one another
  - 02:28 - 02:30
  and we don't expect this tank shell to
  - 02:30 - 02:32
  ever hit something and push it back,
  - 02:32 - 02:34
  we're expecting it to hit something,
  - 02:34 - 02:36
  create a call back in the script and then create
  - 02:36 - 02:38
  an explosion force.
  - 02:38 - 02:40
  So we don't want any physical interactions.
  - 02:41 - 02:44
  And when we don't want those we use what's called triggers.
  - 02:44 - 02:46
  If you hear someone refer to a trigger
  - 02:46 - 02:48
  or a trigger zone,
  - 02:48 - 02:50
  or a trigger area they're usually referring to
  - 02:50 - 02:52
  a collider that's been checked
  - 02:52 - 02:54
  as a trigger.
  - 02:54 - 02:56
  So if you check the Is Trigger checkbox on that,
  - 02:57 - 03:00
  what that basically means is that it doesn't have
  - 03:00 - 03:02
  it doesn't have a solid surface to it
  - 03:02 - 03:04
  it can intersect, but if can send a
  - 03:04 - 03:05
  call back to the script saying
  - 03:05 - 03:07
  'I've now entered another trigger' or
  - 03:07 - 03:09
  'I've entered another collider'.
  - 03:09 - 03:11
  So often trigger colliders are used for things like
  - 03:11 - 03:13
  doors in games, like when you put a big
  - 03:13 - 03:15
  cubic collider in front of
  - 03:15 - 03:17
  a doorway and then when the character enters that way
  - 03:17 - 03:19
  you automatically open the door.
  - 03:19 - 03:22
  It's a pretty classic use of that kind of collider.
  - 03:23 - 03:25
  Once you've added that component, the next thing
  - 03:25 - 03:27
  we want to do is actually set it up.
  - 03:29 - 03:31
  So we need to change the centre,
  - 03:31 - 03:34
  so the centre value for that is (0, 0, 0.2).
  - 03:36 - 03:39
  And the radius is 0.15.
  - 03:41 - 03:43
  And the height is 0.55.
  - 03:46 - 03:48
  Crucially you'll notice that it's not
  - 03:48 - 03:52
  looking in the right direction, so we set the direction
  - 03:52 - 03:55
  to Z axis, and then it should
  - 03:55 - 03:58
  pretty much match our shell perfectly.
  - 03:58 - 04:01
  Or to an amount of precision that would never cause issues.
  - 04:02 - 04:04
  It should look like that.
  - 04:05 - 04:07
  And then finally because this is a physics object
  - 04:07 - 04:09
  we need it to be under control of
  - 04:09 - 04:11
  the physics engine, and so what are we going to add?
  - 04:12 - 04:14
  A rigidbody, there we go, nice and loud.
  - 04:16 - 04:18
  So add our rigidbody component.
  - 04:20 - 04:21
  And it's good to go.
  - 04:21 - 04:23
  So these shells are going to fire
  - 04:23 - 04:25
  a projectile, they're not going to just keep going straight forward,
  - 04:25 - 04:27
  they're going to fall with gravity over time.
  - 04:27 - 04:29
  So just a quick recap of those two points.
  - 04:30 - 04:34
  Okay, so we've found the model named Shell in the Models folder.
  - 04:35 - 04:37
  We dragged it in to the hierarchy.
  - 04:38 - 04:41
  We've added a capsule collider component to the shell
  - 04:41 - 04:43
  and we've made sure it's a trigger so that that
  - 04:43 - 04:45
  trigger won't bounce off of anything
  - 04:45 - 04:48
  it's just going to pass straight through stuff
  - 04:48 - 04:50
  and then immediately be destroyed by the script
  - 04:50 - 04:52
  that we're going to write.
  - 04:52 - 04:54
  We've checked Is Trigger to make sure that is the case.
  - 04:57 - 05:00
  Then we set the direction to Z axis
  - 05:00 - 05:02
  and we changed the centre, so the centre is
  - 05:02 - 05:04
  basically where that originates from so you can
  - 05:04 - 05:06
  kind of offset your colliders if you need to, art-wise.
  - 05:07 - 05:11
  And the radius we've set to 0.15, the radius of the capsule.
  - 05:11 - 05:13
  And the height to 0.55
  - 05:13 - 05:15
  And we added a rigidbody to make sure that it's
  - 05:15 - 05:18
  under the control of the physics engine.
  - 05:21 - 05:23
  So we've got the shell
  - 05:23 - 05:25
  and currently the shell can fall down
  - 05:25 - 05:27
  and nothing is going to really happen.
  - 05:27 - 05:29
  It's just going to go straight through the ground
  - 05:29 - 05:31
  because it's not going to stop, it hasn't got a
  - 05:31 - 05:33
  physical presence, like I said.
  - 05:33 - 05:35
  So we don't want that, we want it to actually
  - 05:35 - 05:38
  explode and do stuff, so we've created
  - 05:38 - 05:40
  a shell explosion for you.
  - 05:40 - 05:42
  So if you look in the Prefabs folder
  - 05:43 - 05:46
  you will find a prefab called ShellExplosion.
  - 05:47 - 05:49
  So what we're going to do with that is make it
  - 05:49 - 05:50
  a child of the shell.
  - 05:51 - 05:53
  So if you drag from the Prefabs folder and drop
  - 05:53 - 05:54
  it on to the shell
  - 05:55 - 05:56
  It should look like that.
  - 05:58 - 06:00
  And when we simulate it
  - 06:01 - 06:02
  it looks like this.
  - 06:02 - 06:05
  A cloud of dust that kind of falls over time.
  - 06:09 - 06:11
  Okay and then the only other thing that we need
  - 06:11 - 06:13
  to do with that is to
  - 06:13 - 06:15
  add an audio source,
  - 06:15 - 06:17
  so similar to the tank exploding,
  - 06:17 - 06:20
  it needs to have visual effects and an audio effect.
  - 06:20 - 06:22
  So I'm going to click the Add Component button
  - 06:22 - 06:24
  and I'm going to choose Audio Source.
  - 06:25 - 06:27
  And then just like before we need an
  - 06:27 - 06:29
  audio clip, so I'm going to use the
  - 06:29 - 06:31
  circle select next to audio clip
  - 06:32 - 06:35
  and choose ShellExplosion to assign it.
  - 06:37 - 06:39
  Now we don't want this to play as soon as the shell
  - 06:39 - 06:41
  gets instantiated, as soon as the explosion appears,
  - 06:42 - 06:44
  so we're going to uncheck Play On Awake.
  - 06:45 - 06:48
  A quick recap, so we've got our ShellExplosion prefab,
  - 06:48 - 06:52
  we had to make it a child of the Shell game object
  - 06:52 - 06:54
  so it's going to travel with it and then do it's
  - 06:54 - 06:56
  thing as soon as it hits something.
  - 06:56 - 06:58
  We added an audio source to that
  - 06:58 - 07:01
  so that it's able to playback sound and we've used
  - 07:01 - 07:04
  circle select to set the audio clip to ShellExplosion.
  - 07:04 - 07:06
  We don't want it to play as soon as it enters
  - 07:06 - 07:08
  the world so we only want it to play
  - 07:08 - 07:11
  as soon as it impacts, so we uncheck Play On Awake.
  - 07:15 - 07:17
  Okay, the final thing we're going to do with the shell
  - 07:17 - 07:20
  so reselect the shell, the parent object,
  - 07:20 - 07:22
  is to add a light.
  - 07:22 - 07:24
  So as this travels across the
  - 07:24 - 07:26
  game board we want this to
  - 07:26 - 07:28
  light up the environment
  - 07:28 - 07:30
  and it helps pick out the shell, because obviously
  - 07:30 - 07:32
  you've got a gold shell, you've got orange sand,
  - 07:32 - 07:36
  it's kind of hard to see it and the light helps pick it out
  - 07:36 - 07:39
  so instead of creating a point light game object
  - 07:39 - 07:42
  we can just add that same light.
  - 07:42 - 07:44
  So if you've new to Unity, what you'll notice
  - 07:44 - 07:46
  if you go to Game Object - Create
  - 07:46 - 07:48
  is that you've got all these readymade
  - 07:48 - 07:50
  prefabbed game objects with several components on them.
  - 07:50 - 07:52
  So for example if you choose,
  - 07:52 - 07:54
  if there was a cube, then you've got
  - 07:54 - 07:56
  a bunch of different components on it.
  - 07:56 - 07:59
  But you could also create a light
  - 08:00 - 08:02
  which has just the light component on it.
  - 08:02 - 08:04
  We don't need to do that, we're just going to put the
  - 08:04 - 08:06
  component directly on to the shell,
  - 08:06 - 08:08
  so I got to Add Component - Light
  - 08:09 - 08:11
  So now we have to actually handle
  - 08:11 - 08:13
  how that behaves, how it's going to
  - 08:13 - 08:15
  impact and what it's going to do when it hits
  - 08:15 - 08:17
  a tank or when it hits the environment and the
  - 08:17 - 08:20
  kind of forces it's going to apply to other tanks in the game.
  - 08:21 - 08:23
  So what we're going to do is to look
  - 08:23 - 08:25
  in the Scripts folder and
  - 08:25 - 08:27
  find the Shell folder.
  - 08:27 - 08:31
  In that you will find a script called ShellExplosion.
  - 08:32 - 08:35
  So we're going to drag and drop ShellExplosion on to the Shell
  - 08:35 - 08:37
  game object in the hierarchy.
  - 08:38 - 08:40
  And then you should see
  - 08:40 - 08:42
  that along with everything else, the rigidbody,
  - 08:42 - 08:45
  the capsule collider, the light that we just added,
  - 08:45 - 08:47
  you've now got Shell Explosion (Script)
  - 08:47 - 08:50
  and we're going to double click on that to open it up for editing.
  - 08:54 - 08:57
  Okay, so in this one we don't have any private
  - 08:57 - 09:00
  variables but we do have a bunch of public ones.
  - 09:00 - 09:02
  So the first one is a layer mask.
  - 09:02 - 09:04
  Now you might remember at the beginning of the day
  - 09:04 - 09:07
  we put all the tanks on the Players layer.
  - 09:07 - 09:09
  So that means that when we cause an
  - 09:09 - 09:11
  explosion from the shell we can just
  - 09:11 - 09:13
  check for everything that's on the Players layer
  - 09:13 - 09:17
  and see which tanks we've hit rather than trying to affect everything.
  - 09:17 - 09:19
  So that will be available in the inspector
  - 09:19 - 09:21
  and we can choose which layer we want to affect.
  - 09:22 - 09:25
  The next is the explosion particle,
  - 09:25 - 09:28
  remember we just dragged on that as a child game object
  - 09:28 - 09:30
  we're going to get a reference to that so we can
  - 09:30 - 09:32
  play the particles when the shell explodes.
  - 09:33 - 09:35
  Likewise there's an audio source reference,
  - 09:35 - 09:38
  so that's for getting a reference to that audio source
  - 09:38 - 09:39
  so we can play a sound.
  - 09:39 - 09:41
  Then we've got a bunch of floats,
  - 09:41 - 09:43
  so the first one is the most
  - 09:43 - 09:45
  damage that it can possibly do,
  - 09:45 - 09:47
  the maximum damage, and we're setting that to 100.
  - 09:47 - 09:49
  so if you get a perfect direct hit
  - 09:49 - 09:51
  then you'll kill the tank outright.
  - 09:52 - 09:54
  But you can't get a perfect hit because
  - 09:54 - 09:56
  it's never going to be exactly on the position
  - 09:56 - 09:58
  of the tank because the collider is covering it.
  - 09:59 - 10:01
  So you're going to get close but no cigar.
  - 10:01 - 10:03
  The next one is the amount of force
  - 10:03 - 10:06
  that the explosion is going to do right at it's centre.
  - 10:06 - 10:08
  Likewise as the explosion radius
  - 10:08 - 10:10
  gets further out the tank will be
  - 10:10 - 10:13
  less affected by the explosion, you'll feel less force.
  - 10:14 - 10:16
  We've got the max lifetime, so we don't want
  - 10:16 - 10:18
  shells to exist forever
  - 10:18 - 10:20
  so if they happen to miss everything
  - 10:20 - 10:22
  we don't want them to stay in the scene forever so
  - 10:22 - 10:24
  we give them a lifetime,
  - 10:24 - 10:26
  and at the start of the scene we'll say
  - 10:26 - 10:28
  if it's not dead after 2 seconds just kill it anyway.
  - 10:29 - 10:31
  So it's pretty unlikely you'll ever see that,
  - 10:31 - 10:33
  it would either hit the ground or
  - 10:33 - 10:35
  some other object before that ever happened,
  - 10:35 - 10:37
  but it's just a failsafe that we'll write in.
  - 10:37 - 10:39
  So the last public variable is
  - 10:39 - 10:41
  the explosion radius.
  - 10:41 - 10:43
  And that is literally how far
  - 10:43 - 10:46
  from the shell it's going to affect when it explodes.
  - 10:48 - 10:50
  Okay, so let's look at these functions
  - 10:50 - 10:52
  and as we're just mentioning
  - 10:52 - 10:54
  in the Start function we're saying destroy
  - 10:54 - 10:56
  the game object
  - 10:56 - 10:58
  after the max lifetime.
  - 10:58 - 11:01
  So that's saying when you instantiate this
  - 11:01 - 11:04
  if it's still alive after 2 seconds, destroy it.
  - 11:06 - 11:08
  And now we're going to have to write some scripts.
  - 11:10 - 11:12
  So the first thing we want to do,
  - 11:12 - 11:14
  when OnTriggerEnter is called, so you remember we
  - 11:14 - 11:17
  put Is Trigger as True, that means that
  - 11:17 - 11:19
  OnTriggerEnter is called when something
  - 11:19 - 11:21
  bumps in to this.
  - 11:21 - 11:23
  So this function will
  - 11:23 - 11:25
  happen whenever it intersects with anything
  - 11:25 - 11:27
  and then we need to check what it's
  - 11:27 - 11:29
  intersected with and what to do as a result.
  - 11:29 - 11:31
  So we have this argument
  - 11:31 - 11:33
  which we've just called other which is of type Collider.
  - 11:33 - 11:35
  So it's going to say 'okay, we've intersected
  - 11:35 - 11:38
  with something else, it's a collider, what do we do about it?'
  - 11:39 - 11:41
  In this case we don't actually care what we're bumping in to
  - 11:41 - 11:43
  just that it's a collider,
  - 11:43 - 11:45
  so we should explode.
  - 11:45 - 11:46
  But what do we do first?
  - 11:46 - 11:48
  First of all we need to gather up all of the
  - 11:48 - 11:50
  colliders that we need to affect.
  - 11:50 - 11:52
  So we need an array of colliders
  - 11:52 - 11:54
  and you'll remember that's the square brackets after a collider.
  - 11:55 - 11:57
  And we'll call that array Colliders.
  - 11:58 - 12:00
  And we're going to set that to the return of
  - 12:00 - 12:02
  a function called OverlapSphere.
  - 12:02 - 12:05
  So that's Physics.OverlapSphere
  - 12:08 - 12:10
  And what that's going to do is similar to a ray cast,
  - 12:10 - 12:14
  it's going to create an imaginary sphere
  - 12:14 - 12:17
  and everything that overlaps with that sphere
  - 12:17 - 12:20
  or is inside the sphere is going to be collected.
  - 12:20 - 12:22
  And we want that sphere to be at
  - 12:22 - 12:24
  the shell's location, so transform.position
  - 12:24 - 12:26
  for it's position.
  - 12:27 - 12:29
  It's going to have a radius that we've already
  - 12:29 - 12:31
  got as an ExplosionRadius.
  - 12:31 - 12:33
  And we're going to use that TankMask
  - 12:33 - 12:35
  so that it's only picking up the tanks.
  - 12:40 - 12:42
  Okay, so just a quick note about layers.
  - 12:42 - 12:44
  Layers we use for various different things
  - 12:44 - 12:46
  in Unity but ostensibly they're
  - 12:46 - 12:48
  just for grouping things together in
  - 12:48 - 12:50
  some way that you want to use
  - 12:50 - 12:52
  to either include of exclude them from something.
  - 12:52 - 12:54
  In this case we're using it as a way of
  - 12:54 - 12:57
  only including or sort of masking out
  - 12:57 - 12:59
  anything but tanks, which is why we've called this
  - 12:59 - 13:03
  variable TankMask, because it's essentially a layer on
  - 13:03 - 13:05
  which only the tanks exist.
  - 13:05 - 13:07
  But don't think of it in any visual terms,
  - 13:07 - 13:10
  if anyone's in to Photoshop or anything like that
  - 13:10 - 13:13
  there's no kind of layering in that sense.
  - 13:13 - 13:15
  Okay, so now we've got all our colliders
  - 13:15 - 13:17
  we need to go through them all and
  - 13:17 - 13:19
  decide what we're going to do.
  - 13:20 - 13:22
  So for that we need to
  - 13:22 - 13:24
  loop through them all using a For Loop.
  - 13:24 - 13:26
  So this is the same format as we saw before
  - 13:27 - 13:30
  for(int i = 0
  - 13:30 - 13:33
  i is less than colliders.length
  - 13:33 - 13:35
  so this is, colliders is the array that we're going
  - 13:35 - 13:38
  through so it's less than colliders.Length.
  - 13:38 - 13:41
  And then i++ means that we add to i for every loop.
  - 13:43 - 13:47
  Then open and close brackets?
  - 13:47 - 13:49
  Brackets? Yes brackets.
  - 13:49 - 13:51
  And then we can
  - 13:51 - 13:53
  use whatever we do in that for loop
  - 13:53 - 13:55
  to affect each of the colliders.
  - 13:55 - 13:57
  So the first thing we want to do is check
  - 13:57 - 13:59
  whether the thing that we've hit has
  - 13:59 - 14:01
  a rigidbody, so what we do is we
  - 14:01 - 14:04
  create a rigidbody variable
  - 14:04 - 14:06
  which we'll call targetRigidbody
  - 14:06 - 14:11
  and we'll set that equal to colliders[i], so that's
  - 14:11 - 14:13
  the collider at the position that we're
  - 14:13 - 14:15
  currently iterating through in the array,
  - 14:16 - 14:20
  .GetComponent,
  - 14:20 - 14:22
  so we'll use the angled brackets for rigidbody.
  - 14:23 - 14:25
  So what that's going to do is
  - 14:25 - 14:27
  get that collider that we've just gone through
  - 14:27 - 14:30
  the array and try and find a rigidbody on it.
  - 14:31 - 14:33
  Next we need to know if it's actually
  - 14:33 - 14:36
  found a rigidbody or if it's just found nothing.
  - 14:37 - 14:40
  So what we're going to do is say if
  - 14:41 - 14:43
  not target(!Rigidbody)
  - 14:43 - 14:47
  so what that's going to do is say
  - 14:47 - 14:49
  if there's nothing there then what do I do?
  - 14:50 - 14:52
  And if there's nothing there we want to continue
  - 14:52 - 14:54
  on to the next loop, on the the next collider.
  - 14:54 - 14:56
  You'll remember it's going back to the
  - 14:56 - 14:58
  start of the for loop and carrying on looking
  - 14:58 - 15:00
  for any collider that's got a rigidbody
  - 15:00 - 15:03
  it's not continuing through a list of commands.
  - 15:03 - 15:05
  So bear in mind that this is a bit of a
  - 15:05 - 15:07
  safety catch kind of thing because we're making it
  - 15:07 - 15:09
  everything that's on the Players layer anyway.
  - 15:09 - 15:11
  So everything should have a collider
  - 15:12 - 15:14
  and everything that has a collider there will also
  - 15:14 - 15:17
  have a rigidbody, so we should always find something
  - 15:17 - 15:19
  but it's good to check just in case because otherwise
  - 15:19 - 15:21
  you're going to get errors.
  - 15:21 - 15:23
  So now we know we've got a rigidbody what
  - 15:23 - 15:26
  we can do is we can add a force to that rigidbody
  - 15:26 - 15:32
  so targitRigidbody.AddExplosionForce (
  - 15:33 - 15:35
  and the force we want to add is the
  - 15:35 - 15:37
  ExplosionForce that we've got as a public variable.
  - 15:37 - 15:40
  So that's m_ExplosionForce.
  - 15:41 - 15:44
  Then comma, so we're on to the next parameter.
  - 15:44 - 15:46
  And the position that that explosion
  - 15:46 - 15:49
  force is emanating from is transform.position.
  - 15:50 - 15:52
  So that's position of the shell.
  - 15:53 - 15:55
  And then the last parameter that we're going to use is
  - 15:55 - 15:57
  the radius, so how far away
  - 15:57 - 16:00
  that explosion force can reach.
  - 16:05 - 16:09
  Okay, so we've added the force now
  - 16:09 - 16:11
  so the tank is going to move but we still need
  - 16:11 - 16:13
  to actually cause some damage to it.
  - 16:13 - 16:15
  So we're going to do something very similar.
  - 16:15 - 16:17
  We're going to create a TankHealth variable,
  - 16:18 - 16:20
  which we'll call targetHealth.
  - 16:22 - 16:24
  So just to qualify that, notice that when we've
  - 16:24 - 16:26
  made these other variables they've been familiar
  - 16:26 - 16:28
  components to things that you've
  - 16:28 - 16:30
  added using the Add Component button.
  - 16:31 - 16:33
  This time we're making a variable
  - 16:33 - 16:35
  of type TankHealth.
  - 16:35 - 16:38
  So that just means an instance of the TankHealth script
  - 16:38 - 16:41
  on a tank, let's go back from the top.
  - 16:41 - 16:43
  So we've gathered all the colliders we could find
  - 16:43 - 16:45
  within the imaginary sphere, the overlap sphere.
  - 16:46 - 16:48
  And we're looping through
  - 16:48 - 16:50
  that list, that array,
  - 16:50 - 16:53
  to the amount that there is, colliders found.
  - 16:53 - 16:55
  And then with each one we're
  - 16:55 - 16:57
  checking that there's a rigidbody and if there is
  - 16:57 - 16:59
  we're adding a force,
  - 16:59 - 17:01
  and then we want to actually also
  - 17:01 - 17:03
  take damage on those tanks.
  - 17:03 - 17:05
  So we're addressing a particular
  - 17:05 - 17:07
  instance of that TankHealth script so we can
  - 17:07 - 17:09
  talk to it and reduce health with it.
  - 17:10 - 17:13
  Okay, so we've got TankHealth targetHealth
  - 17:13 - 17:16
  and we're going to set that equal to the targetRigidbody.
  - 17:17 - 17:19
  GetComponent TankHealth.
  - 17:19 - 17:21
  So we've got the rigidbody, we know that now
  - 17:22 - 17:24
  because we were able to add a force to it.
  - 17:24 - 17:26
  So on the same game object as that
  - 17:27 - 17:28
  get the component TankHealth.
  - 17:28 - 17:31
  And again we should know that
  - 17:31 - 17:33
  there's definitely going to be a TankHealth here
  - 17:33 - 17:35
  but we're going to check just to make sure.
  - 17:35 - 17:37
  Because if somebody wants to extend the game and they
  - 17:37 - 17:41
  make something that's on the Players layer that doesn't have TankHealth
  - 17:41 - 17:43
  then this will still work.
  - 17:43 - 17:45
  So again instead of if(!rigidbody) we've got
  - 17:45 - 17:49
  if(!targetHealth) and then continue.
  - 17:49 - 17:51
  So if there's no targetHealth continue
  - 17:51 - 17:53
  on to the next iteration.
  - 17:54 - 17:56
  So a quick note about this line here.
  - 17:56 - 17:58
  So you'll notice that we've talked about
  - 17:58 - 18:00
  the fact that we need a reference to this instance
  - 18:00 - 18:02
  of the TankHealth script.
  - 18:02 - 18:04
  So you might wondering 'well what's that got to do with
  - 18:04 - 18:07
  the rigidbody, what's health got to do with physics?'
  - 18:07 - 18:09
  Nothing at all, the point is that we've found
  - 18:09 - 18:11
  a particular game object
  - 18:11 - 18:13
  the fact that we're calling it targetRigidbody
  - 18:13 - 18:15
  is not hugely important, we'e just referring to
  - 18:15 - 18:18
  the same game object that we've stored in that.
  - 18:18 - 18:20
  Often when we talk about rigidbodies
  - 18:20 - 18:22
  we'll say 'this is a rigidbody object'.
  - 18:22 - 18:26
  All things in the hierarchy are what we call game objects.
  - 18:26 - 18:28
  But often what people will say is
  - 18:28 - 18:29
  'that's a rigidbody object'.
  - 18:29 - 18:31
  It just means it's a game object with that
  - 18:31 - 18:32
  particular component attached.
  - 18:32 - 18:35
  So when we're talking about the target rigidbody
  - 18:35 - 18:37
  we just mean it's the tank game object that
  - 18:37 - 18:40
  we know has a rigidbody attached to it.
  - 18:40 - 18:42
  So we've done that check and we can then
  - 18:42 - 18:44
  say we know it's the right game object so
  - 18:44 - 18:46
  we know it's got the TankHealth script on it
  - 18:46 - 18:48
  and we'll carry on from there.
  - 18:48 - 18:51
  Just to reiterate what Will was saying there,
  - 18:51 - 18:53
  you don't need a game object to find
  - 18:53 - 18:55
  a component on it, you can use
  - 18:55 - 18:58
  a component reference to find another component.
  - 18:58 - 19:00
  So that's what's actually happening there.
  - 19:00 - 19:02
  You've got the rigidbody component, we want to find another
  - 19:02 - 19:04
  component on the same game object,
  - 19:04 - 19:06
  that's what we're doing.
  - 19:07 - 19:09
  Okay so we know that we've got
  - 19:09 - 19:11
  targetHealth because we've not come out of the loop yet
  - 19:11 - 19:13
  so let's create the damage,
  - 19:13 - 19:17
  so float damage is equal to
  - 19:17 - 19:19
  this CalculateDamage function which you can see at
  - 19:19 - 19:21
  the bottom of the screen there,
  - 19:21 - 19:22
  which we will write in a minute,
  - 19:22 - 19:24
  but what we need to do is give it the
  - 19:24 - 19:26
  position of the target,
  - 19:26 - 19:29
  because we need to know how far away is that target
  - 19:29 - 19:31
  from the shell when it explodes
  - 19:31 - 19:33
  so we know how much damage it needs to take.
  - 19:34 - 19:36
  So you can actually get the
  - 19:36 - 19:39
  position of something from the rigidbody as well.
  - 19:39 - 19:41
  If you remember back from the TankMovement script
  - 19:41 - 19:44
  we were doing things relative to the rigidbody's position.
  - 19:44 - 19:46
  That's the position that we're going to use here.
  - 19:48 - 19:50
  So we've got the damage
  - 19:50 - 19:52
  now we need to apply the damage.
  - 19:52 - 19:54
  So we've got the TargetHealth script,
  - 19:55 - 19:57
  and we need to call the takeDamage function
  - 19:57 - 19:59
  that we made earlier.
  - 20:01 - 20:04
  And we're going to parse in the amount of damage.
  - 20:08 - 20:10
  So that's all that we need to do for that for loop,
  - 20:10 - 20:12
  that's all that we need to do for each of the
  - 20:12 - 20:14
  targets that we've got, but we still need to
  - 20:14 - 20:16
  make the shell explode
  - 20:16 - 20:18
  and play the correct audio and stuff.
  - 20:19 - 20:21
  Yeah, another thing to mention about this is
  - 20:21 - 20:22
  we're creating a float called Damage,
  - 20:22 - 20:24
  we've got this CalculateDamage, currently if we play this
  - 20:24 - 20:26
  nothing would happen because we don't
  - 20:26 - 20:28
  have anything going on in this CalculateDamage
  - 20:28 - 20:30
  function just yet.
  - 20:30 - 20:32
  But all we're doing is just setting it up so when we do
  - 20:32 - 20:35
  we're going to parse that straight to the TakeDamage function.
  - 20:35 - 20:38
  If you remember when we looked at that TankHealth earlier
  - 20:39 - 20:41
  our TakeDamage function there is public,
  - 20:41 - 20:43
  that's how we're able to just reference it by saying
  - 20:43 - 20:45
  .TakeDamage.
  - 20:46 - 20:50
  Public being the accessibility level of that thing.
  - 20:51 - 20:53
  Okay, we've gone through all the colliders
  - 20:53 - 20:55
  that we need to do, so now we need to
  - 20:55 - 20:58
  sort out the particles and the audio.
  - 20:58 - 21:03
  So when we detonate the shell, when it explodes
  - 21:03 - 21:04
  we want to remove it from the scene,
  - 21:04 - 21:06
  we don't want it to hang around.
  - 21:06 - 21:08
  However if we remove it then the particles
  - 21:08 - 21:10
  are also going to be removed because they're children
  - 21:11 - 21:12
  and the audio source is also going to be removed
  - 21:12 - 21:13
  because that's a child.
  - 21:14 - 21:16
  So we want to make sure that those
  - 21:16 - 21:19
  still play even after we've destroyed the shell.
  - 21:20 - 21:22
  So what we're going to do to do that
  - 21:22 - 21:23
  is to unparent them.
  - 21:24 - 21:27
  So it will come in as a complete game object
  - 21:27 - 21:30
  it'll explode and they will decouple themselves
  - 21:30 - 21:32
  so the shell explosion will no longer
  - 21:32 - 21:34
  be part of the shell.
  - 21:35 - 21:37
  And we're going to do that by setting the
  - 21:37 - 21:39
  transform's parent to null.
  - 21:39 - 21:41
  So null just means nothing.
  - 21:41 - 21:43
  That means it would just be loose in the list
  - 21:43 - 21:44
  of game objects in the hierarchy.
  - 21:44 - 21:46
  So we have detached it now,
  - 21:46 - 21:49
  so next we need to play the
  - 21:49 - 21:55
  particle effect, so m_ExplosionParticles.Play ();
  - 21:57 - 21:59
  And likewise we want to play the audio
  - 21:59 - 22:01
  source so very similarly
  - 22:02 - 22:05
  m_ExplosionAudio.Play ();
  - 22:06 - 22:08
  So then we've just got a couple of more things
  - 22:08 - 22:10
  we've got to do in this function.
  - 22:10 - 22:12
  We need to destroy the particles and we
  - 22:12 - 22:14
  need to destroy the shell.
  - 22:14 - 22:16
  So to destroy the particles we're going to use
  - 22:16 - 22:18
  the same trick as we did in the Start function,
  - 22:18 - 22:20
  we're going to give it a delay.
  - 22:21 - 22:27
  So we're going to say Destroy(m_ExplosionParticles.gameObject
  - 22:27 - 22:29
  We don't want to destroy the particles because
  - 22:29 - 22:30
  that will destroy the component.
  - 22:30 - 22:33
  We want to destroy the game object that those particles are on.
  - 22:34 - 22:36
  And we're going to do that after
  - 22:36 - 22:38
  the duration of the particle system.
  - 22:39 - 22:41
  So you remember before we said that it's going to be
  - 22:41 - 22:43
  2 seconds, which was a number that decided on.
  - 22:44 - 22:46
  Well particle systems, one of their properties
  - 22:46 - 22:47
  is how long they last for.
  - 22:47 - 22:49
  So we're just going to say destroy it
  - 22:50 - 22:52
  after how long it lasts for.
  - 22:52 - 22:54
  Yeah, so not to be confused with the lifetime of
  - 22:54 - 22:57
  each particle, but the duration is the entire system.
  - 22:57 - 23:00
  So this, as you can see, autocomplete is showing us here
  - 23:00 - 23:02
  Optional amount of time before destroying the object.
  - 23:02 - 23:04
  We can simply just refer to
  - 23:04 - 23:06
  ExplosionParticles.duration
  - 23:07 - 23:09
  and that will simply wait for that to finish and then destroy it.
  - 23:09 - 23:11
  based on that.
  - 23:11 - 23:13
  Which is great, because you can then go and
  - 23:13 - 23:15
  adjust the duration and this code will still take
  - 23:15 - 23:16
  care of it for you.
  - 23:17 - 23:19
  And as James was saying, the last thing we need to do
  - 23:19 - 23:21
  once we'd destroyed the explosion, or once
  - 23:21 - 23:23
  we've triggered a destroy to occur once
  - 23:23 - 23:25
  it's finished playing the explosion
  - 23:25 - 23:27
  is actually to remove the shell as well.
  - 23:27 - 23:29
  So to do that all we do is
  - 23:29 - 23:32
  Destroy (gameObject) and that will destroy the
  - 23:32 - 23:34
  game object that this is on.
  - 23:34 - 23:36
  As ever with scripting everything is just
  - 23:36 - 23:38
  happening straight away, it's not like we're
  - 23:38 - 23:40
  waiting for one thing to happen and then something
  - 23:40 - 23:42
  else to happens, so theoretically you might
  - 23:42 - 23:45
  consider that you would get rid of the shell and then
  - 23:45 - 23:48
  the explosion but it really doesn't matter in this instance.
  - 23:49 - 23:52
  Okay, so, the last thing that we need
  - 23:52 - 23:54
  to do in this script is complete that
  - 23:54 - 23:56
  CalculateDamage function.
  - 23:57 - 23:59
  So in this CalculateDamage function
  - 23:59 - 24:01
  currently we've just got return 0f and that's
  - 24:01 - 24:03
  purely just so it doesn't spew errors
  - 24:03 - 24:05
  while we're working on the rest of the stuff.
  - 24:06 - 24:09
  So we're going to get rid of that to start off with, we don't need it.
  - 24:10 - 24:12
  And the next thing we're going to do is
  - 24:12 - 24:15
  create a vector from the target to the shell.
  - 24:15 - 24:17
  So that is going to be
  - 24:17 - 24:19
  Vector3 explosionToTarget.
  - 24:27 - 24:29
  and that is equal to
  - 24:29 - 24:32
  the target's position, minus the shell's position,
  - 24:32 - 24:34
  which is transform.position.
  - 24:37 - 24:39
  So if you imagine a big circle on the ground,
  - 24:39 - 24:42
  that's the explosion, at the centre of it is the shell,
  - 24:42 - 24:45
  and somewhere in that circle is the target.
  - 24:45 - 24:47
  We're finding a vector between the two.
  - 24:49 - 24:51
  The next thing we need to do is find out
  - 24:51 - 24:53
  how long that vector is,
  - 24:53 - 24:55
  the magnitude of that vector.
  - 24:55 - 24:59
  So what we're going to do is say float explosionDistance
  - 25:00 - 25:05
  is equal to explosionToTarget.magnitude.
  - 25:11 - 25:13
  Okay, so now we've found that distance,
  - 25:13 - 25:17
  which would be somewhere between 0 and the radius.
  - 25:18 - 25:22
  We want to know what the relative distance is.
  - 25:22 - 25:25
  Because we want a number from 0 to 1 really,
  - 25:25 - 25:29
  rather than a number between 0 and some radius that we found.
  - 25:29 - 25:31
  So the relative distance
  - 25:31 - 25:33
  we know the maximum it's going to be is
  - 25:33 - 25:36
  the radius and the minimum is going to be 0.
  - 25:37 - 25:39
  So what we need to do is calculate a number that
  - 25:39 - 25:42
  starts off at 0 and ends up at 1.
  - 25:42 - 25:45
  We do that by dividing by the explosion radius.
  - 25:45 - 25:50
  So relative distance is
  - 25:50 - 25:54
  (m_ExplosionRadius - explosionDistance)
  - 25:55 - 25:57
  then close the parenthesis
  - 25:57 - 26:00
  and divide all of that by the ExplosionRadius.
  - 26:02 - 26:04
  So when you think about that
  - 26:05 - 26:08
  if the explosion distance is very long,
  - 26:08 - 26:10
  IE it's close to the explosion radius
  - 26:12 - 26:15
  then the explosion radius minus something that's
  - 26:15 - 26:17
  very close to the explosion radius is going to be
  - 26:17 - 26:20
  very very small, divided by the explosion radius is going
  - 26:20 - 26:22
  to be very very small so it'll be near zero.
  - 26:24 - 26:27
  However, if the explosion distance is very small
  - 26:27 - 26:29
  then the explosion radius minus
  - 26:29 - 26:31
  something very small, let's say zero
  - 26:31 - 26:33
  divided by the explosion radius is going to be 1.
  - 26:35 - 26:37
  So we're going to end up with a number which
  - 26:37 - 26:39
  starts off at 1 near the centre and
  - 26:39 - 26:41
  trails down to 0 at the edge.
  - 26:42 - 26:44
  And that's how we're going to calculate how
  - 26:44 - 26:45
  much damage is done.
  - 26:45 - 26:47
  So we create a float called damage.
  - 26:47 - 26:50
  And that's equal to the relative distance
  - 26:50 - 26:53
  multiplied by the MaxDamage
  - 26:53 - 26:55
  m_MaxDamage.
  - 26:59 - 27:02
  So when the relative distance is 1
  - 27:02 - 27:04
  and is very close to the centre,
  - 27:04 - 27:06
  then you're going to deal the maximum damage.
  - 27:06 - 27:08
  When it's close to the edge, it's close to 0 you're going
  - 27:08 - 27:09
  to do very little damage.
  - 27:10 - 27:14
  Okay, so as illustrated in the slide
  - 27:14 - 27:16
  we have our overlap sphere,
  - 27:16 - 27:18
  we have our tank right at the very edge of it,
  - 27:18 - 27:20
  very minimal or maybe 0 damage,
  - 27:20 - 27:23
  and then something right in the middle of that impact
  - 27:23 - 27:25
  such damage, many ow.
  - 27:25 - 27:28
  We're not finished yet with this function.
  - 27:28 - 27:30
  What we need to do next is make sure
  - 27:30 - 27:33
  that the damage is not negative.
  - 27:33 - 27:35
  So we're going to do that by saying damage is
  - 27:35 - 27:44
  equal to Mathf.max of 0f and Damage.
  - 27:45 - 27:47
  So what that's doing is saying if it's negative
  - 27:47 - 27:50
  then set it to 0, otherwise keep it as it is.
  - 27:51 - 27:53
  And then finally we can return that damage.
  - 27:55 - 27:57
  Why is it that we're
  - 27:57 - 27:59
  making sure it's not negative?
  - 27:59 - 28:01
  Well there is literally an edge
  - 28:01 - 28:03
  case in this scenario.
  - 28:08 - 28:11
  In the case that the tank is
  - 28:11 - 28:13
  right on the very edge it's position
  - 28:13 - 28:15
  is actually outside of
  - 28:15 - 28:18
  the overlap sphere but it's collider is within it.
  - 28:18 - 28:21
  So it's going to get picked up by that collider's array
  - 28:21 - 28:24
  and then it's going to be calculated in with everything else
  - 28:24 - 28:26
  but we've only caught the edge of it, so,
  - 28:27 - 28:29
  we're actually going to calculate a relative distance
  - 28:29 - 28:33
  that's negative, because you're starting off at 1 in the centre
  - 28:33 - 28:35
  going down to 0 at the outside
  - 28:35 - 28:37
  and then it'll be negative beyond that.
  - 28:37 - 28:39
  So we don't want negative damage,
  - 28:39 - 28:40
  we don't want to shoot things and make them more healthy,
  - 28:40 - 28:42
  it's just not the way.
  - 28:43 - 28:45
  So that's why we're doing that.
  - 28:45 - 28:47
  Shall we put the script back on and
  - 28:47 - 28:49
  finish it off?
  - 28:52 - 28:54
  Okay, so if you've saved your script switch
  - 28:54 - 28:57
  back to the editor, hopefully there won't be any errors.
  - 28:59 - 29:01
  And then we need to of course populate
  - 29:01 - 29:03
  our script with all those public variables.
  - 29:04 - 29:06
  So interestingly something you won't have seen before,
  - 29:08 - 29:10
  is the first public variable, it's this
  - 29:10 - 29:12
  Tank Mask, so remember it's of type
  - 29:12 - 29:14
  layer mask and we called it Tank Mask.
  - 29:14 - 29:16
  And what that basically gives you is a repeat of
  - 29:16 - 29:18
  all of Unity's layer system.
  - 29:19 - 29:21
  So you'll notice it's the same list that you get in the
  - 29:21 - 29:23
  Layer drop down at the top.
  - 29:23 - 29:25
  This Tank Mask
  - 29:25 - 29:27
  is where we're going to select Players.
  - 29:28 - 29:30
  It's the only thing we want it to actually effect.
  - 29:30 - 29:32
  so select the Players layer from the
  - 29:32 - 29:35
  Tank Mask variable or drop down.
  - 29:37 - 29:41
  Then Explosion Particles is the child object
  - 29:41 - 29:43
  that's underneath the shell.
  - 29:44 - 29:47
  So you can drag a shell explosion on to
  - 29:47 - 29:49
  Explosion Particles, you'll notice in the
  - 29:49 - 29:51
  parenthesis it says Particle Systems.
  - 29:52 - 29:54
  And for Explosion Audio it's the same
  - 29:54 - 29:57
  object because that also has an audio source.
  - 29:57 - 30:00
  But this time when you drag it you'll notice it picks that component.
  - 30:01 - 30:03
  So Unity is smart that way, it knows which component
  - 30:03 - 30:05
  you're referring to if you drag an object that's got that
  - 30:05 - 30:08
  component it'll say 'great, okay, that must be what you mean'.
  - 30:08 - 30:10
  And assign that particular component
  - 30:10 - 30:12
  from the game object that you drag in.
  - 30:12 - 30:14
  Then the other stuff that we've setup there,
  - 30:15 - 30:17
  you know, it's setup based on
  - 30:17 - 30:19
  something that we wanted to make, if we get to the
  - 30:19 - 30:21
  end of the day and you want to have a huge
  - 30:21 - 30:23
  amount of damage, you want to have one shot kills
  - 30:23 - 30:25
  and you just up the maximum damage
  - 30:25 - 30:27
  or add the explosion force and the tank
  - 30:27 - 30:29
  just gets flung all the way off the screen.
  - 30:29 - 30:31
  You can do that stuff.
  - 30:31 - 30:33
  Obviously up the explosion radius as well.
  - 30:34 - 30:35
  You can play around with that.
  - 30:35 - 30:37
  For now let's stick with these values
  - 30:37 - 30:39
  and see how we like that.
  - 30:39 - 30:41
  And then the last thing we're going to do is to save the
  - 30:41 - 30:43
  shell as a prefab, as I said before we don't want
  - 30:43 - 30:46
  it to be in the game when it begins.
  - 30:46 - 30:48
  So I'm going to select my Prefabs folder.
  - 30:48 - 30:50
  I'm going to drag my shell and drop it in to
  - 30:50 - 30:52
  the empty space in that folder.
  - 30:54 - 30:56
  So really we should check if this works, so I'm just going
  - 30:56 - 30:58
  to briefly save my scene and demonstrate
  - 30:58 - 31:00
  what you should be seeing.
  - 31:00 - 31:02
  So if I press Play right now
  - 31:04 - 31:06
  my shell should fall down
  - 31:06 - 31:08
  and because it's pretty near the tank
  - 31:08 - 31:10
  take off quite a lot of damage.
  - 31:10 - 31:13
  Take off a lot of health, sorry, apply a lot of damage.
  - 31:14 - 31:16
  We've applied the shell explosion,
  - 31:16 - 31:19
  in order to populate the particle effect
  - 31:19 - 31:22
  and the audio source on to those two different variables.
  - 31:22 - 31:24
  And then we've made it in to a prefab
  - 31:24 - 31:26
  so now, as mentioned before,
  - 31:26 - 31:28
  we don't need that shell in the game.
  - 31:28 - 31:30
  Delete it out of your scene.
  - 31:30 - 31:33
  Delete on PC, command-backspace on Mac
  - 31:33 - 31:35
  and then save your scene.
  - 31:35 - 31:37
  One more time, select the shell.
  - 31:38 - 31:40
  delete it and then save your scene.
  - 31:40 - 31:42
  Okay, so that's the end of phase 5.
  - 31:44 - 31:46
  Then the next phase we're going to deal with
  - 31:46 - 31:48
  actually shooting these projectiles.
  - 31:48 - 31:50
  A little bit of physics and a bit more UI.
  ShellExplosion
  Code snippet
  using UnityEngine; public class ShellExplosion : MonoBehaviour { public LayerMask m_TankMask; // Used to filter what the explosion affects, this should be set to "Players". public ParticleSystem m_ExplosionParticles; // Reference to the particles that will play on explosion. public AudioSource m_ExplosionAudio; // Reference to the audio that will play on explosion. public float m_MaxDamage = 100f; // The amount of damage done if the explosion is centred on a tank. public float m_ExplosionForce = 1000f; // The amount of force added to a tank at the centre of the explosion. public float m_MaxLifeTime = 2f; // The time in seconds before the shell is removed. public float m_ExplosionRadius = 5f; // The maximum distance away from the explosion tanks can be and are still affected. private void Start () { // If it isn't destroyed by then, destroy the shell after it's lifetime. Destroy (gameObject, m_MaxLifeTime); } private void OnTriggerEnter (Collider other) { // Collect all the colliders in a sphere from the shell's current position to a radius of the explosion radius. Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask); // Go through all the colliders... for (int i = 0; i < colliders.Length; i++) { // ... and find their rigidbody. Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody> (); // If they don't have a rigidbody, go on to the next collider. if (!targetRigidbody) continue; // Add an explosion force. targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius); // Find the TankHealth script associated with the rigidbody. TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> (); // If there is no TankHealth script attached to the gameobject, go on to the next collider. if (!targetHealth) continue; // Calculate the amount of damage the target should take based on it's distance from the shell. float damage = CalculateDamage (targetRigidbody.position); // Deal this damage to the tank. targetHealth.TakeDamage (damage); } // Unparent the particles from the shell. m_ExplosionParticles.transform.parent = null; // Play the particle system. m_ExplosionParticles.Play(); // Play the explosion sound effect. m_ExplosionAudio.Play(); // Once the particles have finished, destroy the gameobject they are on. Destroy (m_ExplosionParticles.gameObject, m_ExplosionParticles.duration); // Destroy the shell. Destroy (gameObject); } private float CalculateDamage (Vector3 targetPosition) { // Create a vector from the shell to the target. Vector3 explosionToTarget = targetPosition - transform.position; // Calculate the distance from the shell to the target. float explosionDistance = explosionToTarget.magnitude; // Calculate the proportion of the maximum distance (the explosionRadius) the target is away. float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius; // Calculate damage as this proportion of the maximum possible damage. float damage = relativeDistance * m_MaxDamage; // Make sure that the minimum damage is always 0. damage = Mathf.Max (0f, damage); return damage; } }
  Связанные обучающие материалы
  - Adding Physics Forces (Урок)
  - Rigidbodies (Урок)