-
Phase 4.
-
So what we're going to do is use a
-
slider component, and it looks like this.
-
The slider component is going to have
-
a totally different appearance to what you
-
normally expect from a slider.
-
We're basically repurposing that
-
to create the same interaction.
-
And we're going to use the background
-
and the foreground elements, which are called fills
-
to create the same effect.
-
What you don't see in this footage is that we're
-
also going to use a script to change the
-
color of that radial health wheel over time.
-
So it's going to change from nice green healthy
-
to orange, to red as you loose health.
-
And you'll see that as we go through.
-
Okay, so first a couple of things.
-
We're going to setup Unity to work how we want.
-
Just make sure up at the top
-
that we're set to Pivot,
-
in our axis handles.
-
What you'll see if you don't do that is
-
the handles just won't appear exactly as we're doing them.
-
So pivot and local is what you should see
-
up at the top of the interface.
-
We're going to start creating this now
-
so I'm going to create a new slider.
-
So a slider
-
currently looks totally different to what
-
we're trying to create.
-
So go to Create button on the hierarchy,
-
then UI section and choose Slider.
-
Then because this new UI system
-
has a whole bunch of different stuff to it I'm just going to
-
cover some basics to begin with.
-
So whenever you have a new UI
-
element it has to be a member
-
of a particular canvas.
-
So a canvas could be something that's filling the whole
-
screen, what we call a screen space canvas.
-
Or it could be something that's an element within
-
the 3D world or 2D world which we call
-
a world space canvas.
-
So the default is screen space,
-
so what you notice is that when you've added
-
this brand new canvas you've
-
got this giant looking rectangle,
-
so what is that?
-
That is a screen space canvas,
-
that's the default for
-
any brand new UI canvas.
-
Because it assumes that if you're making
-
a UI you probably want to put in stuff that's
-
made in screen space like a score or
-
maybe health at the bottom,
-
maybe some kind of status text
-
that's rendered over the entire screen.
-
We don't want to do that in this instance,
-
we're going to do one of those later on.
-
But for this we just want to make it world space.
-
Now the reason it looks huge compared to this
-
is that actually the amount of pixels
-
compared to the amount of units
-
is far far greater,
-
so those numbers just match up
-
so it looks a lot bigger than the actual
-
elements on the ground.
-
We're going to turn that in to a world space canvas
-
and then effectively redesign it.
-
And then the thing that we've actually added
-
is the health slider
-
and it looks like this by default.
-
So it doesn't make any sense to use something like
-
this to represent health.
-
You could have just a health bar and it just gets smaller,
-
we certainly don't need the handle because nobody's going
-
to be dragging the health.
-
We don't want the player to give them self more
-
health during the game.
-
It would be cool but it's not very fair.
-
We're going to totally change how this behaves.
-
And the first thing that we're going to do to achieve that
-
is to tweak the event system.
-
Any new UI setup is made up of a canvas,
-
which is where something is rendered,
-
and then the event system handles any
-
input in to that, that you might need.
-
Now we want this game to be extendable
-
so that if you're working on
-
it and you want to add certain features then
-
you might want to have something that's clickable on the screen.
-
So we're going to leave the event system in there
-
so we're not going to have intractable UI element
-
but we do want the event system to stay in the game.
-
But what the event system does is it handles input
-
for you clicking on or using
-
a joypad to select stuff.
-
And what it does is it gives you
-
horizontal and vertical axis.
-
and they're the same as inputs in the input manager.
-
But we don't want to use those because we don't
-
want them to conflict with our actual controls of the game.
-
But all I'm going to get you guys to do is type
-
in to these UI on the end.
-
So that if you ever want to extend the game
-
in standalone input you will have
-
horizontal UI, vertical UI inputs
-
to map to controls.
-
Not important for the kind of behaviour
-
that we're going to create,
-
but that's all we need to do just to set that up.
-
So horizontal axis just put UI on the end of both of those.
-
Same for vertical.
-
Then the last thing to setup how the canvas behaves
-
is to set the scaling
-
and to set the actual rendering modes.
-
The first thing to look at is this
-
component called Canvas Scaler.
-
So a canvas scaler is there to help you
-
develop for multiple resolutions.
-
So you have a reference size, so UI Scale Mode,
-
and you can use a whole bunch of different scales there.
-
And then you have Reference Pixels Per Unit.
-
So we're going to scale this down from
-
something that's screen space, so absolutely massive
-
compared to the actual world,
-
way, way, way smaller.
-
So we have to turn this Reference Pixels Per Unit
-
down to 1 instead of 100.
-
That will allow us to have
-
sizes that are sensible, instead of typing
-
0.001 scales.
-
So we set those reference pixels all the way down to 1.
-
And then finally to make it exist in
-
the world instead of on the screen
-
in the canvas component itself we set the
-
render mode to World Space.
-
So not Screen Space Overlay or Camera
-
World Space.
-
And what you'll see then is the rect transforms,
-
so all the positions and the scales
-
and where it's rendered,
-
they stop being greyed out, you can edit those.
-
fields and that's exactly what we want.
-
So I'm just going to recap a couple of steps there.
-
So with our event system
-
we've had to rename a couple of axis
-
so they don't conflict with out input manager.
-
We've set horizontal and vertical
-
to HorizontalUI and VerticalUI
-
on the Canvas Scaler.
-
We've set reference pixels per unit to 1
-
so that the values will make sense once we've
-
scaled it all the way down to the size of the tank.
-
And then on the canvas component of the canvas game object
-
we've set that render mode to World Space so that
-
it can be just a small plane in the world that
-
we can mess around with.
-
Now that we've changed that stuff nothing looks different.
-
Okay, so that's fine, that makes sense.
-
We haven't actually changed the size
-
and the positions and the width and height.
-
What you'll notice now is the width and height
-
can be changed and I can scale those
-
and make them different, but we're not going to do that.
-
For those of you that are unfamiliar,
-
this is a rect transform component that
-
replaces the transform component on
-
all UI element and all it's
-
doing is just giving you a few extra properties
-
that you'l use to manipulate your
-
UI elements, for example, having a pivot position
-
which can be useful.
-
And the anchors, and we'll come on to the anchors in a bit.
-
So whenever you see UI elements they'll just
-
have a rect transform, a rectangular transform
-
instead of a normal transform.
-
Like James says, they basically inherit
-
from that behind the scenes so they've got a lot
-
of the same properties.
-
So we want this to be the health wheel,
-
sat underneath the tank as you saw in the video at the
-
start of this phase.
-
So we're literally going to drag this
-
canvas and make it a child of
-
the tank so in the hierarchy just
-
grab Canvas, drop it on to the tank.
-
We want that canvas to drive around with the tank.
-
So currently it's a giant huge rectangle
-
in the sky that if we move the
-
tank around it's going to move around with it.
-
So it's kind of strange, we don't want that.
-
So I'm going to change the position
-
to (0, 0.1, 0).
-
So that's basically centred that, so if I
-
scroll around the world now you can see the centre of that
-
UI is now right in the middle of where the tank is.
-
This would be an easier way to see it.
-
That's it's axis handle, right at 0.
-
And then we want the width and hight, instead of this giant
-
900 by 400something we want it to be much smaller
-
so we just change the width and hight to be 3.5.
-
Scaled it all the way down.
-
So all I've done there is just select the canvas
-
I've hovered of the scene view, I've pressed F
-
to frame select it, so I was all the way out
-
because it was showing me it.
-
Now it's smaller I can hover,
-
press F to zoom in.
-
So we're nearly there, it's currently rotated the wrong way though
-
so we don't really want that.
-
So we're going to change the rotation,
-
so rotation is the second to last property there,
-
to (90, 0, 0)
-
90 in the X axis only.
-
And then once you've done that it should be
-
flat on the floor.
-
Now for those of you who haven't used the UI system before
-
there are a bunch of tools up at the
-
top left of Unity.
-
The fifth one, T on the keyboard is the shortcut,
-
is the UI tool.
-
That will give you these sort of desktop publishing
-
style dots around the
-
corners of that rectangle.
-
Okay, so just a recap of those values.
-
We've dragged the canvas on to the tank
-
so it's going to move around with the tank, follow it around,
-
by being a child.
-
We've selected the canvas
-
and then we set the position to (0, 0.1, 0)
-
and the rotation to (90, 0, 0).
-
So this little square is going to move around
-
with it so I'm just going to show you that.
-
Now as we move this around you can see that
-
is a child object and is going to move around with our tank.
-
This tool is something that I'm using just to
-
show you more easily where these bounds are.
-
You can use it for scanning, we'll do that in a bit
-
when we make the aiming slider later in the day.
-
For now we've just setup our canvas
-
and we've setup our slider and we're just going to
-
save our scene to update it.
-
So the next thing that we're going to do is
-
to expand all of these objects and setup our
-
slider like we want because currently
-
the slider is not where we want it to be.
-
It's off somewhere else still
-
looking like that.
-
So that's great, and you know,
-
you can drive around and move it around,
-
but it's a bit weird, so we don't want that.
-
So instead we're just going to bring this in
-
to the same position.
-
You can see the slider itself is miles away from it's parent
-
it's (-122, -237, 0).
-
We don't want any of that so we're just going to
-
expand the canvas, the slider and everything.
-
There's a short way to do that, so if you
-
hold down alt on the keyboard
-
and you click on the arrow next to the canvas
-
you can show and hide
-
all of the child objects at once,
-
so alt - click that to expand all
-
and then once you've expanded all of it
-
we need to do some housekeeping.
-
So the first thing to do
-
is to get rid of the intractability that we've got
-
with this slider, we don't want people to be able to drag
-
as I said, that would be totally unfair.
-
So we're going to get rid of the Handle Slide Area.
-
So I'm going to select Handle Slide Area and
-
command backspace to delete it.
-
Or delete on PC.
-
A quick note, Handle Slide Area doesn't actually
-
make it intractable.
-
It's just the bit that you would grab
-
if it were intractable.
-
To make it non-intractable we'll have to deal with something else in a bit.
-
So with that deleted we're then
-
going to multi-select the Slider
-
the Background, Fill Area and the Fill.
-
So you can select the Slider,
-
hold down shift, click on the Fill
-
to select all of those game objects.
-
This bit is crucial, make sure you've got all of those
-
four selected.
-
So the the first one, shift, click on the last one.
-
The reason that we're selecting all of these at once is
-
we want to give them a certain anchoring,
-
a certain position that's all the same.
-
We basically want to lock them in to
-
where the canvas is.
-
So we know that canvas is nicely scaled at
-
3.5 square and it's following the tank around.
-
So we're going to tell these to do the same thing.
-
So in the Rect Transform we have this thing
-
called Anchor Presets.
-
And it's this little button here that you might not realise is
-
the button the first time, but if you click on it
-
you'll see this expanded panel of different
-
options for how you can layout your UI.
-
And what you also need to remember is that
-
any Rect Transform, the same as any canvas,
-
inherits a position and anchors
-
based on it's parent.
-
So if I tell all of these 4
-
items to stretch over their parent
-
they will be stretched over that 3.5 unit canvas.
-
So that's exactly what I'm going to do.
-
Another thing you'll notice here is it says
-
Shift: Also sets pivot.
-
Alt: Also sets position.
-
So that's exactly what we want, the latter there.
-
Alt setting position.
-
We want to stretch and also reset
-
the position at the same time for these things.
-
So I'm going to hold down alt and you'll notice
-
that when I tap alt now all of these options are changing.
-
So with alt held down the lower
-
right option is the one you want.
-
Stretch in both directions.
-
So if you click on that.
-
And then go back.
-
You should see that you now have a grey square.
-
So that grey is just the default image that
-
gets put on to a slider but now it's been
-
stretched out of proportion from what it expects to be.
-
We don't need to worry about that because we're just going to
-
go ahead and put on our health wheel graphic that
-
we made earlier.
-
A quick recap.
-
We expanded the canvas with alt.
-
Left clicking it's arrow expands all child objects.
-
And then with the Handle Slide Area
-
we've gotten rid of that because we don't want
-
to be dragging anything.
-
And then we've multi-selected all of the
-
parts except for the canvas
-
and we alt - clicked on the lower right
-
to get that view.
-
Cool, so like James said, this doesn't
-
make the slider not intractable, we need to
-
do that on the actual slider component.
-
And if you select the slider you'll see that slider
-
component has got this little
-
slider icon and we can get rid of that by just
-
unchecking Intractable.
-
Because basically what will happen is that
-
even though you get rid of the handle
-
that's just a focal point, you can get rid of
-
a handle on a slider and you can still have the
-
mouse drag it, so if you don't want a visual handle
-
you can still have it, but if you don't want it to be intractable
-
at all, uncheck that box.
-
Then because the transition
-
is a property is going to handle what happens
-
as you drag it we don't want that either.
-
So we're going to set that to None instead of Tint.
-
And that will get rid of a whole bunch of other options
-
we don't need, it's going to hide them.
-
And then this is going to be to demonstrate our health.
-
Now in code and in general terms
-
we think of our health of going from 100
-
down to 0, right?
-
So we're going to set our minimum value to 0
-
and our max value to 100.
-
And then the default value that we want,
-
so this slider at the bottom here,
-
we're going to drag that up to 100.
-
We want it to start with 100 health.
-
So you'll see that currently it's doing this.
-
So as I drag it you can see the slider's still working.
-
And I've dragged that all the way to 100.
-
So a quick recap.
-
Selected the slider and in the slider component
-
we don't want it to be intractable,
-
we don't want any animation during interaction
-
because there is none, so we set Transition to None.
-
And the Max Value and the Value slider
-
are both set to 100.
-
So this slider is going to be one of
-
2 sliders that are attached to the tank
-
so the first one is for the health wheel and then the other
-
one is going to be this arrow that fires out
-
when you hold down the fire button.
-
They're both using the slider component.
-
So we want to know what we're working with here,
-
we want to make sure things are nice and neat.
-
I'm going to select my slider, hit return on mac, F2 on pc,
-
and rename it HealthSlider.
-
As I said before, we don't want these default grey
-
graphics that are getting stretched over
-
our slider, that doesn't look good at all.
-
Instead what we're going to do is to change
-
the image component.
-
So the slider is made up of
-
that slider component itself, which handles the values.
-
And then the image components on a couple of child objects
-
which handle a background and a foreground.
-
So usually that's a background kind of
-
tube that's being filled up as you drag your slider around.
-
But in this instance it's just going to be a background
-
grey radial and then
-
a coloured radial sat on top of that
-
so that you've got some context of
-
where it's filling in.
-
If you select the Background game object you will
-
see one of those image components
-
and currently it's got this default background source image.
-
We're just going to click the circle select there
-
and instead, in the assets you'll
-
see there's something called HealthWheel.
-
That's a sprite that we've made earlier in Photoshop
-
but it's just a circle with a gap in the middle of it.
-
Once you've assigned that you won't see it
-
in the scene just yet, because remember the
-
foreground is on top of it, so it's obscuring it.
-
But we will see it in the preview at the
-
bottom of the inspector.
-
So you can be sure you've done it if it says HealthWheel
-
here in Source Image and it's at the bottom.
-
Then the last things that we need to do is to
-
change the alpha down a little bit.
-
So the colour defines, in addition to the
-
actual colour of the graphic that you put on
-
a kind of tint for this thing.
-
But it also defines what we call the alpha,
-
how transparent something is,
-
or how opaque it is.
-
What we want to do is to be able to see through
-
the background part of the health wheel
-
and see the desert, the sand underneath it,
-
you know, just a nice additional effect.
-
So I'm going to drag the alpha slider down.
-
So this line underneath the colour,
-
so the colour could be whatever you want it to be
-
it should be white, but generally speaking the line underneath
-
it defines whether it's semi transparent.
-
So if you set the alpha to a value of 80, 80.
-
You'll be able to see through that really nicely.
-
A quick recap, we've renamed it HealthSlider,
-
we've made the background image, the health wheel,
-
and we've made sure it's semi-transparent.
-
Hopefully straightforward?
-
Okay, so then we need to do a similar thing for the fills.
-
So the fill is your foreground.
-
An important point to note here is with the
-
canvas or with any part of the UI system
-
the order in which things are rendered
-
is from top to bottom.
-
From back to front.
-
So if you're used to Photoshop it's
-
basically the reverse of Photoshop.
-
So in Photoshop you have a layers panel.
-
Anything that's at the bottom of the list of layers is rendered
-
at the back and the top of the list of layers is on top.
-
Unity is the opposite of that
-
because it's using this nesting system
-
where child objects are rendered in front .
-
So our fill and our fill area are going to be
-
rendered on top, visually,
-
in front of the background.
-
So the fill is where you'll find the
-
next image component
-
and again we want to choose the Health Wheel.
-
So again I click next to Source Image
-
change it from Fill to Health Wheel,
-
which is one of our assets.
-
Choose that.
-
And then you'll see that we've got
-
a grey wheel, technically on top of another grey wheel,
-
right now because we don't have a script setting that up.
-
That's our two graphics setup,
-
we're not going to colour them here, the script is
-
going to handle the colouring, as I mentioned.
-
But we do need to control how
-
that image actually fills up
-
because what we want this to do is work kind of like
-
clockwise fill up radially around the side.
-
We don't want it to kind of wipe across the circle,
-
we want it to fill around, okay?
-
So instead of an image type which
-
is what we call Simple.
-
We're going to set this to Filled.
-
So on the image component on Fill
-
set it to Filled and it should
-
default to radial 360.
-
And then we need to change the Fill Origin to Left.
-
So Fill Origin will be just one point
-
around 90 degrees from which it starts emerging.
-
We chose left because it's visually
-
the bottom of the tank and it looked quite nice.
-
Again, it's not going to make a huge difference to the gameplay.
-
Finally we uncheck Clockwise.
-
We play tested it a few times and we felt
-
like anticlockwise made sense for when you're losing health.
-
But, you know, feel free to change that to taste.
-
Okay, the final thing that I've forgotten to do is
-
just to change the alpha on the Health Wheel.
-
We want to be able to see through this slightly
-
so I'm going to click on the colour block
-
on that image component and set
-
the alpha to 150.
-
Because if I leave this all the way full we won't see
-
a little bit of the desert through all of that, so,
-
both of these semi-transparent,
-
this one 150, the other one was,
-
a slightly lower value.
-
And as I said the script is going to handle the
-
colouring so it's going to go from green to red for us.
-
So a quick recap of those steps.
-
On the Fill game object we set the source image
-
to the Health Wheel, I tuned the alpha down a little bit
-
so you'll be able to see through it.
-
The image type is Filled so that you'll be able to
-
fill up radially, going round,
-
and we've made sure it starts at left,
-
which is just a particular position on that clock.
-
And then we unchecked Clockwise, so it's going to go
-
around backwards as you lose health.
-
Okay, so one final thing to make
-
sure that this behaves as we'd expect
-
it to as we're driving the tank around
-
is a brief script called UIDirectionControl.
-
So if you look in the Scripts
-
UI folder there's just one script
-
there called UIDirectionControl.
-
And we're going to grab this and
-
we're going to drag and drop this on to the HealthSlider.
-
So UIDirectionControl, grab the script,
-
drop it on to HealthSlider.
-
And when you reselect HealthSlider you should see
-
it's a component underneath the slider component.
-
And we're just going to show you that super quickly
-
what it looks like, it's just a couple of lines of code.
-
Don't worry about opening this one yourselves,
-
it's super quick.
-
In summary all this is doing is making sure
-
that the UI stays in
-
the same rotation that it was at the start.
-
So what it's doing is it finds the
-
rotation of the canvas,
-
so that's the transform.parent.localRotation
-
So finding the local rotation of the canvas.
-
And then using that every
-
update it's setting it's current rotation
-
to that local rotation.
-
So instead of moving around like
-
a normal child would and rotating,
-
it's just keeping the one that it
-
got at the start.
-
Yeah, we didn't notice this the first time we did it,
-
but basically that would look strange because
-
if you weren't losing health but you turned
-
around to where the tank is obscuring part of
-
the radial wheel it might look like
-
you were gaining health as you were driving
-
around and turning to see more of
-
the wheel so we realised that it would make total sense
-
to keep that rotation static
-
so this is just setting it every frame.
-
It's literally all that script does.
-
So make sure you've saved your scene, as always.
-
And because we've been working on our tank
-
what I want to point out to you is that
-
the tank and all of the parts that were with
-
it when we last updated the prefab are in blue.
-
These new child objects have their names in grey.
-
That again is reminding us, along with these emboldened parts
-
of the components that things aren't the same as the prefab.
-
So if I select my tank I'm going to hit
-
Apply at the top of the inspector
-
and now you'll see everything
-
is in blue and we've got no more bold parts
-
of any of our different components
-
in any of the game objects.
-
So our tank is now up to date.
-
We're getting close to a point where we can
-
use that tank as a prefab by
-
the game manager spawning more than one of them.
-
But we need to do some more things.
-
So we need our tank
-
to run out of health, we need to manage the health with a script
-
and we need the tank to explode and
-
make a sound when it's destroyed, right?
-
So we have a prefab
-
for the explosion part itself.
-
And then we're going to handle the actual behaviour manually.
-
In the Prefabs folder you'll find something
-
called TankExplosion.
-
We're just going to drag this in and
-
work with it very briefly.
-
So TankExplosion, if you drag and drop it in
-
to the hierarchy, you'll see is a particle effect.
-
And you'll notice that it plays back as soon as you
-
drop it in, it should look something like that.
-
And when we want to destroy the tank
-
we want to bring in this particle explosion,
-
move it to wherever the tank got destroyed,
-
play it back and play a sound.
-
So currently this particle system game object
-
doesn't have an audio source on it,
-
so that's what we're going to add first.
-
So once you've got your TankExplosion in your scene
-
click the Add Component button, and remember
-
'Sou' is a quick way to get to audio source.
-
Hit return and add the audio source
-
to the game object.
-
Then we need to tell it which clip to play,
-
so next to Audio Clip
-
click on the asset selection
-
so the circle select button there.
-
And we're going to choose TankExplosion.
-
Finally we don't want this to play
-
as soon as this gets put in the game because
-
basically what we do is to put
-
this asset in to the game and then
-
whenever a tank gets blown up just move it and play it.
-
But we don't want this to hear the
-
explosion sound as soon as the game starts
-
playing so we uncheck Play On Awake.
-
One more time, we've put the prefab in
-
for the explosion,
-
added an audio source and we've made sure
-
it doesn't play on awake.
-
Okay, so we just need to update that
-
prefab so I'm going to hit Apply at the top
-
of the inspector, you'll notice our text there
-
went from bold to unbold,
-
to regular I should say.
-
And that's all we need to do with that TankExplosion.
-
We just wanted to make you aware of what it was,
-
what it does and also add some functionality to it.
-
So now that we've updated the prefab,
-
so you can hit Apply as many times as you need to
-
we can then delete it out of the scene.
-
And then what we're going to do is handle the
-
health and we're going to reference this explosion
-
at that time as well, so,
-
in the Scripts Tank folder
-
you will find TankHealth.
-
And we're going to drag and drop TankHealth
-
on to our Tank game object.
-
And when you look at it in the inspector,
-
-
I'll just show you it more easily,
-
The last component I've got there now is TankHealth.
-
So TankMovement is above it, it's the last one we worked on.
-
And now we've got TankHealth.
-
I'm going to double click the title of the script
-
to open it up in my script editor
-
and we're going to talk about how this works
-
and add some functionality.
-
Okay, so first thing you'll notice
-
is like before, we've got some portion of the script commented out.
-
So on lines 13 and 36
-
there are these /* */
-
Get rid of those bits because we want to use that bit of code.
-
So we're going to enable those by deleting
-
lines 13 and 36.
-
So it should show up in syntax highlight colours.
-
Okay, let's have a quick look at the public variables.
-
The first one is the starting health.
-
I'm going to start with 100, it makes perfect sense.
-
Next we've got a reference to that
-
slider because we want to change the slider's
-
value so that it's less or more.
-
So remember the slider is controlling
-
the fill image and how much
-
that radially fills up.
-
So it's just handling the values.
-
The image itself handles the rendering side,
-
the slider handles the values.
-
Okay, and like we said, we wanted to change
-
the colour based on the health, so we need
-
to access that image, so again we've got
-
a public variable so we can drag on
-
the image component of the Fill game object.
-
Next we've got a couple of colours,
-
you can change these in the inspector
-
if you want, but we thought that green
-
for full health and red for 0 health made sense.
-
If you like purple and orange
-
go for those colours.
-
And the last one is a reference
-
to the prefab, so,
-
what we're going to do is we're going to drag on
-
the explosion prefab that we just edited
-
so that we can instantiate it at
-
runtime and use it then.
-
Next we've got our private variables and
-
we've got a reference to the audio source
-
that's on the explosion prefab.
-
So when we instantiate it
-
we'll have a reference to
-
that instance.
-
Then from that we can find a reference to
-
the audio and just below it
-
the particle system as well.
-
So the explosion audio and particle systems will just be
-
references to components on that
-
instantiated game object
-
that we can use when we need to.
-
So notice James is using the word Instantiate.
-
We haven't really mentioned that just yet,
-
it just means to spawn a game object in the world,
-
and you'll see that very shortly in the Awake function.
-
Okay, so next we've got a
-
float value for the current health,
-
obviously we need to keep track of how much health
-
we've currently got, so we have that.
-
And lastly we've got a
-
boolean variable for whether you are dead or not.
-
Okay, next we've got the
-
Awake function, and if you remember Awake is called
-
at the start of the game
-
so we want to do these things to setup
-
what's going on for the rest of the game.
-
This first line is a little bit tricky so I'll
-
go over it a couple of times to make sure.
-
What we're doing is we've got our explosion particles.
-
And we're setting that to the
-
particle system component of an instantiated prefab.
-
So we're instantiating the prefab,
-
so that's Instantiate(m_ExplosionPrefab)
-
and then from that we're using GetComponent
-
to get that particle system reference that we need.
-
So basically we have a particle system variable.
-
We create an instance of the prefab that we know
-
has got that component on it and then
-
we assign that component, so we're doing
-
a couple of things all in one line basically.
-
And then it's very similar for the audio source
-
that's also on that game object.
-
But since we've already instantiated
-
we don't want 2 explosions
-
we're just going to use the reference to the particle system
-
to get the audio source component.
-
And lastly, since we don't want the tank to
-
explode at the start we're just
-
turning that game object off,
-
so m_ExplosionParticles.gameObject.SetActive(false);
-
So that's going to make it inactive in the hierarchy.
-
Yeah, so just to reiterate, whenever you're using
-
particle systems in Unity it's kind of more
-
efficient to put them in
-
the game than play them whenever you need them.
-
Stop them, play them, stop them, play them.
-
What a lot of people do, which is a beginner thing,
-
is to instantiate, so spawn a new particle system
-
and then use what's called Destroy to
-
move that game object from the hierarchy.
-
The problem with that is it can invoke
-
the garbage collector, which is a thing that is
-
basically registering what's going on in the scene
-
and removing references.
-
You don't want that because that will create spikes in performance
-
and make your game less performant basically.
-
So to avoid that always keep your particle
-
systems in memory, keep them in the scene,
-
play them when you need to, stop them when you need to,
-
and that's exactly what we're doing with the explosion.
-
We put it straight in to the game as soon as it starts
-
we switch it off straight away so you never
-
see it and then we assign our references
-
for when we need them.
-
That is definitely the most efficient way,
-
it's not always the simplest because
-
for example with the shells later on
-
we don't know how many we need, we're going to have to spawn
-
them as the player uses them.
-
There's a way round that using something called Object Pooling
-
which we've not included today, if you want to
-
understand object pooling come and see me at lunch or
-
after today and I'll explain it to you.
-
We do have some tutorials that cover
-
object pooling, I think Mike and Matt have done
-
those at various points, so there's live trainings
-
on object pooling as well, which you can find
-
on Unity3D.com/learn.
-
But that would be another way to keep
-
a whole bunch of objects and it's a more performant way to
-
keep them in and then spawn them whenever you need them.
-
We digress.
-
Okay, so you remember we're turning
-
tanks on and off when
-
we kill them and bring them back to life again?
-
So again we're going to be using
-
OnEnable to do stuff when the tank
-
first gets turned back on again.
-
So when the tank gets turned back on
-
we want to reset it's health to the StartingHealth.
-
We know that it's not dead so we set the
-
Dead boolean to false.
-
And we need to update it's UI
-
to make sure that it looks healthy as well.
-
So SetHealthUI is basically just
-
going to the component and setting it to whatever value
-
we tell it to, it's basically just a kind of
-
refresh that we do on the OnEnable.
-
We'll be setting up that function shortly
-
but first off let's go through the
-
TakeDamage function.
-
Note that that's a public function so that it can be
-
called from outside this script because
-
we want the shells to do the damage.
-
And it's also parsed in an amount
-
so that's the amount of damage that it is going to take.
-
So the first thing that we want to do with
-
TakeDamage is to reduce the current health
-
by the amount.
-
So m_CurrentHealth -= so that's setting CurrentHealth
-
by reducing it by amount.
-
So just a quick note for those of you not confident coders.
-
The argument that we're placing in is
-
what we're referring to here,
-
so TakeDamage in the parenthesis here,
-
float amount means that you can call this function
-
and then parse in whatever number you want there.
-
So the reason we've got that is TakeDamage
-
can be a number of different things.
-
Depending on where the shell hits near to the tank
-
will define how much we want to subtract.
-
If it's super close it's going to create a lot of blast damage.
-
If it's just on the cusp of how big that
-
blast radius is then quite a small amount.
-
So it's going to be a varying amount of damage we're taking away.
-
So we can parse in an argument called Amount
-
and then we subtract that from the CurrentHealth.
-
Okay so again we've just changed
-
how much health we currently have
-
so it would be good to update the UI
-
to reflect that, so again we'll call that
-
SetHealthUI function that we'll setup.
-
So remember that this is reducing our CurrentHealth,
-
but unless we tell the user by updating
-
or refreshing the UI
-
they're not going to know.
-
And the last thing that we need to do
-
in TakeDamage is check whether or not we're dead.
-
So if m_CurrentHealth
-
is less than or equal to 0f, because remember,
-
float, it's what we're checking it against,
-
and we're not already dead, so not Dead.
-
Then we can call the function OnDeath.
-
So just to remind you.
-
Less than or equal to 0
-
so we're run out of health.
-
& means add a second condition for the if statement.
-
And the ! there is just means not.
-
So if this thing isn't true and we're not already
-
then we'll call OnDeath.
-
Okay so the next function is the
-
SetHealthUI that we've talked about.
-
The two things that we want to do in this
-
was we want to set the value of the slider
-
and we want to set the colour of the slider.
-
To set the value of the slider
-
we say m_sSlider.value = m_CurrentHealth
-
So remember our slider goes from 0 to 100
-
as does our health.
-
So all we're doing is we're setting the value
-
of the slider based on the current health.
-
And the next thing, if you remember,
-
a slider is rendered by those image components
-
so that's what we need to address
-
in order to change it's colour.
-
So we say m_FillImage.color =
-
and what we're doing to do here is use a Lerp function.
-
So Lerp stands for Linear Interpolation, so we give it
-
2 values that we're interpolating between,
-
that we're making a blend of,
-
and we'll give it a third value that determines
-
how much of each colour we're using.
-
The function is Color.Lerp
-
and we open parenthesis and we give it the value
-
of a color that we want to
-
show when we are at 0.
-
So remember that we have that public variable
-
called ZeroHealthColor that's red.
-
The next is the color that we want to use
-
when our third variable is 1.
-
So 1 not 100.
-
So we need a value that is between
-
0 and 1 that reflects
-
what percentage of health we have.
-
So to do that, all we'll do is
-
we divide the current health by the starting health.
-
So if you've got full health, 100.
-
Then your starting health is 100.
-
100 divided by 100 is going to be 1.
-
If you've got 0 health, 0 divided by 100 is 0
-
so you're going to use the ZeroHealthColor.
-
Likewise, if you've got 50 health,
-
50 divided by 100, you've got half,
-
so it's going to be halfway between those two colors.
-
So that's basically what we're doing every time we
-
refresh the UI, we reset the slider and
-
the slider resets the image for us
-
and then we reset the color to make sure it looks appropriate.
-
Okay, so the last function that we're going to do
-
is OnDeath, so this is called
-
when the tank first dies
-
and since we have that Dead boolean
-
we're not going to call it more than once.
-
So the first thing to do here is make sure
-
that we're only going to call it once by setting Dead to true.
-
As soon as we call the function.
-
The next thing we want to do
-
is play all the effects
-
for the explosion.
-
So first off, the explosion particles need to be in
-
the correct place, so m_ExplosionParticles.transform.position
-
The position of the particles will set to
-
transform.position, that's the tank's position.
-
So wherever you were when you died,
-
grab the particles that we put in at the start of the game,
-
move them there and then.
-
And then once they've been moved to the correct
-
position we need to turn them back on,
-
because remember we turned them off at the start of the game.
-
So m_ExplosionParticles.gameObject.SetActive
-
true in parenthesis.
-
So that's turning the game object back on.
-
Once we've turned it back on then we can
-
actually play these variables,
-
so m_ExplosionParticles.Play
-
and m_ExplosionAudio
-
So that's playing the particles,
-
and playing the audio.
-
And the final thing that we want to do in this
-
is actually turn the tank off
-
so gameObject.SetActive (false)
-
So all that's doing is, we're saying
-
that we only want to call it once,
-
so Dead gets set to true.
-
We take the particle system and we move it to
-
the correct position and turn it on.
-
Then we play the particles,
-
we play the audio and we turn the tank off.
-
And that's all there is to it, so save your script
-
and return to the editor.
-
So just a quick reminder of what we've just done there.
-
We've setup our tank damage.
-
Whenever we get damage we have to update
-
the UI based on the current health
-
and we also have to deactivate,
-
when the tank dies and bring in the effects as well.
-
So once you've saved your script, go back to Unity
-
and also save your scene.
-
Just a quick reminder, if you've got errors
-
with the script they will be at the bottom of
-
the Unity interface where you've got a grey bar down
-
at the bottom here, they will also
-
be in Window - Console.
-
So we've finished our script, we've saved our script
-
and we're back inn Unity and that
-
script as a component
-
is TankHealth
-
and as you see we need to assign some references.
-
So I'm going to just alt-click on the arrow
-
next to my tank in the hierarchy to expand
-
all of it so I can definitely see all the things
-
that I might need to click on
-
and then I'm going to assign the Slider
-
called HealthSlider
-
to the Slider variable.
-
One more time, I'm grabbing
-
HealthSlider, it's underneath Canvas,
-
dropping it on to the slider variable
-
so that's that reference assigned,
-
and then Fill, the one at the very
-
bottom of all the list of game objects,
-
dropping that on to Fill Image.
-
So with the reference to Health Slider it's going to set the
-
value and show the health and update properly
-
and with the reference to Fill Image we're going to
-
use these two color blocks here
-
to define, you know,
-
what it looks like at 0 and 100% and
-
everything in between color-wise.
-
Finally, the Explosion prefab
-
is in the Prefabs folder.
-
We edited it earlier.
-
All we need to do is find TankExplosion
-
and drag it on as the explosion prefab
-
using this variable here.
-
One more time, drag TankExplosion
-
drop it on to the Explosion prefab.
-
If you then save your scene.
-
The last thing we need to do is just make sure
-
this tank is up to date prefab-wise.
-
You know it, we've done it before,
-
hit the Apply button at the top of the inspector.
-
Hit it as many times as you like just to be sure.
-
And then you can play your game.
-
Now you won't see anything changing
-
until we've got some shells that damage
-
the tank and we'll do that right after lunch.
-
But for now what you should be seeing is
-
that the tank is driving around and we've got our health wheel there.
-
Cool, so you should see your tank driving around
-
it should have the health wheel attached to it,
-
this will all make a lot more sense once you've got the shells coming in
-
which is in the next phase, so just to
-
recap that last part.
-
We've assigned the HealthSlider to the
-
HealthSlider variable.
-
We've got the Fill game object
-
and assigned it to the FillImage and then
-
we've got the TankExplosion variable from the Prefabs
-
in the project and put that on to that variable.
-
And then we've applied, we need to update our tank.
-
As we work on the tank we need to keep updating
-
it until it's finished and then we'll
-
get rid of it entirely and it will be stored in our project
-
to spawn at the start of the game.
-
So if you've done all of that save your scene,
-
pat yourself on the back, it's the end of phase 4.