Transcripts
1. Introduction: Unity's new input system can be overwhelming
for beginners. So here is a really
easy way how to implement it in just
a few lines of code. We will also play with physics and create some solid objects, and we will learn
how to draw trees, mushrooms, and plants
in the game world in front and behind the player in a way that makes
visual sense. Are you building a top down game with a four directional
animated character? Here are three tips, tricks and techniques you will need to make
your perfect game.
2. Project Setup: I create a new Unity project using Universal two
D Render Pipeline. This is Unity six, but you
can use any future version. It doesn't really matter. I start by creating a
folder, I call art. You can download all
project art assets in the resources section below. I made all of this, so
there is no license. Use it for your
projects if you want. I'll show you how you can easily tile your background in unity. I have an image I call
background tile PNG. It's a seamless tilable texture. It has some grass
and stones on it. I select the image, and
inside the inspector, I set Sprite mode to single. This image has only one frame. If you want to tie something, you should set mesh
type to full rectangle. If you don't do that, unit will complain and tell you
to go back and do this. I click Apply, I drag and
drop my tile into the scene. I reset its transform
to center it. I set draw mode to tiled, and here we are
dealing with units. Each square in this
grid is one unit. So I want the width of the tiled area to be
five times wider. Seven times eight times. You can do this and Unity will automatically calculate that
three times eight is 24. Height will be three
times five, probably 15. I go to game View tab and
I set aspect to full HD. My game will be 1920 times 1080. Back in scene view, the
area highlighted by this white rectangle is what
the game camera can see.
3. Sprites and Textures: I will drag and
drop another image just to make the game world
a bit more interesting. I called it background top, Sprite mode set to
single and apply. I drag and drop it into the game view and
I reset transform. If for you, this other image is behind the
grass, don't worry. It can happen, and we will
address it in a minute. Okay, so this is fine. I drag and drop a third file. If four directional, I will bear sprite sheet,
I rigged myself. It has idle and walk
animations in top, down, left and right directions. If I expand it, it's auto sliced already, but it's blurry. That's because it's a large
image, 6,200 pixels white. But here we are restricting
Mac size to 2048 pixels. So I select something more than 6,200 to allow the image to
expand to its full size. I click Apply, and now
the frames are sharp. I open Sprite Editor. Unity auto slice
this for me already, but I want to change two things. Slice will be grid
by cell size and each frame will be
200 times 200 pixels. And more importantly, I have to set pivot point to bottom. This will allow our character
to walk in front and behind other game objects in a way that makes visual sense. I'll explain this in more
detail when we get there. I click slice and apply. I expand my frames, and I pick any frame I want, and I drag and drop
it into the scene. Unity will automatically
create a game object for it, and it randomly
decides if it's behind or in front of the other
game objects in the scene. So I rename it to player. I go here and add sorting layer. I click Plus under
sorting layers, and we will have a layer called background all the
way in the back, and another layer I call
objects in front of it. Background tile game object, the grass will be on
background sorting layer, order in layer zero. Background top image will also be on the same background
sorting layer, but order in layer will be one. Player game object will be on objects sorting layer
on top of everything.
4. Player Movement Script: I create a folder
I call scripts. Inside, I right click Create script in mono
behavior script. I call it player controller. In this script, we will
write a few simple lines of code to move and to
animate the player. I select player
game object and I attach player controller script as a custom component like this. I can click it here or here to automatically open it in
my default code editor. Unity already auto generated basic syntax for a component. Mono behavior class
allows us to attach this script as a component on player game object,
which we just did. Let me show you the easiest
and quickest way to use Unity's new input system to make the player move
in four directions. I will delete things
that I don't need. We can move the player from
this script by changing its position X and position Y values on this
transform component, but that's only
suitable for objects that will not have any
physics interactions. I want the player
to collide with other game objects
and things like that. So the other way to make something move that
will work in sync with unities built
in physics system is to take the
player game object. At component, and I search for rigid body two D. Make sure
you use the two D version. I set gravity scale to zero because this
is a top down game. And here in constraints, I freeze Zt rotation
to make sure the player doesn't spin around when it collides
with something. So now I want to access this rigid body two
D component from my custom player controller
script component so that I can apply forces to the
player to move it around. Public variables I define here will automatically
appear as fields on the component here unless I set
them to private. If I want a variable to be
at the same time visible in Unity editor and private so that it's not accessible
from other scripts, I can give it a serialized
field attribute like this. Serialized field private
type is rigid body two D, which is a special type that unity engine name
space will understand, and I give it a custom name. For example, RB. Save that and back in unity, you will see this
new field called RB appeared on my
script component. You can see that the value it's looking for is rigid body, so I drag and drop this
rigid body component here, linking it to my script. Update method runs over and
over as often as it can, usually 60 frames per second. When we do anything to do with physics that we also want
to run over and over, we do it in a separate
method called fixed update. The rate at which fixed
update method runs is tied to the physics
engine updates. By default, that's 50 times per second unless you go to
settings and change that. So in fixed update, I
take my RB variable from line five that is linked to this rigid body
to the component. I access its linear velocity that expects value in
vector two format. Vector two is a simple data
type that has two components, one for X, and one for Y. Let's say I want to push
the player one unit per second to the right plus one
on the horizontal X axis. F means float,
floating point number, a number with the
decimal points, and zero vertically.
I save that. If I click here to enter
play mode in game view, you can see that it's working. Perfect. Now we just simply
connect input keys to this linear velocity
value and player will move based on the
inputs we are pressing.
5. Using the new Input System: Unit six comes with the new input system
already pre installed. You know, it's installed and ready to be used when you have this input actions file
in your assets folder. It's very simple to
use. Let me show you. The new input system comes
pre installed in the project, so we can access it from
anywhere like this. I create a new variable. Type is input action. For this to work,
we need to include input system name space up here. I will name it, for
example, player controls. I save in unity on player game object on its player controller
script component, I will have this new
player controls block. I can click Plus and let's do updown left right composite. We want it in a two
d vector format, and we get these
four new fields. I click up. And
inside this field, I can press the key itself, and Unity will give
us some options. Let's pick W Key on my keyboard as the key that
makes the player move up. I click down here. I choose a keyboard from these options. Left will be the A key, and player will move
to the right when we press DKey on the keyboard. Okay, so we set up Ws AD for up, down left and right controls. From this point, we can use
it in the same way we used the old Unity input system
if you are familiar with it. It's very simple. I
declare a variable. I will use serialized
field just so we can see these values in the inspector
so that we can check them. Type is vector two, which is a data type with X
and Y component. I call it, for example,
move direction. Update method will
run over and over, usually something like
60 frames per second. From here, we will
set move direction, which is a vector two type to player controls
from line seven, which is also set
to vector two here. Dot read value Vctor two. So now I can apply forces
to players rigid body to the component based on the
inputs that are being pressed. Move direction X here, and move direction Y here. As the game runs and
we press WS AD keys, we will be moving
the player around. We can also add another
variable float move speed, and we add it as a
multiplier here and here. So if I save back in Unity, I can see the horizontal and vertical component
of move direction. And here I can set move
speed to some value. I try four, for example, I play the game and
it doesn't work yet. I'm pressing WS AD keys, and these move direction
values are not changing. I exit play mode. It's because when using
Unity's new input system, we have to do one
extra small thing. We need to enable
it. Private, void, on Enable, we take player
controls and we call Enable. And while we're at it, I say
private void on disable. Player controls Disable. Save changes and play. And now when I press WS AD keys, I can see move direction values changing and player is
moving around the screen. So now let's make the
player switch between different animations based on these move direction values.
6. Setting Up Animations: I go to Window
Animation Animation. I usually like to dock it here. Notice that what we animate depends on which
object here we select. In assets, I right
click Create folder, and I call it Animations. So with player game
object selected, to begin animating
player, I click Create. I navigate to Animations folder and I create a new
dot anime file. I call it playerid Down. I go to Assets art, I expand my players pride sheet, and I select frame zero. I want the full idle
down animation sequence, so I go all the
way down to frame 30 and I hold Shift
key and I click it, selecting all the
frames in between. I created this spreadsheet, and it has a lot of frames. So if I'm not sure where the individual animations
start and end, I can always go up here, select the main spread
sheet, inspector tab, open Sprite editor, and this particular spry sheet
has one animation per row. So idle down is from
frame zero to frame 30. Walk down is frame
31 to frame 61. Then we have 62 to 92 and so on. Okay, so animation window player Idle down here. I
click frame zero. And I shift click frame 30. I drag all of them on
the animation timeline, and I click Play to
preview the animation. It's too fast, so I
reduce the samples. If you don't see samples here, click these three dots and
tick Show sample rate. I set it to 30. That's better. I click
here, create New clip. Inside the same
animations folder, I create playerwalkdwn
dot Nim and I save. With player walk
down selected here, I click frame 31 and I
shift click frame 61. I drop all of them
on the timeline. If they don't show, it's because I don't have
player selected here. So if I select it, we
can seal the frames. I create new clip,
player ID left. I click frame 62, and I shift click frame 92, selecting all frames in between. I drag all the frames
on the timeline again. I set samples 230. You can show and height
samples field by clicking these three dots
and show sample rate. Create New clip,
player walk left. Frame 93 to frame 123. I select the player
game object here. Okay, I play 30 samples. Good. To animate player
idle and walking right, I could go to Inspector
and flip X here. We can control ticking this
checkbox from our script. But since we have the frames, let's just follow
the same pattern we have been doing so far. So create new clip,
player idle right, frame 124, 254. 30 samples. Okay. Create New clip.
Player walk right. Save frame 155, 285. 30 samples. Alright.
Create new clip. Player idle up, frame
186 to 216. 30 samples. Create New clip. Player walk up. Frame 217 to frame
247, 30 samples. So we have eight animations now Idle and walk in all
four directions. In Assets animations, I can see all eight animation
files we created, and we also have this player controller file
that was created. If I click it, it opens
inside Animator Window. I can also open this by
going to Window Animation. All we have to understand
here is that animation window is where we set up timelines
for individual animations. Inside Animator window, we
have a simple state machine. Here, we set up how the
game object transitions between individual
animation states. The easiest technique
to do this is to create a kind of a
brain here that will decide automatically which
one of these animations will play based on which keys
we press on the keyboard. I will delete all these
states from here. We will implement them through something called a blend tree, which will make this
entire screen much cleaner and easier
to navigate in.
7. Blend Trees: All right click Create
State from New Blend Tree. Inspect a tab, and I
rename it to player Idle. This one blend tree will handle all four idle animations
at the same time. Idle left, right, up and down. I double click this, go
in one layer deeper. Here I can see we are
inside base layer and deeper inside
player idle state. Here, we have a blend tree, and I rename it to idle. In parameters, I
click Plus and float floating point number number that can have a decimal point. I call it move X.
I create one more. I call it move Y. With my Idle blend
tree selected, I click here and blend type will be to the
simple directional. Parameters will be
the move X and move Y. I click here and
add motion field. I will add three more. I'm inside assets animations, and here I drag player idle
left to this motion field. When move X parameter is
minus one and move Y is zero, we will animate
player idle left. I drag player idle right here, when X is positive
and Y is zero, Idle up here, horizontal X is zero and vertical
Y is positive. And finally, idle down when
X is zero and Y is negative. Now if I select Idle
blend tree here, I will get this
nice little preview of the player model down here. We have two parameters, move X and move Y. And based on the current value of these two
parameters combined, this little brain we created, the blend tree will decide what is the best animation
to play in that moment, based on the conditions
we defined here. Blend tree unity
is a special type of state in animation
state machine that allows us to automatically
transition between multiple animations based
on the rules we define. If you change the values
of Move X and move Y here, all these visuals on the screen should make it very
clear what is happening. Now, all we have to do is
to connect Move X and move Y to move direction X
and Y, and that's it. To do that, I go to
player Game Object here. And we need access to this animator component from our custom player controller
script component. We do it in the same way we
are accessing rigid body. First, I declare a
field type is animator. My custom variable
name for it is, for example, animator
with a lowercase A. Inside update method,
after every time we update move direction based on what
controls are being priced, we will also access
animator component. We call built in
set float method. And if you remember, we
created this move X and move Y float parameters that
determine which animation plays. It can be any value between
minus one and plus one. So I set float, we called move X to the X component
of move direction vector, which can also be values
between minus one and plus one. So it's all compatible. And we also set float move
Y to move direction Y. So as the game runs and
controls are being pressed, we set move direction
value accordingly, and we use that to play
the correct animation, and we also use that to move the player in
that direction. I save changes back in unity. Player game object selected, and I drag animator
component to this field, linking it to our custom script. Now, if I enter play mode, as I press WSAD keys
on my keyboard, the player moves and animates
in the correct direction. It animates only idle
animation so far. Notice that every
time I stop pressing keys and move direction
resets to 00, player will stop and
start facing left. I would prefer if
player stopped and faced the last direction
it was moving. I exit play mode. To do this is simple. We will only send values through to animator component if
there is a direction. If move direction is not 00, when we release all keys and
move direction becomes 00, we will not send that
through to the animator, so the player will stay facing in the last movement direction. Save that and play. And yes, that worked. Now we have to do the same
thing for walk in animations. I exit play mode, animated tab, and I go one layer up
to the base layer. Here, I can right click, create State from
new Blend Tree. I rename it to player walk. Here, we will do the
same thing we did for player idle blend
tree, basically. Double click to go
one layer deeper. Inside player walk, I rename
this blend tree to walk. We already have move X and
move Y parameters from before. So I set blend type to two
the simple directional, and parameters are going to be, again, move X and move Y. Plus, add motion
field four times. This time we will do this
for walk animations, starting with player walk left. We know it's minus 10. Walk right is plus 10. Walk up is zero plus one. Walk down is zero minus one. Player here and walk blend tree selected to
get this little preview, and I can change these
values and check if the player is turning
in the right directions. Yes, that means the rules
we set up here are correct. I go one layer up
to the base layer. To finalize this, we
need some logic to transition between
idle and walk states. In parameters, I click plus, and this time, it
will be a booling, which can be true or false. I will call it
moving. Right click player idle and make transition. I drag it to player walk state. Now I select that transition
arrow and I set it up. I antique has exit time. I expand settings and I set
transition duration to zero. Ignore this warning because
we will address it right now. Because here in
conditions we click Plus. We want to transition
from idle to walk if moving is
true like this. Now I right click player walk, make transition, and I
drag that to player idle. I can clear the console, but it doesn't actually
matter because when I select this other transition and
I antique has exit time, it will complain again until
we give it a condition. I set transition
duration to zero, and plus the
condition to transfer from walk to idle will
be when moving is false. So we have this new
parameter I called moving. When it's true, we transition
from idle to walk. When it's false, we transition
from walk back to idle. In my script, when move
direction is not zero, zero, we know that WS AD keys are
being pressed and we set move into true using built in set
pool method, set Boling. Else, meaning that move
direction is zero, zero, we set moving to false. Save that back in Unity, and I set move speed to two. We learned a quick and
easy way to move player in four directions using
Unity's new input system, and we also know how
to switch between four directional idle
and walk animations. I can end this class here, but let's give it
a bit more polish. This is a bonus
quickfire section.
8. Blocking Movement Sorting Sprites: You can download Shadow image in the resources section below. Sprite mode, single apply. I drag it into the
hierarchy, syn tap, sort in layer objects, or the in layer minus
one behind the player. I parent it under the player
and I reset its transform. I move it a bit up.
Now if we play, the shadow is moving
with the player. I drag and drop Obstacle
spreadsheet into my art folder. I open Sprite Editor. Auto slice is fine, but I need to change
pivot to bottom here. I did the same thing when I sliced the players
spreadsheet. It will become important
now. I click Slice. Now, all these frames
have pivot point at bottom center. I click Apply. Okay, let's pick one of them
and drop it into the scene. Sorting layer will be objects. The same layer we
put the player on. If I play, it's just flat. It doesn't do anything. Let's turn this into
a solid game object that the player can
actually collide with. I need this plant to
be in front and behind the player in a way that
makes visual sense. This is a top down game, so we achieve that
by sorting objects based on the vertical position
of their pivot point, which we placed to
bottom center on both player and this
obstacle plant. Player selected sprite
sort point set to pivot. Obstacle selected, sprite
sort point also set to pivot. Finally, I go to
assets settings, and I find renderer
two D. On it, I find transparency sort mode and I set it to custom axis. We will sort our game
objects based on their position on the
vertical Y axis. I play. If the plant is lower
than the player, it will be drawn in front of it. If the player is
lower than the plant, the player is drawn in front. You will need this technique
for so many different games. It's very useful. Okay, but now the plant doesn't have any
physics, no collisions. We can just walk through
it as if it wasn't there. I selected here at component, circle collider two D. I click this to edit
collider geometry. It will give me four
small handles I can use to resize this collider. Looking at this, there is
a better collider type. I click here and
remove component. Instead, I will search for
capsule collider two D. Direction will be horizontal. Edit collider geometry,
and I resize it. In a game like this, we want the collision area to be only
the part where the object touches the ground so that other objects with colliders
can actually move behind it. Something like this is good. Player selected at component, capsule colli two D. By default, it's vertical, but we
want it to be horizontal. I do something like this. Because of the
fact we are moving the player using its
rigid body velocity, unit is built in physics system
will work automatically. We don't actually need to write any extra code or
do anything else, and we already have
collisions in our game. I use the same shadow
for the plant. I parent it under
it, reset transform, certain layer objects,
or in layer minus one, and I move it a little bit up. I rename it to evil plant. We created and configured
a game object. But what if I want
to duplicate it many times without having to
configure each copy separately, I can go to assets and create
a folder I call prefabs. I can drag Evil plant here
and store it as a prefab, prefabricated and
preconfigured game object. Now I can use it all around my game and even in
different scenes. I can simply just drag out
multiple copies like this. And let's say I select one of the copies and I change
it a little bit. For example, I can flip its spread sheet
horizontally like this. I'm giving you many other
obstacles in this spreadsheet. You can go ahead and build a full game from
this if you want.
9. What's next: Well done on completing
the project, there is a playable demo
and source code linked below in case you want to
compare your code to mine. Check out some of my other Unity game development
classes if you want to take this further and apply what you learned
in a complete game.