All language subtitles for Learn Unity Beginner_Intermediate 2023 (FREE COMPLETE Course - Unity Tutorial) (1)

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

hello and welcome I'm your code monkey

and here is a free complete course on

making a game from start to finish if

you've always wanted to learn how to

make a game or if you already know the

basics but want to see how to organize a

more complex project then this video is

for you it's perfect for both beginners

and more intermediate users this is a

completely free course video but it has

the same level of quality as my paid

courses or my Steam games you can

download the project files to follow

along or inspect the funnel game you can

even play the final game directly on

scene we're going to start commonly from

scratch and build a really awesome game

with tons of systems and mechanics

building this design requires working

with lots of unity and c-sharp features

so this is a really awesome project for

you to learn after following this course

and learning all of these techniques you

won't be able to build all kinds of

games in all kinds of genres this is

going to involve learning about the

basics of unity and c-sharp learning how

to make a character controller physics

raycast learn all about c-sharp

interface and events using script more

objects handling UI the new input system

and lots more

very importantly everything that we're

going to do here is going to be focused

on writing good easy to understand clean

code meaning that I will not be teaching

you bad practices that some beginner

tutorials teach the code that we're

going to write here is production

quality code this is not a throwaway

demo the quality of the code and the

structure of the game that we're going

to build is on the same level of quality

as my own Steam games as you can see

from the video link this is indeed a

complete very thorough course so don't

try to watch this whole thing in one

sitting take your time take it slow and

just focus on learning there are

chapters for every single lecture in the

video here's a quick overview of the

entire course all the steps that we're

going to take to reach the final

published game so first of all we're

going to start commonly from scratch by

selecting a Unity version and creating a

brand new project with that new project

we will then learn all about the basics

of the UNT interface and setup plane

layout

then the other important part is Visual

Studio which is where we're going to be

writing all of our code

after that comes an extremely important

lecture all about coding style and

naming rules like I said the code in

this course is on the same level of

quality as my Steam games so having

proper naming rules and good code sound

is Paramount next we're going to

download and import all the assets that

we're going to use in the course

everything is included so you can follow

along with every step of the way

with yes it's important we're going to

set up some quick post processing just

to make the game look good then for our

first piece of logic we're going to make

a simple character controller with that

logic working we will then Implement a

proper character visual with the

included assets

next we're going to learn the basics of

animation and the animator component and

with that we're going to make our player

really Common live with some simple but

really nice animations then we're going

to install the send machine package this

isn't actually used too much in this

course but I still wanted to include it

because it is such a useful tool so I do

want you to know about it after that

comes another extremely extremely

important lecture with regards to

writing some good link code we're going

to do a nice refactor to replace the

Legacy input Venture with the brand new

input system

learning how to refactor is an extremely

important and very valuable skill that

will massively improve the quality of

your code with that then we're going to

implement some nice Collision detection

to make sure our character doesn't want

through walls

next we're going to create the very

first kitchen counter and make a script

to handle how to interact with it then

we're going to learn all about c-sharp

events and create a proper interact

input next we're going to build a

selected counter visual which will

require us to learn about the extremely

useful Singleton pattern with the

counters working we're going to start

working on the kitchen objects

themselves so these are going to be the

ingredients and the plates we're going

to use scriptable objects to Define all

of the types

then a very important part of our design

is each kitchen object will have to be

placed somewhere so we're going to take

some time to really think about the best

way to achieve that all while riding

some good clean code next we're going to

enable the player to pick up an object

in doing so we're going to learn about

c-sharp interfaces then we're going to

make a container counter this is from

where we can spawn new objects

with that we will enable the player to

pick up objects and drop them anywhere

where there's space

then we're going to make the cutting

counter this one enables the player to

cut an ingredient into slices so to do

that we're going to make an alternate

interaction

and for handling the cutting we're going

to once again use script more objects to

define a proper cutting recipe

then we're going to learn about a really

awesome Unity feature we're on canvases

and use that to display a nice progress

Bar for our cutting progress after that

is a quick lecture just going to make a

very useful generic script to make any

object look at the camera

next for another counter we're going to

build a trash bin this is where the

player can drop objects to destroy them

then the stove counter this one is going

to be quite a bit complex we're going to

create recipes for cooking and for

burning we're going to learn how to make

a basic state machine and handle timers

next we're going to make the plates

counter this is a simple encounter that

just spawns a bunch of plates

after that we're going to make some

custom Logic on the plate to be able to

hold other objects

with that logic working we're going to

build a complete visual for all the

objects that can exist on the plate

then make a nice UI element on the plane

itself to showcase the icons of what

exactly is on that plate afterwards

we're going to make the very last

counter the delivery counter this is

where we drop the completed plates and

in this lecture we're also going to

learn about the unity share graph and

make a quick simple custom Shader

then we're going to build the delivering

manager class that generates the recipes

that the customers are requesting next

we're going to build a UI to showcase

the wedding recipes after that comes

something pretty crucial we're going to

add some music and then add some sound

effects for all kinds of game actions

without the game won't be almost done so

next we're going to build a proper game

start and a game end

then make a simple main menu and handle

scene loading after that hand on

creating a basic pause window

then make an options menu enable the

player to modify the audio levels and

rebound keys

after that we're going to enable menu

navigation with a controller and in the

end as usual comes the Polish stage so

we're going to add all kinds of small

tweaks and effects to make the game feel

really great like I've said many times

polish is what separates good games from

great games after all of that we will

have our final completed project so as

you can see you will learn about tons of

Topics by following this course also let

me point out one of the reasons why I

chose this specific design is because my

next free course won't be on taking the

game that we're going to build here and

make it multiplayer so if you've ever

wanted to make multiplayer games then

that course will be excellent for you

definitely take your time following this

course the multiplayer free course

should hopefully be out next month or if

you're watching this in the future check

the links in description although that

multiplayer video won't be starting from

where this course ends so definitely

make sure you watch this one now if you

are new to the channel then welcome and

here's a bit about me and my credentials

or why you shouldn't listen to what I

have to teach

my name is Hugo and I've been running

this Code Monkey YouTube channel for

five years now in total almost 700

videos on all kinds of topics including

tons of tutorials sharing my knowledge

to help you on your Game Dev Journey I'm

also a professional indie game developer

making games for over 10 years with 8

successful Games published on scene so

what I'm teaching here is based on a lot

of years of experience making a lot of

games just like with my paid courses I'm

always going to be in the common

censoring questions so if you get stuck

at a particular point or need extra

clarification on something go ahead post

a comment and I'll do my best to help do

make sure you include a timestamp of

what you're referring to I will also be

updating the pin comment with any

frequently asked questions that I see so

actually right now go ahead pause the

video and scroll down a bit just to look

at that comment since on YouTube I

cannot update the video after it's

published I will be updating that

comment over the next months and years

with anything that comes up also I've

been running this channel for five years

and in that time I've made almost 700

videos so there's lots of topics that

I've covered separately in more detail

all of those videos are linked in the

description throughout this course I

will be focused on building this

specific game using whatever it takes to

build it meaning for example when we get

to using c-sharp events I won't teach

the basics about how they work in order

to achieve what we want to build but if

you then want to learn about c-sharp

events in more detail definitely go

watch a dedicated video and I also made

a page on my website for this course it

contains a link to download all of the

project assets you can also download the

complete project files for every single

lecture so if you get stuck at any point

you can download the code at that

lecture and compare with your own

there's also references to all of the

videos and I will also be including

frequently asked questions for each

lecture so definitely keep that page

open in a second tab as you follow along

this course now this free course Took a

ton of work to make so I really hope you

find this video helpful go ahead and hit

the like button if it helps you it's a

small thing but it generally does help

this video on the YouTube algorithm

making this course was a ton of work and

by making it commonly free it means it

will obviously never make as much money

as if I had just made this a paid course

I'm personally okay with that decision

with the hopes that by making it free it

won't reach and help many more people

I'm also a big believer that education

should be free so if you can't afford

one of my paid courses like if you're

just a kid or going through a rough time

I still want you to have access to high

quality education so you can achieve

your Game Dev dreams one easy way you

can help me for free is simply by liking

this video subscribing to the channel

and just watching this course

that will hopefully help push this video

on the YouTube algorithm and help it

reach many more people another free way

to support what I do is I'm currently

working on my next team game called turn

one Liberation you can wish list the

game on Steam wishlists matter a lot for

steam visibility so just by doing that

you won't be helping me and just in case

you can't afford it and you find this

free course useful you can also support

what I do in a few other ways I spent a

bunch of money making this course I

hired an artist for the 3D assets so

that I had the right to distribute them

so that you can download it and follow

along

same thing for the music and sound

effects the logo and the cost to upload

the game to seem so I would like to at

least not lose money on this project

hopefully there's enough of you who

can't afford to help me so that I can at

least break even

and for one way you can support is I

added this exact same course on my

website as a regular paid course

although I want to be very very clear

there is absolutely no difference

between this free video and the paid

course there is absolutely nothing

behind any kind of payroll all of the

lectures are free all of the apps are

free everything is free you don't have

to pay for anything if you can't afford

it or you just don't want to the paid

version is essentially a donation the

only difference is this free YouTube

video has regular YouTube ads whereas

the paid version on the website doesn't

have any ads that's it that's the only

thing so the only reason why I made that

paid version is just in case some of you

can't afford it and you want to support

what I do and want to help me break even

on this project but again only do that

if you can't afford them if you can't

that's personally fine I hope you'll

learn a ton from watching and following

this free course beyond that if you

follow this course and you enjoy my

teaching sound perhaps look into my

other courses if you like this video

then I think you won't really like my

turn-based strategy course that is the

perfect course to follow up on this one

one it Dives even deeper into some of

the concepts used here and it will help

you make the jump from beginner to

Advanced and since you're interested in

unity I think my ultimate unity overview

course would also be very useful to you

each lecture on that course is focused

on teaching one entitled feature there's

already over 15 lectures including

plenty of small but very important

things that you just wouldn't see in a

regular YouTube video if you're

interested in visual scripting I have

course on making three unique games

internally with visual scripting and no

code at all or if you prefer code you

can learn how to build a nice Builder

Defender game so if you enjoy my

teaching Style on this free course then

check out my other ones then of course

YouTube has Channel memberships and

super thanks so you can use those if you

want I also have my patreon if you

prefer that and in a lot of my videos I

have some affiliate links if you ever

pick up anything through those I get a

nice commission and I also have some of

my own assets on the unity Astor so if

you enjoy this free course and you want

to support what I do there's plenty of

ways but again don't feel obligated if

you can't afford it or you just don't

want to that's perfectly fine I hope

you'll learn a ton from watching and

following this recourse alright so

that's enough talk of that for now

before we begin building the game from

scratch let's inspect the final polish

game that we're going to build so let's

see that in the next lecture

hello and welcome I'm your code monkey

here let's take a look at the final game

that we're going to build so we start

off on a simple but really nice main

menu so we've got a nice visual a nice

logo and a bunch of useful buttons then

of course the game has a nice loading

system so when I click on play it's

going to load into a unloading scene and

then funnel into the final game scene so

let's go ahead and play and if there we

go here we do see the game scene and

right away we see a nice internal window

so it's telling us how to play the game

so the basic interactions and then over

here the controls importantly these are

all rebindable so over here this element

is all Dynamic then we can look at this

tutorial for as long as we want and we

are waiting for the interact to continue

there's also a really nice song playing

in the background so the game has music

now we can look at this tutorial for as

long as we want and when we're ready we

can interact and continue and as soon as

we do if there you go we've got a nice

countdown some nice animations a nice

sound effect and there you go now we are

playing okay so here I am controlling a

nice character I can move in any

direction

there is Collision detection so

obviously I cannot go inside solid

objects so I can walk around and for the

goal of the game over here on the left

side we've got recipes that the

customers are waiting for so for example

One customer wants a simple Burger so

for that we gonna need to pick up a nice

bun so let's pick it up then the burger

obviously requires a meat Patty so let's

go ahead we can pick one up from here

but this one is an uncooked meat padding

so we need to drop it over here on the

stove and there you go it starts cooking

we've got a nice timer we've got a nice

warm bar UI

and there you go it keeps counting and

we've got some nice park on some nice

visuals and over there even a nice

indicator telling us the meat is about

to burn and there you go the meat has

burned so now I can pick this up and I'm

holding some burnt meat so the customer

probably doesn't want to eat this so we

can go over here to the trash or trash

it let's try doing another one and do it

properly so let's wait for it to cook

pick up a plate so we can pick it up

directly onto the plate there you go to

the meat is cooked so let's pick it up

then go pick up some bread and there you

go here we have our camelli recipe so

let's go into the delivery counter

deliver it and there you go a nice

delivery success all right awesome we've

just delivered our first recipe so then

someone else wants a salad so let's go

ahead pick up a tomato here we have a

big uncut tomato so let's drop it onto a

cutting board and now we can interact

with it so we can interact with a

secondary interaction key

and by interacting we cut the tomatoes

so it takes a few cuts and there you go

with slices and it's sliced into tomato

slices so let's do the same thing for

the Cabbage here we are holding a

regular cabbage then slice it and this

one actually takes a bunch more and

there you go got both slices okay great

so now let's pick up the plate pick up

both slices and deliver to the customer

and there you go got a nice success all

right awesome and of course we have a

correct identification of if we have a

crack recipe or not

so if I just pick up an empty plate and

deliver it there you go got a film

delivery because nobody wants just an

empty plate alright so here you can

already see quite a lot of interactions

quite a lot of systems at work so the

character has a nice character

controller it has physics interaction

you can see how it identifies the

counter that is in from the character I

can press a button to interact with the

counter and interacting with different

counters does different things so if I

interact with a clear counter I can pick

up or drop things over here I can pick

up drop it with an alternate interaction

I can do the second action then there's

the stove machine so that one has a nice

State machine so it counts up over here

we've got some nice particles we've got

a nice Bloom so all the Visions look

really great so we've got some post

processing we have a bunch of UI

elements directly on the world and

outside of here we've got some regular

UI elements

so we've got the recipes with Dynamic

icons for all of them we've got a timer

over there on the top right corner

showing how long we have to deliver on

our recipes and on the kitchen counter

we're also using a custom Shader so this

was built using shade wrap so as you can

see lots of internalized systems then

the game also has of course the basics

that any game should have so I can pause

the game and there you go we've got a

nice pause menu so we can resume to go

back or pause it again and of course

while pause everything is possible

that's great we can go back into the

main menu or we can go into options and

over here we can play around the sound

effects volume the Music Volume we've

got all of our controls importantly

these are the controls for the keyboard

and also the GamePad

so the game can be played with any

Gamepad so it can be an Xbox controller

PlayStation switch controller it doesn't

matter all of them work and we can also

rebind all these Keys both the keys as

well as the GamePad inputs so let's go

ahead and deliver a cheeseburger so

here's some burn meat so let's toss this

then pick up some more meat pick up a

plate here we've got some cheese we've

got some bread pick up the meat and

deliver it all right awesome and of

course finally at the end when our

timers left here we have a nice game

over window showing how many recipes we

delivered alright so this is the final

game that we're going to build as you

can see it involves lots of interesting

interactions which require learning lots

of different skills we're going to be

using c-sharp interfaces c-sharp events

the new input system shade graphs

critical objects we're going to learn

about c-sharp events making character

controller handle collisions and so on

like I said one thing that we're going

to focus heavily throughout the making

of this game is on writing good clean

code meaning that the final game that

we're going to build won't be very easy

to expand upon thanks to how long the

code is very clean it will be very easy

to add more recipes maybe more counters

with more actions maybe things like

perhaps washing dishes adding an oven

and so on or really you could make

something completely different

this game is all about character and

interactions

so that could be whatever you want you

could take this as a base and build some

kind of sci-fi game something like Among

Us or FTL you could make a survival

crafting game like rust or Minecraft or

Don't Starve really fun learning how to

build this game by the end you won't

have gained the knowledge required to

build all kinds of unique and

interesting games alright so now that

we've seen the final game Let's actually

build it just before we do let's get a

quick refresher of the absolute Basics

you should know in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to just get

a quick refresher of the absolute Basics

you should know in order to be able to

follow everything in this course okay so

like I said this free course is targeted

at both beginners and more intermediate

users in order to start following the

course you really only need to know the

absolute Basics I've made three useful

videos with all of the basic knowledge

required to follow this course

watch the video on how to download

install and set up Unity then the quick

Unity Basics and the c-sharp basics

those three Quick videos contain all of

the absolute basic knowledge you need so

if you're a complete beginner go ahead

pause this video and go quickly watch

those and even if you are already

somewhat familiar with unity still go

ahead and give those videos a watch

perhaps in a faster speed just so you

know everything that this course assumes

that you know here I will assume that

you know the basics covered in those

videos like what is a game object what

is a transform what is a mono Behavior

how scripts have a start and update and

some c-sharp Basics as long as you know

those absolute Basics you should be able

to follow everything in this course I

won't teach everything above the

absolute Basics and if you are a more

advanced users definitely keep watching

the beginning of this course might not

have much that is new to you but as we

build the game and start using more

advanced tools like script of objects

c-sharp events and interfaces

refactoring code and focusing on Project

architecture and writing some good clean

code

if you are not a complete beginner you

will still learn quite a lot from seeing

how this project is built and again like

I said I answer comments every single

day so any questions you have just post

them there and I'll do my best to help

this course is split into lectures they

are all as chapters on videos so you can

navigate around let me also take this

time to point out that you are not

expected to follow this course in one

sitting go ahead and take your time

focus on actually learning remember

that's the only goal you're not

competing with anyone you're gaining

knowledge just for yourself

so take as much time as you need

re-watch some lectures if you feel you

didn't fully get it or just ask some

questions whatever you do take your time

and just focus on actually learning so

again if you haven't done so go ahead

pause this video and go watch those

three Basics videos with that we're

going to have everything we need to get

started we're going to start only from

scratch so let's begin creating a brand

new project in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to begin

actually building our game so let's

create a chameleon 2 project and start

building it on from scratch okay so the

first thing that we need is to install

Unity now I cover this in detail on that

other Basics video so here I will assume

that you already have Unity Hub

installed the first decision we really

need to make is choosing a Unity version

Sony Hub you go into installs and

install an editor and now Unity

recommends that you use the LTS version

or long term sport you should be using

that one in most cases it's what it

installs by default which as the time of

this recording the latest one the latest

LTS one is 2021.3 however I want this

video to stay up to date for as long as

possible so for making this game I will

actually be using version 2022.2 if

you're watching this video where it is

came out then download this version and

if you're watching this months in the

future after version 22 on TS is out

then you can use that one it won't

probably be the exact same thing as

version 22.2 so you should be able to

follow everything exactly for any

changes I will Point them out in the

updated pin comment and if you're

watching this years in the future and

there's an even newer LTS version I

would still recommend you follow using

the 22 LTS don't worry about using a

quote unquote older version everything

you'll learn here in this version will

still be applicable even 10 years from

now so I said I'm going to be installing

this one in terms of modulus doesn't

really need anything I already have

Visual Studio Community installed and

all the other ones are unticked so

install

okay so the version is installed now

let's create a new project let's go into

the projects tab then create a new

project and now first up up here make

sure to select the right version so

again I'm going to be using 22.2 then

for the templates this has mainly to do

with the UNT render pipelines now if

you're a beginner don't worry about that

too much just go ahead and select the 3D

urp template so scroll down this one

right here 3D urp make sure to select

this one and not the one that says just

reading the urp here stands for the

universal render pipeline which means

our game will be playable on literally

any platform so we can make the funnel

game and put it on steam or consoles are

mobile it won't run on everything then

over here on the right side let's

quickly just download the template there

it is it's done

now select the name for your project so

I'm going to call this kitchen chaos and

then select the founder for it all right

so that's it again make sure you're

using the exact right version make sure

you're using the 3D urp template give it

a name a folder and let's head on create

all right so it's open and right away

you might or might not see a window

talking about urp material upgrades I

think this has to do with the template

not having the default materials updated

to the latest Erp version so if you're

watching this in the future chances are

you might not see this one at all but if

you do then just go ahead click on OK

and it will automatically upgrade all of

the default materials alright so here we

have our basic unity window now since we

started a project starting from the RP

template we have down here A bunch of

Erp helper files so you can click to

select the readme file and you can see

it over here on the right side on the

inspector if you want you can browse

around these links in order to learn

more about urp but in our case we're

building the our game we really don't

need this so we're here on the

inspection let's just click this button

to clean up these readme files just go

ahead click on yes and okay that's it so

basically you should only have these

files in your project window so there's

a scene folder and inside we've got the

simple scene then we've got the settings

and inside a bunch of urp assets while

this should have been set up

automatically since we use the 3D

template and then finally we just have

the urp equivalent settings asset now

let's just verify find everything worked

correctly so let's go to the top left go

into edit then go down into project

settings then over here let's go into

the graphics Tab and you should see the

urp High Fidelity asset assigned by

default if not you can click on the

circle icon and assign it then the other

menus over here the urp mobile settings

again this one should be set by default

then down here on the quality tab on

this one make sure High Fidelity is

selected basically whatever you select

here is the quality that we'll be using

in the editor and in turn the selected

quality over here also has a render

pipeline Ascent now in order to avoid

any confusion let's actually get rid of

the other ones so let's just click on

the trash icon to get rid of the

performance and the bounce quality so

just click and click okay so we only

have this one then let's close the

project settings and let's go into the

settings folder and over here let's

select the urp balance there are two

assets for each quality so select those

leave the High Fidelity and the

performance and let's delete these

alright that's it by the way if you made

a mistake and accidentally deleted

something don't worry you can always

just click over here on the plus icon on

the project window and then go over here

under rendering and you can create a new

urp asset with the universe personal

render okay so just like this so we only

have one quality setting we have high

fidelity the quality setting is using

this random pipeline asset which is also

using this renderer so that's really it

with this we have the absolute bare

minimum we need if in the end after

building the whole game you want to

provide multiple quality settings then

you can come back to this menu and

recreate them but in order to avoid

confusion while building the game let's

keep things like this as simple as

possible okay so that's the basic setup

done next we want to prepare our layout

so let's continue on to the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to learn

about the union layout and set it up so

first things first let's familiarize

ourselves with the various NT Windows to

create our own layout it's very

important that you feel uncomfortable

with your layout that you have easy

access to all the things that you need

then you know where everything is you

can see that there's lots of tabs

everywhere over here on the NT window

all of them can be dragged and dropped

in any different position so you can

customize your layout to get it looking

exactly as you want you can set it up in

any way but it will be easier to follow

this course if you're following the same

layout as me I'm assuming you've seen my

quick Basics video so I'm assuming you

know what is the inspector what is a

game object what is a transform what is

the console where is the hierarchy and

so on if this is the very first time

you're seeing the UNT interface go watch

that other quick video first just learn

the absolute Basics now for me I've been

using Unity for over 10 years now so

let's see the layout that I've developed

over the years first the inspector on

the right side just like default that

way we always have a nice view of the

selected object and whatever scripts and

components it has then for the hierarchy

I like to put it down here only on left

side we're going to make sure that in

our scene is always organized so we

don't need the hierarchy to take up tons

of space then with the project files

next to it this corner is enough to

really browse all of the files we want

the console to be on the tab right next

to it usually I find that when making

the game I want to look at the project

window but when playing the game I just

want to look at the console so keeping

them in the same place but on different

tabs works great then over here on the

center of the scene View and again with

the game view right next to it okay so

this is the basic layout that I normally

use now for a couple more options let's

go into the project window and on the

top right corner you can see over here

these little three dots by default it

shows you a two column layout so there's

a column here and a column here but

personally I prefer the one column

layout this shock is one of the project

files in a nice compact list view the

one thing where I prefer the other one

is if you're browsing for some visual

assets over here you can increase the

thumbnail size but for most times I

really like to use the one com layout

much more compact also since we're

talking about the project window just in

case you don't know there's over here

this little button with the eye this one

has to do with package visibility if you

toggle it then some of the inside

compacts are hidden whereas if you

untangle it then you can see all the

various packages with all the source

code and so on you can expand over here

the packages and right now it is showing

all of them all of them with source code

the things everything in there and if

you click on this then it hides it only

shows a bunch of core ones but for most

part you really want to leave this text

and leave this one collapse nice and

clean okay so then on the console over

here once again let's go into the three

dots and for the unlock entry for this

one I like to select one line this makes

the console nice and compact which I

personally prefer you can see more logs

without taking up more space and if you

want to read the home log you can always

just click on it to see the home stack

Trace now there are also some more

options over here if you want for

example show the timestamp this will

show the timestamp when each message

were sent you can use a mono space font

meaning a font where every character has

the exact same width so a bunch of

options but for me leaving it just like

this works perfectly fine then also

importantly over here these three

buttons these toggle the visibility for

the type of messages that appear in the

console the unlocked one this one is for

regular messages we're going to use this

a lot then we've got warnings and

finally errors if you untangle them then

the messages of that type will not show

up on the console so if you ever come

across an issue where nothing is showing

up on the console make sure all three of

these buttons are ticked then on left

side on clear you can click on the Arrow

to see more options I like to set it to

clear on play then collapse this one

basically collapses messages that are

the same all of them into one entry

personally I do nothing like this I want

to see every single message as it comes

out even if it's repeated I've also seen

this lead to a lot of confusion for some

people they think their code is firing

just one message when it's actually

firing hundreds So to avoid any

confusion make sure you leave this

Untitled then for airpods this will

automatically pause the game when there

occurs you should definitely have this

one toggled if there is an area you

definitely want to know about it you

want to know when it happens so you can

fix it whereas if you untuckle this you

might get some errors and the game might

keep playing which will then lead to

lots of confusion when something starts

behaving weirdly so always leave this

one toggled and then the editor button

this one is for more advanced use case

so don't worry about it okay so that's

the console then over here for the game

view we've got a button here to select

the aspect ratio let's go ahead and

select fully Gene this one is a 16x9

aspect ratio so everything is pretty

normal this will really only matter when

we start working on the UI but so I like

to keep it at 16x9 always then on this

button that says play Focus we can

modify some options basically Focus

won't play exam like this on this small

window if you choose maximize then it

will maximize this one when playing the

game and play in Focus won't play the

game even when the window is not in

Focus then another important one is

actually on the same one as the aspect

ratio here we've got a button to turn on

vsync usually When developing the game

you really want to toggle this that's

because right in the beginning when the

game doesn't really have anything you

can leave it on Talent then this might

run at like a thousand frames per second

and that will pretty much drive your GPU

crazy finally if your game view is

looking a bit too pixelated make sure

over here on the scale slider make sure

this one is not zoomed in this one

should always be pushed straight to the

left as much as possible okay so that's

the game view then over here on the

scene view for this one default should

be good these two buttons are extremely

important pretty much all the time you

want to keep the tone handles on the

pivot it and not on the center if you

ever see your handles on weird places

always come back to this you want to

sound pivot pretty much all the time

then for rotation sometimes local is

useful but for the most part you should

probably be keeping in and Global then

for the great showing the reason why yep

down looks pretty good a nice little

visual grid then you've got a bunch more

options if you want then next to it

we've got snapping this one we also

don't need this for now and finally same

thing for increment also don't need this

okay then on the right for the drum mode

let's leave it on Shaden for two then

let's leave this disabled since we're

working on a 3D game for lights let's

make sure this one is enabled for sound

we're only going to add this in the end

so it doesn't really matter for now then

for special effects usually you want

this one to be enabled so it shows

everything you can click on the arrow

and make sure all of them are toggled

the only exception is always refresh you

probably don't need this little scene

window to be refreshing at 60 frames per

second so you can leave that one

unticked and take on the others then

these are for the hidden objects so

let's leave them toggled for the camera

here are the defaults and finally gizmos

leave them all enabled as the defaults

alright so down that's end here is in

layout and going to be using throughout

the course it will be easier to follow

the course if you're using the exact

same layout as me so ideally you should

be using this but again like I mentioned

all the windows are customizable so if

there's something that you absolutely

prefer differently then go ahead you can

drag and drop and place any Windows

anywhere you want so once you have

layout your happy win you can go up here

to the top right corner where it says

default you can click on it and here

you've got a bunch of layouts so you can

save your new layout so I'm going to

save this one as kitchen chaos and then

over here you can select anyone you want

for example if you ever have some issues

with any kind of weird editor Windows

you can load back the default layout and

then go back and load your own layout

okay so with that our layout is set up

the next important thing is setting up

visual studio so let's do that in the

next lecture

hello and welcome I'm your code monkey

in this lecture we're going to set up

our Visual Studio alright so with the

Intel layout setup let's make sure

Visual Studio is also set up correctly

I'm going to be using version 22

Community this one is the free version

you don't absolutely have to use the

same code ID that I'm using you can use

writer or vs code or whatever you want

so let's see my setup for visual studio

but first let's actually set up

something over here in unity so let's go

up top into window and then let's open

up the package manager then over here on

the drop down menu let's select the

packages and select the ones from DNT

registry then let's scroll down to find

the visual studio editor package so here

it is this one this package basically

handles the integration with visual

studio so you can use the debugger and a

bunch of things alternatively there's

also a package over here for visual

studio code and there's also one over

here for jetbrains Rider so if you're

using a different IDE go ahead and

install the package for me I'm going to

install the visual City one so this one

just go ahead and install okay it's done

so next let's go up into edit and let's

open up the print preferences then over

here let's go down into external tools

and on the external script editor make

sure you select the one you're using so

again for me I'm using visual studio 22

and also over here you've got a bunch of

extra options now if you want to play

around with reading the source code for

the very CNT packages then you can tick

on these boxes but in our case for this

simple game we don't need that so go

ahead and leave everything just like

this with defaults okay so with this

setup now we can go over here into

assets and open up the c-sharp project

and this should open up visual studio

and alright so here it is now for some

more settings inside of here in my

visual studio I have a really nice

extension that adds a bit more colors to

my code which makes it easier to read

and write so up top let's go into the

extensions menu and manage extensions

and the important one that I've

installed is this one vs4 if you want

you can go into the online Tab and over

here search for it any Apple that show

up in here then for the settings on that

extension let's go up here into tools

and let's open up the options then over

here let's scroll down and find vs4 Yep

this one and here are all the settings

and expand this and a bunch more

settings now for me I think these are on

the defaults I don't remember if I

changed anything the important one is

over here the rainbow braces so these

have a bunch of Commerce which make it a

bit easier to read the code so let's

create a simple script just to see this

so back in until let's go into the

project window let's click the plus icon

and let's create the brand new c-sharp

script let's call it just testing wait

for it to compile and now let's open now

over here I'm just going to write a

bunch of simple code just to test it out

you don't have to follow this alright so

here's a bunch of sample code these are

the colors you can see it makes

everything a bit easier to read although

again this is not a requirement you

don't absolutely need this extension but

personally I do find it quite useful I

find that it helps make the code more

readable than having everything be gray

okay so that's the setup for this

extension next for the text formatting

options so once again let's go into two

holes go into options and then over here

let's go into the text editor then over

here I think I've got pretty much all

the same defaults then we can go into

the c-sharp rules so here are all the

settings if you notice something

different on your end go ahead and pause

the video and compare the settings but

again I think everything here is pretty

much defaults I believe the only

difference that I did was over here on

the code style over here for new lines

personally I like to have the currently

brackets on the same line but if you

want you can also change it and put it

on the second leg I think that's pretty

much the only difference that I did

everything else should be exactly the

same as defaults so that's the code

sound settings and speaking of that the

next lecture is very important we're

going to talk a bit about naming rules

although just before we go let's just

clean up our testing script so let's

close this one click on the X then back

into Unity we don't need the script so

let's just delete it okay so with that

we have Visual Studio setup and ready to

go now let's continue in the next

lecture to learn about some naming rules

hello and welcome I'm your code monkey

in this lecture we're going to learn

something extremely important let's

learn about naming world this one is a

very important lecture that you should

definitely refer back to whenever you

have some questions so first what

exactly are naming rules these are

really just rules you follow when

writing your code it is extremely

important that you are consistent in

applying your own rules you don't want

one class in your game to be written a

certain way and then a different class

using a completely different style that

would create tons of confusion so naming

rules and writing the code correctly is

very very important one mistake that I

see a lot of beginners do is they send

me some code and ask why it's not

working then I take a quick look and I

see that all of the code is written in a

very messy way some functions are on

lowercase others using snake case some

films are in personal case some in camel

case and so on remember that code is

case sensitive so it is extremely

important that you write the code

correctly if you change a character from

lowercase to uppercase then you are

suddenly referring to something

completely different if you're a

beginner keep that always in your mind

code is case sensitive so don't just

write code semi-randomly write it

properly as if you were doing an English

literature test now with that said when

it comes to naming roles you can use

whatever name neurons you want different

people like different rules for example

you can use a prefix in your variables

you can use a postpick you can use

capitals for consonants chemical case

for properties snake case for Fields by

the way here are the definitions of what

those terms actually mean Pascal K

starts with a capital and every word is

capitalized camel case starts lowercase

and then uppercase for the first

selector of every other word kind of

like a camel hump in the middle and

snake Haze is where you add an

underscore in between the words I send

every rule can be valid the important

thing is that you are consistent in

always following through with your rules

as you might know Unity mono behaviors

have some deformed functions you can

Implement things like start and update

which are written using pastel case

since you can't really change in these

rules at least on function names I would

say you should base your rules off of

theirs so for functions you should

probably be using Pascal case for the

rules like I said choose whatever makes

sense to you here are some of my own

personal rooms that have developed

jumped over the last 10 years and the

code sound that I won't be following in

this course for functions I use Pascal

case just like unity and just like the

c-sharp standard for function parameters

I use camel case for Fields also camel

case properties are in personal case

constants are in uppercase snake case

then another rule is that I like to add

the top of the variable as a postfix so

if it's a list type in the list if it's

an array open array and now you might be

thinking with this wouldn't it be an

issue if we change the type then the

name is suddenly wrong and the simple

solution for that is that if I change

the type then I just use Visual Studio

to quickly change the name that's it

then for the currently brackets like I

mentioned in previous lecture I like

them on the same line some people have

some very strong opinions about this

really it's just a visual style and this

is the one that I personally prefer if

you like new online then go ahead and

use that it doesn't change how the code

Works in any way in a final rule spend

some time deciding on a proper name and

don't be afraid to rename things you

will note how all the code that we're

going to write in this course has proper

names for everything you should never

use a variable with a single letter like

X X or k the exception of course would

be iterated in a for Loop also don't use

acronyms or abbreviations those might

seem player right now but in a few weeks

you might not remember what they mean

remember you don't get bonus points for

writing extremely compact code so

prioritize making your code readable and

understandable even if it requires

variables and functions with long names

so these are my general rules and the

code style that I personally follow

figure out what works for you and follow

your own naming rules but naturally in

this course I will be using my own code

cell so if when following the course you

are not sure how to write some type of

code you can refer back to this lecture

and watch it again like I've mentioned

many times the code that I won't teach

you how to write in this course is on

the exact same level of quality as my

paid courses and my Steam games so as

such because that this lecture these

naming rules are all extremely important

okay so with this very important lecture

out of the way now let's start playing

with some visuals by importing some

Assets in the next lecture hello and

welcome I'm your code monkey in this

lecture we're going to import the

project files with all the assets that

we're going to use by the way remember

that if you have any questions go ahead

and post them in the comments I go

through those every day and I'll do my

best to help okay so with the project

created the next thing we want is to

import the assets that we're going to

use to make this game you can download

all of the assets with the link in the

description which by the way like I

mentioned a while ago that link contains

a Unity package that contains both the

assets and the final game so when you

download that you get ENT package just

go ahead and double click or click and

drag and drop it on the projects window

here is the asset import window just

make sure you select all and let's

import okay so here it is let's import

the assets folder and inside comes all

of the assets meshes textures and so on

so everything we're going to need and

then it also imported inside of it

another ENT package so if you want to

import the final project with all of the

code already written it's also here if

you extract this one you're going to get

the complete project files now of course

don't do that if you want to follow

along with the course and be aware that

if you're following along and you

accidentally end unpack this one it will

override all of your own files so if you

want to inspect the final project files

go ahead and do that but do that in a

separate project in order to make sure

that we have no accidents I'm going to

delete this one from the current project

so just go ahead and delete okay so

that's it and over here we've got all of

our really nice visuals we can look in

the prefabs visuals and over here we've

got a visual for a container Sergo

that's a container counter then we have

a cutting counter we've got a trash bin

then on the kitchen object visuals we've

got all the visuals so a block of cheese

we've got some burned meat we've got a

plate and so on these are all the nice

3D models that we're going to use in our

game and then over here on the textures

folder we also got a bunch of General

icons as well as actual icons for all of

the various parts okay so all of the

assets have been important now let's

continue on to the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to set up

post processing now here let me make a

quick note usually when making your

games you probably don't want to hand on

post-processing right way you should

first get an ugly prototype up and

working before worrying about any

visuals so normally I would only add

post-processing much later on in the dev

process but since this is a course in

video format in order for the video to

look a bit more appealing let's set a

post processing right away now we

already have the project set up to use

urp so adding post-processing is

actually super simple it's actually

already added by default first before we

do that let's rename our scene with a

proper name so inside the scenes folder

it starts off with sample scene this

will be our main game scene so let's

just rename this to game scene okay and

now here on the hierarchy we can see by

default this scene already contains a

global volume game object this is how

you actually add post-processing and by

default you can see that it also already

has a sample and profile attached this

is how you add all of the various

effects you can click on this link and

it will show it over here on the project

window now let's film this from scratch

instead of starting from this one so

let's go into that file into that asset

and just delete it okay so now we have

no value profile now let's go ahead and

click on new to create a brand new one

okay so now here we can add overrides

add all of the effects that we want

let's drag some visual meshes that we

imported in the last lecture to get a

better look at all these effects and

what they do so first let's make some

kind of more so let's make a 3D object

let's make it a plane let's name this D4

also one extremely important thing

whenever you create a brand new object

always check the object's transform

position by default when you create an

object it appears in front of the scene

camera which will probably not be on

zero zero zero you always want to be

very careful with the position of your

actual objects so for a plane we do want

this to be on the origin so on zero zero

zero so make sure you always do that

then let's scale it up a bit so on the

scale let's put it on 555 which by the

way you've got this nice little icon

this was added in a recent Indie version

basically if you enable this and matches

all of these values so if you just

change one of them it changes all of

them so let's put this on Five okay

great now for the visual let's go ahead

into the mesh render on the materials

and let's select the brand new material

so let's click on the circle icon and

over here let's find the floor material

so here it is it's the one included in

the assets there you go we've got a nice

basic form material now let's also drag

the player visual so let's go inside the

assets folder and over here let's go

inside the prefabs visuals and down here

we find the player visual so let's just

go ahead and drag this one so there it

is a nice player visual let's also drag

a counter so let's find let's say the

Clear counter let's drag this one let's

rotate it to face the camera something

like this and let's also put a cutting

counter again we're just placing some

visuals just so we can see what the post

processing will do and let's also place

a bunch more things so let's say a

tomato let's place a tomato over there

and maybe cabbage all the way over here

okay so we've got a handful of nice

visual elements so we can test out our

post pressing by the way here's a quick

empty tip on scene controls whenever you

are on the scene view which make sure

you're on scene View and not game view

those are different so on the scene view

you can move the camera with a mouse you

can pan with mouse 3 so the middle Mouse

button so hold that and pan around we

can rotate with the right Mouse button

you can rotate around Point by holding

down left alt and left click and just

drag it around to rotate around an

object you can select an object like for

example player visual then you can press

on F to select that object and now if

you hold alt and click it will rotate

around that object also another method

is you can hold the right Mouse button

to move it around and then you can use

was to move so d a and so on then you

can even press shift to move in faster

and you can use the scroll wheel while

holding down the right Mouse button or

to modify the speed at which you move so

there are plenty of camera controls to

really get you seeing exactly what you

want to see now for another quick empty

tip you can move the scene camera to

where you want the game camera to be so

let's say I want the game camera to see

things from about this angle so you just

position the scene camera then on the

hierarchy select the camera game object

so the main camera right here and with

that object selected you press Ctrl

shift and F and if there you go you can

see over here on the camera preview let

it position the main camera looking on

the exact same position at the exact

same direction as the scene camera set

the shortcut Ctrl shift F or

alternatively go up into game object and

over here on line with view now if you

look here is the scene View and over

here we've got a nice camera view so

just position the camera somewhere where

we can view all of the Assets Now with

this let's add some post processing

effects so first let's select the global

volume game object and over here we can

add all of our effect overrides first up

let's begin by adding tone mapping so

there you go we've got the effect and

over here we've got a nice little

checkbox so you can enable it in order

to enable this effect and set one of the

options now for this one I'm not too

familiar with color correction but I

find that usually adding a neutral tone

map usually that helps also make sure

you're looking at the game View and not

the scene view if you're looking in the

game View and you enable and disable

this effect you should see a difference

whereas on the scene view if you enable

and disable it doesn't actually show

that even if you're on the scene view

over here you have all the effects

enabled even with that some effects for

some reason don't show up on the scene

view so when playing around these

effects almost make sure you're

unlocking through the game view so like

I said you should be able to toggle this

and see a visual difference on the game

view if you don't then make sure the

camera has post processing enabled so

let's select the main camera game object

and down here there's a tongue for post

Crossing make sure this one is enabled

and then also on the render pipeline

assets so let's find that one on the

project window over here we've got the

settings and we've got the urp High

Fidelity this one should be using a

renderer so if you click on the renderer

over here you should have post-rossing

enabled again all of this should already

be correctly set up by default so if

you're going to take a global volume

enable our disabled you should see a

visual difference okay so next Effect

one that I always like to add is a bit

of saturation so let's add an override

post processing and let's add a brand

new here it is color adjustments then

over here you've got plenty of things to

play around with for me I like to add a

bit of saturation so just lift it up a

little bit let's say just about 20 and I

also like to add a little bit of

contrast over here and let's also add

20. and there you go it makes the colors

pop a little bit more so personally I

don't like this effect then later on

we're going to have some glowing objects

for example the stove let's actually try

dragging that into the scene so let's go

into scene View and in the assets let's

find the stove counter so here it is and

inside the stove counter there are some

things so here it is the stove on visual

this one is disabled by default also on

the inspector let's just enable on this

game object to make it visible again

don't worry about the positioning of the

objects on the scene view right now

we're only positioning them just to set

up the post pressing we're going to

delete them all at the end of this

lecture okay so now in enable let's go

into the game View and over here we see

the stove enabled so now let's go into

the local volume let's add an override

go into post pressing let's add a volume

effect so right now notice how that one

is not glowing red hot for that work we

need to have Bloom and we need to enable

the threshold and the intensity if we

raise the intensity we do see yep there

we go a really nice low there by the way

here's a quick visual attempt if you

want to make your game feel a bit more

ethereal and magical one good way is to

put the threshold that on low value

below one so something like 0.5 and then

put the intensity as a little bit and

with this notice how everything has a

slight low even colors that don't have

any extra intensity so the floor is

glowing the character is going so

everything looks quite a bit ethereum

this is a bit extreme but it is an

interesting effect also another quick

note here in case you're not seeing

anything change make sure you go into

the render prop online assets so the urp

High Fidelity and over here make sure

AGR is enabled you can look at so low if

I disable it yep that one stops glowing

and with that enabled it does start

glowing AGR stands for high dynamic

range so that is how you can have a

color go with an intensity above one

which actually makes it low when you

have the balloon post pressing if even

with that you're still seeing issues

then make sure you go into the renderer

and over here for the post processing

sometimes Unity has a weird bug and

doesn't generate this post-process data

file so if that does happen just go

ahead untoggle and toggle this and it

should work and finally like I said on

the camera make sure you have post

Crossing in Arrow so with all that you

should be able to see the game view glow

okay back into our effects with our

balloon working like I said you can

lower this below one to get a nice

ethereum look but this is a bit too

intensive on what we want so let's make

it a bit more subtle so on the threshold

let's put it at 0.95 so there's a slight

low on the white Parts but nothing too

intense and for intensity let's put it

at a wrong number one okay so I think

that's a nice amount of Bloom all the

colors glow a little bit and we can see

over there the stove it is indeed

glowing okay great now if you ever

forget all these steps and you can get

your project to Glow I made a nice video

with a nice checklist of everything

needed for you low definitely go ahead

and watch that video whenever you have

issues then for another fun effect we

have yet so let's go into ad override

post Crossing and let's find the

vignette what this one does is adds a

bit of Darkness to the colors so if we

enable the intensity and we increase it

you can see what it does so it adds

Darkness around the corners there

personally I find this one looks good

when it's quite a bit subtle so let's

put the intensity at some like 0.25 and

then for the smoothness let's also put

it on 0.4 so just like that just a

slight Darkness on the edges so

personally I think it looks pretty good

and that's pretty much it for the Post

Crossing on the volume component I like

how this looks you can see difference

with the volume enabled or disabled

quite a big difference looks pretty nice

but again these are just visuals so feel

free to play around maybe add some more

effects using different settings these

are just visuals they don't impact the

game logic at all so feel free to make

it work exactly as you wanted then yet

another thing related to post processing

but not in this component it's some

anti-aliasing for that one place where

you can change it is on the main camera

over here you see a film for post

Crossing and you have a bunch of types

so fxa a or smaa or if you want some

more higher end post processing you can

go into the render prop online Essence

so urp and hyphenoly and over here we

see anti-analyzing msai this one is a

bit more expensive but looks a bit

better if you want to see difference you

can go over here into the aim View and

on the slider up top on the scale you

can increase this quite a bit so with

this we can now see the pixelation and

you can see over here if I switch at the

only thing from 4X back into the table

you can see lots of jagged edges and if

I put it on 2x Yep looks a bit more

smooth 4X a bit more smooth and 8x even

more smooth so with that you can see

difference on all the edges on the

things by default this renderer has on

4X and nothing on the camera this

already unlocks pretty good but to make

the video look even better I'm going to

put it on 8X and on the main camera I'm

also going to leave it with no

anti-alency you can combine them but if

you do then everything looks a bit too

wiry so I don't quite like that effect

so put this one on none and the other

one on 8X although again this is just a

visual so if you have a low end PC feel

free to go into the urp and over here

disable anti-alizing so the game looks a

bit worse but it won't run much better

okay let's drag the scale back down okay

now one final thing we can add is some

really nice screen space ambient

conclusion for that let's go into the

render so not the render pipeline asset

the renderer and over here by default it

already added screen space ambient

Collision if it didn't add you can click

on ADD render feature and over here you

won't be able to see it I don't see it

because I already have it okay so here

it is basically what this effect does is

it adds some tiny Shadows where geometry

intersect if we enable and disable it

quickly we can see the effect over there

on the counters so you can see with

default effects it already Works quite

nicely for example look there on the

player we can barely see the difference

between the head and body but if we

enable this it has that nice little

Shadow I think it looks really nice but

then we've got a bunch of settings we

can play around increase the intensity

the radius and so on Now One important

thing when setting all these effects is

to remember the point of view of the

camera in this case we're making a

top-down game so before we play around

these settings let's actually position

the camera in a correct position so

let's go ahead select the main camera

and let's position it above pointing

down so let's put it on an X of 0 on a y

of 21.5 on his head of minus 21.3 then

for the rotation on the X 46 then 0 and

0. and finally on the camera over here

on the field of view instead of 16

that's really wine for this game let's

go with 20. okay so this is the view

that we're going to use for our game let

me just rotate the object so they

actually face the camera so on the

hierarchy let's just select all the

objects let's rotate them all around and

just position them again we're only

using these just to see what they look

like we're going to delete all of these

objects in a bit okay so yep that's the

game view now that we have the camera

set up let's work on the settings for

the eminent conclusion so let's go down

select the renderer and over here for

the settings for the intensity and let's

put it on four for the radiance let's

put it at 0.3 and direct lighting

strength let's put it all the way up to

one okay so you can toggle this enable

and disable to see difference and yep I

do think these settings look pretty good

finally the last thing we need to check

is in lightning window so let's go into

window then down into rendering and

let's go into lighting how it pops up

the unlighting window personally I like

to Anchor it over there next thing

inspector and over here we're really

going to leave everything on defaults so

you can leave it as the lighting

settings assets and nothing assigned and

then on the environment tab over here

again all of the defaults I didn't touch

any of these so we've got environment

lighting from the Skybox and then some

multiplier of one so everything pretty

much on defaults although again like I

said most of these visual effects are

very much personal preference so if you

want to make your game look a bit

different than mine then go ahead you

can play around with lighting over here

you can change Skybox gradient color and

so on if you want you can use some bake

lighting then if you want you can add

all kinds of extra effects and also by

the way remember that the effects are

stored on this profile over here so for

example you can click over here on the

Clone button and it will include the

effects and let's click on it to find it

yep there you go so that's the one that

I've built and here's a clone one so if

you want you can make a clone one and

then make it look very different for

example let's go into chromatic

aberration make it really intense and

for example let's go into the counter

curves and over here for some reason

let's drag the green up and so on so

there you go completely different visual

so if you want to play around make some

weird effects and if you want to go back

to just revert back into the original

profile personally I'm quite happy with

how this looks so I'm going to be using

this one okay again you can enable and

disable the volume game object to see

quite the big difference that

post-processing makes if you ever want

to make your game look quite a lot

better always make sure that some post

processing alright so like I said this

looks really good I like it now before

we go to the next lecture let's just

clean this up so let's get rid of all of

these objects so the counter cabbage

tomato and so on let's get rid of all of

them except the four so let's leave the

four and get rid of all these alright so

here we have our nice empty scene let's

just save our scene and let's get ready

for the next lecture

hi there this is a quick intermission so

how are you doing are you enjoying the

course so far are you having any trouble

with anything is there something you

didn't understand if so remember I'm

always active in the comments answering

all the questions so if there's anything

you need some extra clarification go

ahead and ask and I'll do my best to

help also remember to check out the pin

comment YouTube videos cannot be updated

so for any notes or comments I'll put

them in the pin comment and definitely

check out the website page for this

course as people ask more and more

questions I will keep that page updated

with any frequently asked questions for

every single lecture so that way you can

see what others have asked and learn

from them and you can also download the

project files for each lecture so keep

that page open on a second Tab and check

it every time you start watching a new

lecture I really hope you're enjoying

the course and I hope you've already

learned quite a few things go ahead and

hit the like button and subscribe to the

channel if you haven't already

okay so let's go to the next lecture

hello and welcome I'm your kudmaki in

this lecture we're going to begin

creating our character let's make a nice

character controller so we can move our

character in the world

okay so first let's begin by creating

the character game object

and now usually most beginner tutorials

will tell you to just right click go

into 3D object and create something like

a capsule that way you would have the

game object with the visual included

however for a good project structure and

good organization you should only

separate the visuals from the logic for

example here in let's say that I don't

want my capsule exam like this let's say

that I want my player to be a little bit

more skinny to do that I would have to

modify on the scale on this game object

so put it maybe on 0.7.7 so something

like this basically by doing that by

modifying the visual I also modified the

scale on the actual player game object

having a non-uniform scale on a logic

game object that can cause all kind of

problems with any kind of logic

component also I would prefer to have my

character on the floor but if I put it

on yf0 notice how the character is half

underneath the floor so if I were to use

this method I would have to apply some

kind of offset in order to make the

visual above the floor so that would

require rearranging all the logic to

work with an offset on the Y position so

because of those reasons and many more

you should not Place both the logic and

the visual on the same game object

instead you should separate them so

let's get rid of this and instead let's

create an empty game object let's name

this the player

let's put it on zero zero zero okay and

now inside of it now inside let's create

let's say a capsule now in this one we

can easily scale this to get any size

and shape you want so for example 0.7.7

then since the visual is a child of the

game object we can also easily offset

this so let's say you put it up by about

one unit so with this we can position

the visual so that basically the player

game object is over here on zero zero

and the character is above the floor so

we don't have any weird offsets this

will make all of our logic much more

simplified

and on this empty Parent Game object we

can attach all of the logic components

we want and then in the child visual we

can either replace whatever visuals we

want so as a general rule you should

always try to do this only separate the

logic from the Visions in your game

objects

okay so with that we have the player

game object now let's make our character

controller script

and before we do let's keep things once

again organized so before we do let's

create a brand new folder so let's right

click on the assets create a brand new

folder call it scripts and now inside

let's right click and create new c-sharp

script called the player wait for the

code to compound then select the player

game object and attach the script again

remember logic components go on the

parent game object not the channel

vision so the challenge visual this one

only has visual components and the

player this is the one that actually has

the logic components so let's open up

this script

okay so here's our first c-sharp script

like I said I'm going to assume you know

the absolute Basics go watch the c-sharp

basics video If you haven't seen it yet

so I won't assume that you know what is

a function what is a variable what is

start and update so pretty much the

absolute basics for a character

controller we first need some input from

the player and for that EMT actually has

two methods you have the Legacy input

manager and the new input system

basically the Legacy input manager is

super simple and very easy to use so

this one is perfect for quickly

prototyping and the new input system is

extremely capable with tons of features

but it's also a bit more complex so what

I do is while I'm doing a simple demo or

testing out a new prototype by just

using Legacy input manager but when

making a more complex project like for

example my sim game then at a certain

point I refactor my code to use the new

input system so here I'm going to teach

you both as well as teaching you how to

refactor code which is an extremely

useful skill so let's first begin by

using the Simpson Legacy input manager

we want some basic was movement to move

our character and we're going to need to

run that logic on every single frame so

let's do it on update and let's actually

get rid of the code that Unity writes by

default let's start coming from scratch

and let's get rid of this just close

okay so here let's start by writing

private void update and now here very

important if you're a beginner make sure

that update is written exactly like this

if you write update with lowercase if

you do this then it won't work the

function will not be calmed

automatically I'm pointing this out

because I have seen a bunch of comments

from beginners wondering why their code

doesn't work and it's as simple as this

with a lowercase Unity will not call

this automatically it needs to be

exactly perfect so again if you're a

beginner make sure you write the code

exactly the code is case sensitive so

this is very important

also another note you saw that the code

that Unity wrote by default when we made

a new script it just had void update it

did not have the private keyword private

is what is called an accessor you have

private then you have public and then

there are some more advanced ones

secondly you can omit the accessor and

in most cases it will default to private

however in writing good clean code you

should be as explicit as possible there

should be no room for misunderstandings

so while technically you could emit the

private you should always include it to

make your code easy to read and easy to

understand

this one is the first of many clean code

rules that I will teach you during this

course like I said all of the code that

I'm writing here is on the same level of

quality that I use in my own

professional games I'm not going to

teach you bad practices like so many

beginner tutorials do so always be

explicit always include the accessor

okay so we have our update Running code

on every single frame then to test if a

key is being pressed we just go inside

input then over here we've got two

functions so we have get key and get key

down

both these functions were turning Boeing

so that's how the true or false the

difference between them is that get key

down this one only returns true for a

single frame when the key is pressed

whereas get key this one stays true for

as long as the key is held down for

example for an action like jumping you

just want to know when the player

presses the button so for that one you

would use get key down however in our

case for a character controller we want

to know if the key is being held down we

don't want just one frame but always

so for movement let's make sure we go

with get game

then requires a key so let's write our

key code and then choose the key let's

say we want w

and then let's just put this inside and

if just like this okay so here we have

code we want to run while holding down

the down key let's do a quick test just

to verify everything is working

perfectly and for testing we can use a

super useful debug.log this one lets us

print a message in the console someone

said One log here just say something

like pressing and then let's also do an

else and if else let's do a debug.log

and just do a dash okay so here is our

very basic script let's make sure to

save it so Ctrl s then back in unity

over here make sure you have the script

attached to the player game object and

now we can test and now down here on the

console we can already see dashes so I'm

not pressing anything also like I

mentioned in the setup lecture if you're

seeing just one message then maybe that

means you have over here the collapse

Target if you talk on it and look how it

only shows one message but then over

here on the right side it says the

number of messages personally I prefer

to always keep it untoggle so I can see

every single message also over here on

the right make sure you have info

messages visible if you untangle this

and you don't see it so make sure this

one and actually both of them make sure

all of them are enabled okay so we're

seeing a whole bunch of dashes and one

more note if over here these chromebars

stop scrolling so right now you can see

it's stuck up instead of being down

there so if that happens one is easy way

to reset that is just click over here on

clear and it goes back into AutoZone

okay so we have the dashes I am not

pressing anything now as I press yep

there you go there's a message if you

don't see it make sure the game window

is in focus

so selective game View and click right

here on the middle to make this one the

focused window then if you press the

down key you should see the message and

if I Let Go yep there it is and I stash

okay great so all the basic logic is

working back in the code here now that

logic is working let's get rid of the

else here

and let's set this for all the other

keys so let's copy paste this so we're

going to need w a s and D so let's make

all of these

okay so we have our inputs let's also

get rid of the logs we don't need this

all right so we have all of our key

presses now let's construct a vector

with our inputs and since we're just

going to have two axes

the double s that is forward and

backwards and this one is left and right

so just two axis

so because we have just two let's use a

vector two and let's call it the input

vector

let's construct it so we'll do a new one

and start off at zero zero okay

then over here the logic is pretty

simple so when we press W then let's go

into the input vector and set the Y to

pause one

then when we have an S we want to go

backwards so put the Y on -1 for the a

we want to go left so that's an x on the

minus one and finally for the D that is

an x on plus one okay so with this we

have our correct input Vector let's do a

quick log just to test so debug down log

on the input vector

okay so let's test all right so we can

see in log zero zero okay makes sense

now if I press W yep we've got an 1 on

the Y if I press a we got minus one in

the X press D plus one press s and minus

one okay great so everything works

except we also need to be careful about

one other thing if I press both W and D

with this look at that the vector is 1 1

which is correct that's exactly what it

is then except the factor one one

actually has a bigger magnitude than

just one vector if we leave it like this

then the character will move faster when

moving diagonally versus when moving in

just one direction for our input Vector

we really want it to be normalized

meaning we wanted to have the same size

regardless of the combination of keys

that we're pressing so back in the code

here after calculating the input vector

and let's simply normalize it so we go

into the input vector and we set it

equals to input Vector Dot normalized

so this will normalize our input Vector

let's see and over here if I press

doubly you've got one press s minus one

okay so all those work now if I press

both W and D if there go now it says

0.71 when you combine both these I need

the math these do end up with a

magnitude of one so with this our

character will move at the same speed on

both diagonals and straights okay so we

have the input Vector on correct now

let's actually apply some movement for

that there are many ways of making a

character controller for example you can

decide to use physics or not over here I

want to keep the game simple so let's

not use physics instead let's just move

the player transform directly over here

we have our input Vector okay great now

we want to apply this to our character

position so first we access the

transform

this one refers to the transform where

this script is attached to

this script was attached to the player

so this is going to refer to the player

transform then we want to modify the

position so let's access the position

and now for moving we don't want to just

assign it if we do something like this

like this the player would never leave

the center of the world he would always

be near zero zero so instead we don't

want to just assign it but instead we

want to add onto it now if you're a

complete beginner and you don't know

this syntax then this one is exactly the

same as this so transform dot position

equals transform dot position plus input

vector so both these little lines are

doing the exact same thing personally I

prefer to use the shorthand I find that

equally readable and more compact okay

so we have this and we add our input

Vector to the transform position except

we can also see a really nice error

basically it's telling us that we are

mixing two types our input is a vector

two where we only have an X and Y but

transform that position is a vector 3

meaning it has an X Y and Z one simple

solution is to cast our input Vector

onto a vector three so we just convert

this from one type into the other one

and yep we don't have the error so let's

test and now if I press W any of the

character does move Let's ignore the

massive speed for now so it does move it

does seem slightly correct except you

can obviously notice that it's not

correct we are moving on the x-axis on

left and right that is correct but then

we are moving up and down instead of

fourth and back basically we convert the

effector 2 directly into a vector three

so we are moving on the X and Y axes but

in our 3D game we really don't want the

characters to fly so instead we want to

move on the XZ axis so back in code here

instead of directly casting this down

into a vector 3. let's construct a move

to your vector similar to Vector three

let's call it our move there for our

move Direction and over here we

construct a new vector3

and basically we're just going to assign

the input y to the Zenon here so first

of all for the X7 is correct so input

vector.x then for the Y let's leave this

one on zero and finally let's use the

input vector.y as I said on the Move

direction also now at this point you

might be questioning if we're using a

vector 3 here why don't we also use a

vector 3 appear and then just assign the

Z directly that's certainly a

possibility and for making a super quick

prototype I might even do that myself

but the proper answer to that is once

again all about writing good clean code

the input logically only has two axes

there's no z-axis on your keyboard so

logically it makes no sense for the

input to have three axes and beyond that

you should keep the logic separate so

you should first get the input and then

actually move the object we're going to

see the benefit of that separation when

we refactor this code to work with the

new input system doing that will in turn

make enabling Gamepad joystick support

super easy because we have the input

Vector separated from the actual

movement some of that to say and let's

do things properly let's keep the input

Vector separate from the movement Vector

so we just translate the X Y onto X end

and then we just apply this into our

transform position

okay so let's test so now if I press the

right turn left and press W and S and

there you go okay great so it is indeed

moving Left Right forward and back okay

great so it is working but as you can

see it's moving insanely fast you might

think the issue here is just applying

some sort of movement speed multiplier

except there's actually one sneaky issue

here on the game view on the top right

corner we've got a stats button and over

here we can see a whole bunch of things

specifically we can look at the frame

rate we can see that it's running at 144

frames per second over here on the left

side on this button I have vsync enabled

this will cap the frame rate to the

monitor's refresh rate so that is why

I'm seeing 144 Hertz I can overhear

disable vsync and the upload that goes

all the way up to 700. basically now the

game is running as fast as my computer

can run it and if I press the movement

keys and look at that now it's moving

even faster

now I've completely lost track of where

my player is this is not what we want we

don't want the player to move at

different speeds depending on the frame

rate we want it to always move at the

same speed regardless of frame rate so

when you do any kind of movement Logic

on an update you always need to make

sure to multiply by time dot Delta time

what this variable contains is the

number of seconds in Labs since the last

frame for example let's unlock to this

we no longer need the input Vector so

let's unlock just the time that down to

time okay so we can see there there's

basically telling us how many seconds it

is taking to render a single frame once

again note how I have vsync enabled so

I'm running at 144 frames per second and

now if I disable it let's see what

happens to that number so if I disable

and you have a look at that that number

is now much much smaller and the game is

now running much much faster so by

incorporating this value into our

calculation we are going to be taking

into account the frame rate

thus making sure that movement is always

frame rate independent right now with

this frame rate if I move you can see

I'm moving at this speed and now if I

enable vsync change the frame rate and I

move and I'm still moving at the exact

same speed

okay that's great except obviously it's

not exactly great it's moving way too

slow so let's also incorporate a

movement speed now for this once again

most beginner tutorials will teach you

to go all the way up here and find a

public float move speed

maybe they found it to some villain like

7f something like that

then you have this field and then down

here you simply use it in the

calculation so movement here move

multiply it by move speed and by time

dot time so this is what most tutorials

will teach you by making it public up

here what you're doing is you're

enabling access from the editor so if

you go over here in the editor over

there on the player we can see the move

speed variable we can see this exposed

and we can modify it this makes it

really easy for testing and for

iterating upon the value even while the

game is running

so the game is playing I can move and I

have this move speed now I can modify

this and yep now I got a different move

speed so I can use this to quickly to

rate and find the perfect value

so it's great to have this variable

exposed in the editor and this feature

is indeed the reason why most beginner

tutorials will teach you to make it

public it's so you can see it in the

editor that is indeed a very valuable

thing being able to easily iterate upon

important values is always very useful

however when you make something public

when you do that you don't just expose

the film to the editor you are exposing

it to every other class in your entire

code base so some other class could

access this field and set the player's

movement speed to something like zero

and you would have no idea that was

happening because the issue would not be

on this code right here I have an entire

video on this subject why you should not

make everything public this is an

extremely important topic to know about

this one tiny change will massively

improve the quality of your code

definitely go ahead and watch that video

to learn why such a bad thing and make

sure you don't do it so to avoid all

kinds of problems you should never make

films public so very quickly the obvious

alternative is make it private making it

private means that only this class only

the code in here only this can modify

this film so you know for certain that

no other class can ever modify this

however making it private also means the

editor cannot modify this film so we've

lost our very useful iteration approach

so what we can do to expose it just to

the editor is to keep it private and

then we add the attribute serialize

field

this way this field is still private

meaning that it can only be modified by

the code inside the player class but

with this attribute over here in the

editor yep we do have an editable field

so only the code in that class in the

editor can modify it nothing else can

touch it nothing else can read or write

which is exactly what we want one of the

main rules in writing good clean code is

minimizing complexity and one of the

easier ways to minimize complexity is

simply to minimize axis by making this

feel private we are minimizing

complexity because it doesn't matter how

complex our game is maybe our code base

is a thousand classes long it doesn't

really matter because only this class

can never touch this field so if we have

a bug related movement speed we know for

certain it has to be inside this code

and nothing else so we minimize the

things we need to keep in our head which

is always a very good thing okay so with

all that said we have our movement speed

and down here we are incorporating it

into our calculation just with this we

have our character working with a

variable movement speed and by using

Delta time we have our movement

correctly being frame rate independent

so here's our character and using the

keys I can walk around and yep the

character moves in any direction so we

have movement only working while using

the Legacy input manager like I said

we're going to learn how to refactor our

code to use the new input system

learning how to refactor is an extremely

important skill to improve your own

programming skills it is something that

you should always do when necessary it

will massively help you improve the

quality of your code

so we're going to do that but before we

get to that let's actually do something

a bit more fun and add some proper

visuals and animations to our player in

the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to replace

our boring capsule visual with a nice

proper character mesh okay so in the

included assets project files over here

if we go inside the prefab visuals we

see a nice player visual let's position

it inside the player game object so

let's drag it inside again because we

separate the logic and visuals this is

going to be pretty easy we don't need to

modify the parent game object at all we

just dropped the visualize this channel

that's it also again very important make

sure the visual is over here on low

composition zero zero zero only the

parent game object should move the

visual itself should never move if you

notice some weird positions as your

player moves and rotates always check to

make sure that the channel visual is on

zero zero zero okay so with this let's

delete the old capsule delete it okay so

here we have a pretty simple but really

nice character visual it's really just

two spheres stacked on top of one

another with a bunch of eyes very simple

for the visual itself the material is

using just a solid color so here it is

inside the assets material you can see a

bunch of player bodies with different

color these different colors they won't

be used in the upcoming multiplayer

video basically each player will have a

different color also by the way if

you're a complete beginner here's a

quick lecture on materials these are

materials and if we call it select we

can see a bunch of sets related to that

material basically the materials have a

Shader and then a bunch of properties

now the Shader is the actual code that

runs on the graphics card that says how

an object should be rendered by default

you have a whole bunch of included

shaders we're using the universal render

pipeline so you should mostly be using

the ones inside the urp and by default

you probably want to be using the

standard light Shader then of course you

can also build your own custom shaders

one excellent tool for doing that is

shade graph which I have covered in

detail in a previous video it's a fully

visual tool that you can use to make

shaders without having to write any

shutter code it's a great tool I've also

made a bunch of tutorials on all kinds

of effects you can make although right

now we're not going to be using custom

shaders we're going to do that later on

the course but for now we're going to

stick with default light Shader so

materials have a combination of shaders

and the properties on that Shader for

example over here for the phone light

sharing you can see that it has over

here based map that has a counter field

this is what you can change to apply a

different color to your player also as

to how you apply a material to an object

over here on the player visual you can

see the objects are made up of a sphere

so this is the mesh and then the mesh

render this is the one that has the

material so both these are what stores

the shape as well as the visual for the

object the mesh is just a 3D shape but

just by some of the mesh filter doesn't

actually render anything so it needs a

mesh render which needs a material

attached to it so for example over here

on the hierarching let's right click on

empty space and let's create a brand new

Cube just to see it so if there you go

it does create an object and as you can

see it has a mesh filter and a mesh

render now to apply a different material

you can click on this little circle icon

and it shows you all the materials in

that project alternatively you can grab

the material directly from the project

window so for example the player body

just grab it and drop it in there or you

can also drop the material over here on

scene view as you can see as I Mouse

over different objects it applies that

material to a different object although

note that only works over here on scene

view it does not work on game view so

this basically sets the material over

there on the object right now one more

very important thing on materials if you

have multiple meshes only using the

exact same material and then you modify

the material it won't change the vision

while all meshes using that material so

for example if I modify the color here

put it on something different there you

go all three instances all three objects

that are all using the exact same

material they all update to the new

color if for example you wanted the head

to be a different color from the rest

then you would just create new material

so you can right click on the project

window let's create a new material then

you can give it a name give it colors

use a different shade or whatever and

then use this one for something

different so that's pretty much the

basics for materials and by the way if

you're a complete beginner and you have

questions remember to post them in the

comments and I'll do my best to help

like I said I want to keep this video

moving I'm trying to teach as much as

possible while still keeping the video

reasonable length so if you need any

further clarification on anything

specific just go ahead and ask in the

comments okay so when materials are out

of the way here we have our player with

visual let's just get rid of our Cube

okay and just with this if we test and

yep over here we already have a nice

player visual walking around okay great

except the player isn't actually

rotating ideally the visual should be

facing the walking direction so if I

walk down it should be rotated to face

down so let's have that doing that is

actually going to be pretty simple let's

go into our script here we are on the

player script and over here we already

have the movement Direction so we're

going to use this in order to make sure

to rotate the game object to face this

move Direction and for rotating and

transform there are many many ways to do

it one obvious one is to modify the

transform dot rotation however this one

as you can see works with quaternions

for me even though I've been doing Game

Dev for over 10 years I still find

quaternions quite a bit confusing so I

normally don't use this method another

method is to modify the transform dot

Euler angles this one is much more

intuitive and makes more sense to me it

works with regular Euler angles which is

much easier to understand if you don't

know that name it really just means the

angles that go from 0 to 360. then for

another method you can also use the

function transform Dot and look at this

one makes a transform look at a certain

point so it can be a transform Target

can be a vector three for one position

and anything like that so this is a very

useful function we could calculate a

point right in front of our move

Direction and look at it or finally the

method that I personally like to use for

this specific purpose which is just

modify the transform dot forward this

one has the normalized vector

representing the foreign axes and

importantly you can get it and you can

also set it so you have both read and

write you can read it to get the current

transform for it but you can also write

to it to essentially rotate the

transform so we can just assign this to

our forward Vector also by the way you

also have transform dot up and transform

dot right both these work exactly the

same way for example transforms are

right this one is extremely useful for

2D games but over here we're working in

3D so we want to transform that forward

and all we need is the forward Vector

which is really just in move Direction

so let's set this one equal Z move there

okay so just like this it shouldn't

really work let's also just clean up the

log we already need to see the Delta

time okay so let's see like this okay

here we are and as I move and you better

go and look at that the player object

does indeed rotate to face the move

Direction okay so it's already looking

great all right awesome however it also

looks a bit odd with how it's instant so

I move left and right look at that it

instantly rotates so there's no

smoothing nothing it's way too janky so

let's add some nice simple smoothing and

for that let's use a really awesome

really useful math function called lerp

it helps you interpolate between two

values I made a quick video showcasing a

bunch of uses for it you can alert

floats Vector 3s quaternions or just

about anything it's really perfect for

making some smooth movement or smooth

rotation so for that we can access the

function inside the vector 3 class so we

can find an alert then here we actually

have two options we've got learn this

one interpolates and we've got slurp

this one interpolates but with a

spherical interpolation basically if

you're dealing with rotations like what

we have here then we want to be using

slurp whereas if you're dealing with

just positions and you want to use so

here let's use slurp this one as you can

see takes an a a b and a t like I said

this interpolates between A and B based

on T so for example if T is zero then it

won't return the value a if T is one

then it won't return to Value B if C is

0.5 then it won't return the point in

between A and B if you want to learn

some more about interpolation and the

math behind this then I highly recommend

you look at my video on splines splines

are basically just a whole bunch of

merps put together so anyways over here

we can add some smoothing to our

Rotation by just using the current

transform.ford as our a

then for the B this one is our Target so

let's use the move there and finally 14

let's use time dot Delta time meaning

that with this over time the character

won't rotate towards our Target movement

Direction so just with this let's test

so here if I move to the right and you

have a look at that it is indeed

rotating it's way too slow but yep it is

rotating smoothly all right so let's

just add a bit more speed so over here

let's just find a float for the rotate

spin let's put it at some like 10f then

we just multiply it to times that down

time multiplied by our speed let's see

and move any up there you go look at

that much much better okay great so as

you can see everything works as I move

the character does rotate to face the

move Direction all right great so here

we have our character with a nice visual

all rotating to face the move Direction

now next step is we want to add some

nice animation so let's do that in the

next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add some

animations to our player character now I

have already included some pre-made

animations with a pre-made animator over

here inside the Asus folder but let's

first do it from scratch so you'll learn

how to do it first to animate we're

going to need the animator component if

we go inside the player visual game

object once again remember all the

visuals go on the visual game object so

for adding the animator component we

want it on the visual and not on the

logic component so anyways over here as

you can see by default I already attach

it with the assets included but let's do

it from scratch so let's remove this by

default now let's add a new component

let's go on an animator also one very

very important thing here it's the

animator component not the animation

component these QR can only difference

the animation component this one is

actually related to unity's Legacy

animation system from a very long time

ago it's only here pretty much for a

backwards compatibility and for super

simple use cases so most of the time

make sure you're using the anime tour

component okay so to drive this animator

component we need an NM troller let's go

into our project files and let's create

and create a brand new animated control

let's call this my player animator then

let's select the player Visual and just

drag the controller on there okay again

if you have issues then you cannot drag

the animator onto the film make sure

you're using the animator and not the

animation component okay so with this we

have assigned our animator controller

now let's double click on it to open the

animated window and if you don't see it

then go into window then go into

animation and open up the animator

window and also if you still don't see

anything that maybe you might have some

issues with your layout if that's the

case then go on to the top right corner

layout and go back into the default and

then back into your own layout and

finally if you still don't see anything

on this window if you don't see defontes

make sure you have the object selected

in the hierarchy so with that you should

be able to see these states so this is

our animator controller now I have a

really detailed overview of the animator

and the animation windows in my ultimate

unity overview course so you can go

watch those lectures for some really

in-depth explanations about everything

this does basically the animator is a

state machine so you have various States

and you can create transitions between

each state by default you have these

three special States there's the entry

State exit and any state these are used

for making transitions but we don't

really need to worry about them just for

now first let's just make a basic new

animation and for that the easy way to

do it is to open up the animation window

so let's go up top into window go into

animation and open up the animation

window so here it is again that's a

different window that's animation not

anywhere and for me for this window I

like to dock it down here so there's a

nice timeline so I think this is good

okay and now if we select the object in

the hierarchy that has our animator then

we can see the text here so to begin

animating we've got a nice button to

create an animation so let's go ahead

and click on this and now let's give it

a name for now let's first make the

iPhone animation so let's just call this

Idol and name just like that we have

created an animation you can see the

animation window down here has changed

we now see a nice timeline showing the

time and also on the animated controller

you can see the new animation was added

as a brand new state so a new state was

created and if you click to select it on

the right side in the inspector you see

the motion so the actual animation

selected and you can also see that

there's an arrow pointing from the entry

onto the unknown state so that means

this one is going to be the default

State when the animated controller

starts it won't start playing right on

this state let me just point out one

more thing related to animations so on

the project window we can see yep here

is our animation that we just created

and you can see the inspector unlocks

just like this now if your inspector

looks differently that might be because

you accidentally created the Legacy

animation that has to do with the

previous animation system that I talked

about the one that is Legacy that should

really no longer be used so if you see a

different inspector then a quick way to

fix it is to click on these three dots

on the inspector these three dots then

you change the inspector into debug

inspector and over here you see a toggle

on foreign legacy so for the animations

that we want to use right now we do not

want to be using Legacy animations so

make sure this one is untoggled if in

our case is toggle just untoggle it then

go back into the normal inspector and

now yep it shouldn't look just like this

okay so we have our animation and now

it's on our animator controller now it's

actually make an animation so let's

select the animation window though and

again let's make sure to select the

objects and let's select the player

visual game object so here on the

animation window we see this nice little

red button this one enables or disables

recording so if you click on it you can

see yep the timeline is now red meaning

that we are now recording and now we can

do anything to any channel objects and

it won't record any changes we make now

note what I said that's very important

it needs to be challenged objects if you

select for example the apparent game

object then all of a sudden it stops

recording so you can only animate child

objects so let's select the player

visual let's enable recording then let's

expand the player visual let's make sure

that our timeline is on zero so drag it

all the way to the left and now for

example let's grab the head object and

let's move it just a tiny tiny bit

basically just move it enough in order

to make sure that the position over here

is in red meaning that we have recorded

a keyframe then let's drag the timeline

by a little bit let's go over here to

frame 30. this one is actually going to

be half a second and soon to be that

because over here on the samples this is

the frame rate for the animation so at

6C that means we have 60 frames this

makes one second so 30 frames would be

half a second you can also zoom out by

scrolling over here or dragging the

handles down here so let's go into 30

half a second and on this one let's move

the head by a little bit something like

this as you can see down there we can

note that I record the new keyframe and

now if we hit on the play button we can

preview the animation any upon like that

that does do exactly that so it starts

off down and then moves up okay so

that's great but we don't want to snap

back so let's actually add another

keyframe right at the end so let's stop

playing the animation and to make sure

we have a perfect Loop let's just click

to select the keyframe let's press Ctrl

C then let's go down into the one second

Mark let's press Ctrl V and there you go

there's the exact same keyframe so now

if we hit on play the other go we have

our nice seamless Loop so the head goes

up and down and repeats forever alright

awesome okay so that's great now let's

also do one thing let's also record a

keyframe on the body however we don't

want it to move at least not in this

idle animation we just want to have a

static keyframe so let's select the body

and let me actually move it a bit to the

side just to make sure to record and now

manually we can modify things over here

here to modify the actual keyframe data

so on this one I don't want it to move

so let's put it all the way back at zero

just make sure we have a nice keyframe

recording now the reason why we are

recording the body position even without

moving it is because the wonk animation

will indeed move the body but when we

get back to idle we want the body to go

back to this exact position so that is

why we need the keyframe here okay so

that's done so we can stop recording so

let's click on the red button again okay

great by the way one more note to make

sure that the animation Loops go into

the project window and over here select

the animation and make sure on Loop time

is enabled it should be there by default

okay so the animation is set up and if

we unlock in the animator it's already

the default set so if we hit point we

should be able to see the anal animation

playing non-stop so let's hit play and

if there it is the anal animation with

the head moving up and down everything

works perfectly alright awesome okay so

next up let's make a wonk animation now

for me when making an animation that is

based on another one I like to actually

duplicate it instead of starting from

scratch so over here on the project

window let's select the anal animation

and let's duplicate it so Ctrl D let's

learn name this one to the wonk

animation and now if we select the

player Visual and then we go into the

animation window over here we see a nice

little drop down menu for all of the

animations except right now we don't see

the wonk animation we only see the idle

animation that is because this menu only

shows animations that are attached to

the animator so first we need to add the

animation onto the animator component

and how we do that is actually super

simple let's just open up the project

window and just write the wonk animation

and drop it here that's it so with this

we have attached a new state to the

animated controller and now if once

again we select the object in the

hierarchy go into the animation click

the drop down menu any up now we do see

the wonk animation so let's click to

select this one and now for this one

let's make the animation so let's look

in scene View and make it bounce just up

and down so I'm going to enable record

go back here and for the body this one

already has a keyframe so let's go up

here move it a little bit and then copy

the keyframe put it the same one at the

end something like this so there you go

just goes up and down once actually

input it offsets it looks a bit better

so something like this by the way in a

bit we're going to replace these

animations with the ones that I made

previously so don't worry about making

the animations perfect unless you want

to do that okay so there you go that's

the animation although for walking

should be much faster so here's a quick

animated tip this top bar here lets you

select all of the keyframes within a

certain time so if I click the select

note how it selects both those keyframes

and also if you click and drag once on

top of here you can select multiple

keyframes so for example to select

everything just click and drag to select

all of them and now you see these nice

little vertical bars so if you click on

those and then you drag them you can

basically modify the time of all the

animations and everything matches up so

for example let's make this one super

fast let's put it just 20 frames there

you go now it's a much faster walking

Mission okay great let's click on the

right to stop recording all right and

back in the animator so over here we

have both animations and now what we

need is to make a transition going from

idle into wonk otherwise the wonk

animation will never play so how we make

a transition is also super simple let's

right click on the I don't say let's

make a transition then now we have a

nice little arrow under the mouse and

now if we go into the wonk and click on

it there you go we have a nice

transition now we can click on the

transition itself to select it and over

here in the inspector we see a bunch of

transition options so let's expand the

settings yep there you go everything now

like I said I covered all of these

options in a lot of detail in my

ultimate TNT of recourse so if you want

to learn more go watch that here on

let's just learn the basics for how to

achieve our goal and making a simple

player animator the important one is

over here the exit time basically if

this one is toggled then this transition

won't be triggered automatically meaning

it won't play the outline Mission and

immediately transition into the walk

animation so for example if we hit play

and look at it quickly if there go

there's the idle any of transitions into

wonk and now it stays there forever okay

so that's good but not exactly what we

want we want the Wonka mission to only

play When the character is walking and

when it stops we want to go back into

the idle animation now for that we need

to use animator parameters so back in

our animator on the top left corner we

see something called layers we don't

need to worry about that for now and

then next week we see parameters then we

can click on the plus button or to

create the brand new parameter and you

can see all the various types that we

can create now for wonky we want

something that we can set to either true

or false so let's go with a nice bullion

and for name let's go with is wonky

again pay very close attention to the

capitalization this is extremely

important just like code is walking is

different from is walking so make sure

the capitalization is perfect okay so

with that we have our nice parameter now

let's click on transition going from

idling to wonk and now let's untick exit

time we don't want this transition to

trigger automatically and as soon as we

do we see this nice little warning

basically it's telling us that this

transition will never happen so over

here we have the nice conditions if we

click on the plus icon we can add some

conditions and for this one we want this

transition to happen from idling to walk

when the parameter is walking is set to

true so that's it this is our transition

now let you see the reverse so let's

right click on the wall make Transition

go back into Idol let's click the select

transition get rid of the exit time and

conditions when is Walking is set to

false okay so just like this our basic

animation logic should be working so

let's test so here we are and the

character is playing the online Mission

by the way you can look at the end

better while the game is running so let

me just drag the animator window just

drag it and put it on the side of the

game view so we can see both at the same

time okay great and right now note how

it's not updating so there's nothing

moving over here on the animated

component that is because like I said

you must select the object so on the

hierarchy make sure you select the

player Visual and you have there go now

you do see that updating so make sure

the object is selected in the hierarchy

and over here we see a nice little

progress bar showing the Adeline Mission

constantly playing in looping okay great

another important thing is over here the

parameters you can manually change the

state of these while the game is running

so for example if I click it's going to

trigger the is walking parameter which

should trigger this transition and

should go into one so if I click and if

there go transitions into the wonk

animation and now yep it is playing The

Walking animation and if I click to

untick it look at over there what

happens untake and there you go

transitions back into idle alright

awesome so as you can see we have

overall logic working we have the

animator with both of our states and by

changing this parameter we can change

which animation is playing now of course

the goal is not to trigger this manually

by clicking on it but rather doing it

through code but at least for now we

know that our animator is fully set up

again if you want more detail on the

animator and animation windows and

everything related to animations then

check out those lectures in my ultimate

TNT overview course and also later on

for more advanced use cases I have video

on the animation rigging package this

one is for more advanced use cases for

making Dynamic procedural animations

it's really fun so definitely check it

out but only after finishing this course

that one is a much more advanced duel

for now let's continue here so we want

to trigger our parameter but do it

through code and again here we have yet

another clean code question technically

we could add that code directly over

here on the player script we could just

grab the animator component and change

the parameter and in this case for this

very simple game that would actually not

necessarily be a very bad approach since

the game is so simple with so few

animations but like I said I want to

teach you proper good practices so let's

make it properly and actually separate

the animations from the logic for then

let's go into our project right click in

our scripts folder create a new c-sharp

script let's come with the player

animator let's select the player visual

game object and attach the component

okay so now here first let's grab the

animator now one approach is like we've

seen we could just make a serialized

film and and drag the reference in the

editor that's one approach or

alternatively since the animator is

attached to the same game object as this

script then we can just do a get

component both approaches are really

valid so here let's use get component

just to see a different approach so we

just have a field for our animator so

animator and then we just do a private

void awake and then awake lets you get

component of type animator and we set

our animator variable again like I

mentioned very important make sure you

don't mix animator and animation these

are two different components we want the

animator okay so with this we have a

reference to our end meta component and

now how we modify the parameter is

actually very simple we just access the

animator and then we have a bunch of set

functions you can see we have one for

each type so we've got a set bone set

float then down here a set trigger set

Vector so function to set any parameter

type now we made the Boolean so let's

use the set bone and this one as you can

see takes the name for the animator

parameter by the way strings are a

horrible horrible way of identifying

things but suddenly this system really

does require strings to identify the

parameter we want to change change if

you're wondering why strings are bad for

identifying things the reason is because

it's very easy to make a mistake for

example if you use is walking here then

this won't work however if you instead

right is walking then all of a sudden

does not work if your right is walking

like this doesn't work like this doesn't

work and even though it doesn't work it

will also not throw any compiler errors

that is because for the compiler a

string is a string it's always valid but

then when the code runs this one is

going to be different than our parameter

which is named exam like this always

remember that strings are case sensitive

so that's one reason why you should

never use strings to identify things

it's very very easy to make tons of

mistakes that are then very difficult to

find out but like I said in this

animator system we have to use strings

there's no other way in order to

minimize our usage of strings one thing

we can do is for example let's define a

constant up here so let's make a private

make it cons for a constant meaning this

will never change make enough type

string and conlet is wonky again refer

back into the naming wrong section for

constants we always use uppercase snake

case so is walking and let's set it with

is wonky again make sure you don't make

a mistake here make sure you type it

exam like you did on the animator then

down here let's use is one and now if

you do make a mistake so if we

accidentally use something different now

we do get a compound error so at least

we have a little bit of protection okay

so this one takes a string for the name

and then a simple Boolean for the value

so this is going to be the value that we

want to set to our parameter now for

this one we want to set to True when the

player is walking and false when it's

not so for that we need to ask the

player what it's doing so let's go over

here into our player class and let's

make a function to return just that so

let's make it public because we're going

to access it from another script we're

going to return a boom and call it is

wonky now over here we just need to

return if the player is walking so let's

make a local field to store that saved

so over here private bone is walking

again note the capitalization for films

we start with camel case whereas for

functions we have Pascal case so these

are different okay so basically in order

to Define if we are working that's very

simple it's just down here we have the

movement Direction so we are walking if

the move direction is different from

Vector 3.0 which by the way Vector 3.0

is just a shorthand for writing zero

zero zero so if the movement direction

is different from zero then we are

indeed walking so we Define that we

update that film on every update and

then over here we just return it okay

just like this and now back in our

player animated component over here

first we need a reference to the player

so let's add it here let's add a

serialized film of type player and we

need to compound this in order to drag

the reference so let's just come without

this line just make sure the code

compounds now here with the code

compound let's write the reference of

our player okay that's it and then over

here for the animator set is wonking

let's go into the player and let's ask

is walking and of course we don't want

to do this just on awake we want to do

it on every single frame so let's do a

private void update and on update let's

do this alright that's it so this should

be working let's test so here we are

starting off as Idle and as I move yep

there you go it is playing The Walking

animation and now if I stop and if there

go back into idle alright Awesome

everything does work perfectly okay

great we can can even look at the

animator to see the state change so here

with both side aside and with the

objects selected in the hierarchy right

now you can see he's walking his phone

so it's on idle and as I move that one

stays true that one goes into wonk and

now if I don't let go if there and go

back into falls back into idle all right

awesome so with this everything is

working perfectly if you're having

issues make sure you pay attention to

the capitalization so make sure the name

you wrote here is exactly the same one

that you wrote here and it's exactly the

same that you're using here alright so

all of our animations are working

perfectly now if you want you can go

ahead and make your own animations or

you can use the ones that I pre-bumped

so in the included project files inside

the assets here we've got the animations

and we've got the player with the idol

and the wonk animations if we double

click on this don't look at it you can

see yep it looks exactly the same so

there's a parameter called is walking in

our transition so everything is exactly

the same just over here let's select the

employer Visual and on the prefab like

we saw we already have the animated

component we just removed that one from

the prefab in order to build it on from

scratch but if you want to use my image

then we can just go ahead remove the

animator that we added and then right

click on this one on the remove

component let's revert back to changes

and there you go here we have our

animator with the player controller so

that's the one in the animations and

just like this if we had on play and

actually over here I found an issue

although in your case there shouldn't be

any issue because I've updated the

assets but this is a good time to teach

you about any issues with animations so

if you select the animation and you

select the animation and over here you

might see some of them in yellow saying

missing basically the way that

animations work is based on the actual

name of the object if it cannot find an

object with the exact same name then it

cannot load the same animation so my

problem is that when I initially made

the assets package I made this animation

and the object was previously named face

and then I renamed it the head so now it

normally loads so if you ever have

problems with loading animations just

make sure the name is perfectly matched

so in my case I can just click in here

in order to rename this keyframe on the

animation and I'm just going to use the

name that I renamed it so head and just

like this yep the animation does play

correctly so it's just a nice quick tip

if you ever have problems with and

missions always remember that the stored

keyframes their own stored based on name

so if you rename the thing in here or

over here on the game object if you're

in a name you're going to have missing

animations but if you make sure the

names match and the animation shouldn't

work perfectly so let's hit on play and

if there go there's the anal animation

and if I move yep there's the nice wonk

animation so everything still works

perfectly because it's only using the

exact same parameter alright awesome so

like I said if you want film free to

make your own animations or use the ones

that I've included for me I'm going to

be using these ones so the ones that we

made just for learning which I created

down here so the multiplier animator and

these animations I'm just going to

delete these just to keep the project

clean so just delete and just like that

okay so now there we have our character

fully working let's quickly handle our

camera

hello and welcome I'm your code monkey

in this lecture we're going to quickly

install cinemachine this is a Unity tool

that makes handling cameras super easy

our game isn't really going to have a

moving camera so this part isn't

strictly necessary but same machine is a

super useful tool so I definitely want

you to learn about okay so let's begin

by installing the package let's go into

window open up the package manager then

up top let's make sure we are in the UNT

registry make sure you're on the all Tab

and now just scroll down until you find

yep there it is send machine okay so

let's go ahead and install this

all right Sunstone so let's close this

and now the way that send machine works

is by creating what is called a send

machine virtual camera so let's go up

top into the game object menu then

scroll down into cinemachine and over

here you can see that we can create a

multitude of virtual camera types now

just by the names you can see how this

tool is insanely useful for example

making a free download camera doing that

from scratch is a bit tricky but with

same machine it is super easy for our

case like I said we want the absolute

most basic thing possible so let's just

create an empty virtual camera okay

that's it this creates a virtual camera

over here in the hierarchy and turn this

object has the send machine virtual

camera component and also importantly

when we added this it also added over

here on the main camera if we scroll

down we can see it has a sin machine

brain component basically the way send

machine works is it works on top of the

main camera so it doesn't replace it it

works on top of it and drives the main

camera so now that we're using send

machine if we try modifying the main

camera game object so there's one over

here if I try to drag the field of view

nope does not work I cannot move it if I

try to move the position nope can't do

it it if I try to rotate it nope that

does not work like I said when working

with cinemachine the sin machine brain

is what drives the main camera so rather

than modifying the things over here on

the camera itself what we need to do is

change them on the virtual camera so

over here we have pretty much the exact

same options that we have on the main

camera for example modifying the fov

over here we've got the lens so we can

modify the fov and if we look in the

game scene as we modify this one yep it

does modify the actual properties on the

actual main camera now this has tons and

tons of options related to everything

the most important ones are all kinds of

options down here for the body and the

aim so this is where the camera is

positioned and where it's looking at

using this you can make a funnel camera

in five seconds it really is insanely

useful if you want to learn about Sim

machine in more detail I have a

dedicated video on it I go through what

all of these options do then I also have

another super detailed video on how to

make a camera system with pan Zoom

scroll in both 2D and 3D and a bunch

more features again all of it using send

machine but in our case we really want

to keep it simple so let's just position

our virtual camera on the same settings

that we had previously so for first

let's set the film review so for a game

we want something narrow so let's go

with just 20. then for the position

let's put it above so zero on the X then

21.5 on the Y and minus 21.3 on the Zen

then for the rotation 46 on the X and

then 0 on the others okay so our camera

is positioned in the exact same position

and if we head on 20 yep everything

still works the same the camera is going

from the same point of view and the

character still works everything's still

exactly the same now since we're using

cinemachine we can easily add some

things on top of this like for example

we can add some noise to our scene

machine camera to make it smoothly move

a little bit this one is a fun simple

effect that can make our game feel a bit

more Dynamic especially in games like

this where we have a fixed overhead view

how we do that is over here on the scene

Mission virtual camera we've got a film

for noise so let's click and let's

select basic multi-channel purlin and

then over here we've got the noise

profile so we can choose one of the

included ones or we can create our own

profile so for example let's go with

handheld normal mild and by the way you

can actually modify these settings while

the game is playing so here it is the

game playing and you can see what this

effect does it adds a nice little wobble

to the camera and then over here at my

student frequency so we can play around

these so you can make it really intense

so something like this that is way too

intense so there you go quite a lot so

for something more subtle maybe put 0.5

and 0.5 there you go just a slight

little movement in the camera so this

would help make the game a little bit

more Dynamic so this could be a fun

effect although actually in my case in

order to make sure that the video

doesn't get way too compressed I'm

actually going to disable this on my end

so just set the channel noise to none

but you can see how easy it is to add

complex camera features when using send

machine and of course when using

cinemachine if you want you can use it

to make your game a lot more unique now

for me I want to design here where the

camera is fixed but let's say for

example you wanted the camera to

actually follow the player like I said

you'll watch that dedicated video tool

and learn all about cinemachine but over

here very quickly let me just show you

how to do that but at the same time

don't bother following this part it's

just to show what scene machine can do

that I'm going to revert back to this

state so first of all for testing one

great thing about scene machine is you

can have multiple virtual cameras you

can have as many as you want and then

the priority and the game object enabled

state is what defines which camera is

actually being used so for example on

this second one let's make it follow the

camera and put the priority on 20 so

that it's above then over here for the

body I'm going to select transposer

let's put it with World space it

requires a funnel Target so let me drag

the player as the final Target and put

it as slightly above and behind Okay so

it's pretty similar as before then for

the aim let me also drag the aim player

Target and just with this it should

already work so if I head on play if

they're going to look at that the camera

is now moving and following the player

so I can move the player anywhere and

yep the camera follows along so as you

can see it's this simple to really make

some complex camera movement doing some

complex camera logic just like this

would require a ton of work manually but

with thin machine it is super easy then

you can even play around with either

priority or enable and disable and there

you go see the machine even transitions

between the state of only your virtual

cameras so as you can see in lots and

lots of things you can make with your

camera very easily all thanks to

cinemachine like I said in my case I

just want the fix overhead camera so I'm

just going to delete this secondary

virtual camera and there you go just

this one on top looking at the player

and looking down with a low fov and Yep

this is the exactly the kind of camera

that I want for my game okay so that's

in machine it's a really awesome tool

for making camera handling much much

easier so this was a quick lecture all

about learning about Sin machine now

let's handle the tests that was actually

left and done quite a while ago let's

finally learn how to refactor code and

implement the new input system so let's

do that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to refactor

our code from the Legacy input manager

onto the new input system so the

simpleton character controller that we

made is working perfectly fine within

Legacy input manager like I said this

one is excellent for making quick

prototypes and demos as you can see it's

super easy to use

but now let's quickly refactor this code

to use the new input system instead also

like I said in the beginning of this

course here I'm going to be focused

primarily on building this game so for

example for any Unity tools that I use

like the new input system I'm going to

cover enough to be able to use a tool

and Achieve our goals in building this

game

of course every tool does a lot more

than just what we're going to use so

definitely make sure to watch the

dedicated videos Link in the description

for example the input system tutorial is

40 minutes long covering everything you

need to know about system whereas here

we're just going to learn enough to know

how to use it so let's refactor this

code to make it work with new input

system except before we work with new

input system let's just refactor this

code so we can completely decoup on the

input from the player class again we

want to focus on writing good clean code

so we should keep all of our input logic

in its own class that other scripts can

access remember the goal with clean code

is to minimize and manage complexity so

every class should do one thing and just

one thing meaning that the player class

should only handle the player and then

the input list should only handle the

input the only reason why I put this

over here in the beginning is exactly to

teach you about refactoring and how it's

a very common thing that you should be

doing all the time this is exactly how I

build my own games I start by making a

prototype and I write the input directly

inside the player class then at some

point I refactor the code to split them

up so don't be afraid to refactor code

it's a Perfectly Natural part of the

Game Dev process and actually a very

very good thing okay so let's make a

script just to manage our inputs let's

make a new c-sharp script call this game

input let's create an empty game object

give it the same name input as always

keep things lean so put it on zero zero

zero let's attach the script and open

okay so here's our script and let's get

everything related to the inputs on the

player for the input we are calculating

the input Vector then getting the actual

inputs from the keyboard and returning

the input vector

so let's put this on the other script so

over here let's make a new function

let's make it public since we want to

access it from the player we're going to

return a vector 2 and let's call it get

movement vector

now here let's really just copy paste

the exact same code that we have on

player so let's copy paste all of this

let's go and paste it here

okay so we get the input Vector we get

the inputs we normalize it and then

return the input vector

okay so that's it super simple also by

the way here we have an interesting

question

which is do we normalize the input over

here or do we do it over here on the

player both options can be valid you can

make it so that the game unplug glass

returns a regular input or you can make

it return a normalized vector you can

use either option but whatever you do

make sure you are explicit so over here

I am going to normalize input inside the

game input class however I'm also going

to make sure to rename this function so

instead of get movement Vector get

movement Vector normalize that way it is

100 clear this returns a movement Vector

as a normalized vector okay great

so now let's use this in our player over

here in our player class we need some

reference to our input class now later

on in this course I'm going to teach you

about the Singleton pattern but for now

let's just do a simple direct reference

again remember don't make it public make

it a serialized film private so over

here

let's make a serialized film private of

type game input and let's call it just

game input

okay so we have this we're going to drag

it in the editor then over here we

simply grab the vector 2 for the input

Vector we simply go into this one and we

get the movement vector normalized and

okay that's it no more errors let's just

make sure to save all of our scripts and

back in the editor let's go into the

player and just drag the reference for

the game input okay so just like this

everything should still work everything

should work exactly the same as

previously Let's test and make sure so

here we are moving and yep everything

still works I can move in any direction

okay so far so good

and what we have done here is

essentially we have refactor our code

and conveniently separate the input from

the player class this is an excellent

thing so again don't be afraid to

refactor code also what we did here of

putting the code in a separate class and

then doing a quick test to make sure

that everything soon works the same as

previously this is exactly what you

should do whenever you do some kind of

reorganizational refactoring in the end

you want to end up with the exact same

behaviors previously just with the code

organized in a different way okay so now

that we have this separate game input

class now we can very easily refactor

the Legacy input manager onto the new

input system so the first thing we need

is to install the package so let's open

up the package manager let's make sure

up here we are in the ENT registry make

sure we are in all and let's scroll down

to find the input system so here it is

let's go ahead and install

okay the package is installed and right

away we see this message basically it's

asking us if we want to enable the new

input system

now you could click on yes but let's

actually go ahead and click on no we're

going to enable it manually so click on

no then let's close this window and now

let's go up here into edit then let's go

into project settings then on the left

side let's go into player and now let's

scroll down expand over here the other

settings tab

and keep scrolling down until we see yep

here it is the active input Henley this

is where you can select which input

system you're using basically if you

click yes on that window it would

automatically set this option to use the

new input system so it would only enable

that one and can only disable the unless

input manager but like I said the lace

input manager is still pretty useful so

normally for me I prefer to enable both

of them so let's go ahead click on both

and this will restart the editor so okay

let's go alright the editor has

restarted so now the new input system is

now enabled okay so the way that this

system works is by creating something

called an input actions asset so on the

project files let's click on the plus

icon let's create something and let's

find the input actions so we need to

scroll down here so click on the little

arrow to go down and find the input

actions creates this file let's call

this the player input actions

okay now let's go ahead and double click

on it and yep there you go out pops out

the input system window basically this

one is where we're going to manage all

of the settings for all of our inputs

also by the way and like I've mentioned

if you're watching this in the future

and for some reason the input system got

a new update and changed this window if

so make sure you check the pinned

comment I'll keep it updated with any

changes on anything in this course so

over here we've got the action Maps then

we've got the actions and then we've got

properties now action maps are how you

can have different maps for example one

action map would be for the player

whilst walking normally and you could

have another one whilst driving a

vehicle then for the individual actions

in each action map and finally the

properties for each action again if you

want to learn about the entire input

system itself in more detail go ahead

and watch my dedicated video on it in

order for this course to not be 20 hours

long I'm really only going to use enough

to make sure that we can achieve our

goal so over here we just need one

action map so let's click on the plus

icon let's name this the player and now

for the actions right away we have a new

action

so let's just rename this one let's call

this action move then with the section

selected over here on the Action

Properties we can select the action type

again in the dedicated video I cover

what all of these mean

for movement we do not want a button we

want movement in multiple directions so

let's go with value then over here for

the control type for this one let's go

with the vector 2 and then let's expand

our action over here we can see our

bindings however we don't want this

default binding so let's actually delete

this one instead let's click on the plus

icon and over here for the type first

for the keyboard and let's go with this

one up down left right composite

so this one adds essentially four

bindings let's go ahead and name this

was

then for the up let's select the

bindings over here on the path let's

click on it then we can either find it

manually over here or click on the

listen and I'll press the W button yep

there you go W then for down let's go

ahead and listen s then for the unless

listen a and for the right let's listen

d

okay great so with this our input as it

is correctly set up one thing you must

never forget is up here make sure to

save the asset you can see this little

asterisk here that means we have unsafe

changes also alternatively there's an

auto save there but for now let's just

manually save the acid okay great

so now let's see how to actually use

this in our code there are many ways we

can use the input system one way is by

using the built-in player input

component so for example on the player

we would add the player input

so you could add this one attach and

input actions asset so this is our

player input actions then over here we

have various behaviors in order to be

able to trigger our actions but in this

course like I said I'm going to be using

the exact same code quality that I used

in my own Steam games so I will not be

using this component so let's remove

this instead I won't be using the native

c-sharp method so what's like the player

input actions and over here on the

inspector we see this nice toggle to

generate a c-sharp class

let's go ahead enable it and for these

films we can leave them all on defense

that's okay let's just go ahead click on

apply

and now it's going to generate those

scripts and compound them okay great

basically what this is doing is auto

generating some c-sharp code and on the

employer input actions we can see over

here yep we've got the generate script

if you want you can even open this to

see all of the source code now all this

like it says here this was all auto

generated so don't make any

modifications here

if you change anything any manual

changes won't be lost when you save some

changes in the input asset so if you

want go ahead and read through in order

to see how all this works but in order

to use it sectionally super simple you

don't need to worry about this script

first thing we need is to construct our

script class that was Auto General so

let's do it over here in our game input

let's make a product void awake and on

awake let's construct it

so let's do a new player input actions

so we construct an object of this time

so we have this although just like this

it won't be active so we need to

manually activate whatever action map we

want so let's go inside and let's go

inside the player so this is the action

map that we created and let's call

enable one okay so just like this it's

really already working all we need to do

is modify our code over here on the yet

movement Vector so for that we're going

to need to access this so let's actually

make this a member variable so private

let's store it up here instead of making

a local variable in here okay

so we have this one and then down here

on the input vector

let's go inside the player input actions

inside the player action map and then we

called it move so we've got this one and

then we defined it as a vector two so

over here we can call read value and

this one takes in the type of the value

now we Define it as a vector two so

let's read it as a vector two and just

like this this returns a vector 2 which

is really going to be our input Vector

so let's put it exactly like this and we

can now get rid of the rest of it all

right so that's it and just like this we

should already have everything working

exactly the same as previously

so let's just do a debug download just

to make sure so let's test so here we

are and the output is zero zero now I

press W there you go plus one minus one

left right and all of the ones in

between all right awesome so we have the

new input system all of it working

flawlessly also by the way over here we

can normalize the input just like we

were doing previously so we do it over

here through code or alternatively we

can also go into the player input

actions and over here there's something

called a processor so you can go into

this action add a processor and make it

normalized so these processes here can

be quite useful I cover the modeling

detail in the other dedicated video but

over here let's stick with making it

through code that works just as well

okay so that's our refactoring done with

that simple change we are now using the

new input system

so you can see how by refactoring our

code to make sure to use the game input

less when we change from the input

manager onto the new input system when

we made that change we did not have to

touch a player class at all the player

class just has the game input to get the

movement vector and does not care what

system he uses to get them so here we

have a very practical very excellent

example of the power of writing good

clean code because we separated things

correctly we managed to change something

completely and not have to make any

changes on any other class

so now that we're using the new input

system let's just quickly see one of the

main benefits of this system which is

easily supporting gamepads and more keys

for example a lot of people like using

ones but some people also like to use

the arrow keys with this system that is

super easy to add so let's go into the

move what's another one let's add

another one up down left right composite

let's call it arrow keys then let's just

put them so let's listen on the up Arrow

then over here we've got the down arrow

then we have the left arrow and finally

we have the right arrow alright so we've

got all the arrows and now we don't even

need to touch any code at all let's just

make sure to save the ascent which again

in turn that is going to Auto generate

the c-sharp class and go into compound

okay so we don't need to touch any code

at all let's just hit on play and now if

I move we're using the ones Keys yep

still works and if I go into the arrow

keys yep also still works alright great

now for another one let's make it for a

Gamepad so I just connected an Xbox

controller and we can see over here on

the log yep the game did identify it so

this is the new input system in action

let's once again open up the input

actions and over here on the Move let's

add another one and this time let's just

make it a regular binding and over here

on the path once again if we want we can

go down here and specifically find some

joysticks so you can find any of them or

once again let's just use in listen now

I'm just going to move the thumbstick on

the controller yep there it is I know if

you wanted you could go specific and

make it just work with Xbox controllers

or you can just use the generic left

stick this will make it work with an

Xbox controller or a PlayStation or

really anything so let's go with this

one and that's it nothing else we need

to do let's just save the asset and

that's it we don't need to touch any of

our code to make our game playable with

a controller so let's go ahead and test

so here we are and first of all if I

move the keys yep song Works move the

arrow keys yep both of them works and

now if I use my Gamepad any up there you

go everything works perfectly alright

awesome so as you can see this is one of

the main benefits of the new input

system it makes handling different

inputs really super easily as you saw we

didn't have to touch our code at all we

just had new bindings and just like that

our game is playable with all kinds of

inputs

so here you can really see just how

powerful new input system is okay so

with this our basic character movement

is working great we can walk around

everything looks great now in the next

lecture let's apply some collisions to

our player

hey again here's another quick

intermission I hope you've already

learned a ton from the course have you

seen the benefits of writing good clean

code has the course already helped you

understand some more advanced concepts I

really hope the answer is yes to both

those remember to follow the website

page as you follow along I won't be

adding frequently asked questions to

every lecture if you ever get stuck you

can just download the project files for

a lecture and compare with your own and

definitely check out the related videos

when I reference them this course is

focused on making this game but you

should definitely learn more about some

of these Concepts in more detail and you

can learn that in the videos that I

mentioned by the way if you're watching

this right now this is the secret con

loud so go ahead post the time step in

the comments with a nice monk Emoji I

want to see how many people make it this

far okay so that's it for now let's go

to the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to apply

some collisions to our player movement

okay so here we have our game so far we

have our player walking around and

everything looks pretty good however now

let's create over here in the hurricane

let's right click create a brand new

Cube so there you go let's place it over

here and push it down okay there's the

cube make it just a little bit bigger so

there's the cube and by default it has a

boxcon leather component so it has

physics and the player if I move and

nope there's our issue the player is

going right through the object now the

player is not meant to be a ghost so

let's fix this over here in our player

script we are hearing the input Vector

calculating the move Direction and then

just moving the transform so right now

we're moving it no matter what now

before we do that let's first do a test

to see if any object is in the way and

how we're going to do that is by firing

a raycast this one is a physics

operation that basically fires on laser

from a certain point towards a certain

direction and then tells you if it hits

something how we do that is let's go

inside the physics class and let's call

the raycast function

this one as you can see has many many

versions of this function with all kinds

of parameters let's use this one option

number seven which takes a vector 3 for

the origin a direction and a max

distance so first for the origin that is

from where we want to fire our recast

let's put the player object in so that's

transform dot position

then for the direction this is going to

be our move Direction so let's use our

move there and finally for distance

let's use some kind of player size

player width something like that

some lights to find up here a float for

the player size and put that 0.7 units

let's try out with the size just like

this okay so basically this returns a

Boolean it's going to return true if it

hits something and funks if nothing is

in the way so let's just do a bone call

it can move and basically we can move if

this raycast doesn't hit anything so we

can move if this one is false so if the

raycast is false then can move is going

to be true

that's very simple so if we can move

then we move the transform position

otherwise we don't okay that's it super

simple Let's test

so here we are I can move around and if

I go towards the cube and nope no longer

works so I can no longer go inside that

Cube okay great now in your case if it's

not working

first of all make sure that the cube

make sure it is touching the floor we

use the transform position as the origin

which is right on the floor so if the

box is raised up then you won't be able

to go through so make sure the cube is

touching the form also make sure the

cube has a box on leather component it

can be any type of calendar but you if

you made a cube then it should have a

box layer by default and it should have

the same shape as the visual

and also remember that the 2D and the 3D

physics systems those are completely

separate they are completely different

worlds so make sure you're using 3D

components and not the 2D ones so for

example if I add boxing weather 2D if I

add this one then it will not work so

make sure you're using the 3D and not

the 2D components same thing over here

on the script make sure you're using

physics and not physics 2D also finally

if you're still having issues make sure

you check the player position

again the player should be on a y of

zero the only thing that might have an

offset is the player Vision although if

you're using the same acid me then this

one should also be on a y of zero so all

of these on y of zero and then you can

also check the four by default this one

has a mesh calendar but if it is exactly

on yf0 with no rotation then it

shouldn't cause any issues alternatively

you can also just disable or remove the

mesh con leather from before since we're

not going to need that so with all that

yep everything works I can move the

player but I cannot go through solid

objects alright awesome so it is working

but for this particular use case a

recast isn't necessarily the best method

we should use basically Rick asses like

I said kind of like a super thin laser

but as you can see the player visually

has an actual body shape so the visual

and logic are using can only in

different shapes if I go ahead and push

towards the box you can see it works

just fine however if the player is a bit

more off to the side and the center of

the player right in front of it is not

the box and I move and yep there you go

now I am going through the box the

reason is because the erase accounts

being fired from the center of the

player and like I said it's kind of like

an infinitely thin laser so it has no

shape so as long as the center of the

player is not hitting the box and it can

go through it whereas what we really

want is for the visual and logic to have

pretty much the same shape so let's not

use a raycast over here on the code

instead of a recast we can use a physics

query with an actual shape

there are all kinds of casts you can use

as you can see all of them with

different shapes you've got a box cast

if you want to have a box a capsule if

you want the capsule or a sphere cast

all of these were pretty much the exact

same way except instead of a raycast

which fires an infinitely thin laser

these are going to have an actual shape

and for player controllers for the most

part you really want to be using a

capsule cast that's usually the

generally accepted player shape although

alternatively a boxcast also can work

very well in our case let's just go with

a simple capsule cast this one to define

a capsule has a 0.1 and a 0.2 by the way

if you have no idea what is a capsule

then we can go over here in the

hurricane let's right click create a 3D

object let's make it a capsule and there

you go this is the capsule it's kind of

like a stretch sphere so it has around

the top round bottom and then over here

in the middle it's just a cylinder and

over here for the raycast takes a 0.1

and a 0.2 so that is going to be the

bottom of the capsule and the top of the

capsule basically with those two points

we can Define the height of the actual

capsule okay so let's just get rid of

this capsule let's just lean it and over

in the code let's put those now 4.1 it

is indeed going to be the transformed

opposition since that is the point at

the bottom and for the second point

for this one it's essentially going to

be the player head so we can take the

transform dot position so this is the

bottom and we can essentially just lift

it up so let's add a vector 3 dot up and

multiply by some kind of player height

let's define up here a float for the

player height

and I tested it in the editor and the

player is about T and Stone

so over here let's go ahead and move it

up by that much

okay so next we want the radius so this

is pretty much the player size that we

defined previously so let's use the same

thing

but as always let's make sure to write

good clean code since now we are

referring to a radius let's actually

rename this to be a bit more clear and

by the way here's a quick Visual Studio

tip you can right click on a symbol and

then you can click on the rename option

alternatively use a shortcut Ctrl R

control R if you do that then now you

can change the name so for example on

player radius and note how it changes

every single instance of that variable

so this renaming feature is extremely

useful always make sure to rename

something if you find the name that

works best Okay so let's rename this to

play radius then we have Direction so

that is as usual going to be our move

Direction

and then finally we have the move

distance for that we can use the actual

move distance so that is going to be the

movement speed multiplied by time dot

all the time

so I just find here a fluid for the move

distance

and you should see that just move speed

time dot Delta time we have the move

distance and we use it both in here as

well as down here

okay so here we have our cancel cast the

rest logic is exactly the same so if

this one is false that means it didn't

hit anything so if it didn't hit

anything then we can move and then we

move the transform okay let's test and

over here now if I go towards the box

and the Epson works is only the same as

previously that's great and now if I go

towards the end and make sure that the

center is not hitting the box and I try

to move forward and nope now we no

longer go inside the cube so even on the

edges everything still works perfectly

alright awesome so it works it looks

good but it also is a little bit janky

for example let's stretch this cube out

a little bit so let's put it just on One

Direction so stretches like this let's

see now if I move towards it then nope I

cannot go through it so that is correct

and if I move left and right yep that's

also correct that works however if I now

press W and D at the same time in order

to move diagonally and nope right now it

does not move the reason is because the

diagonal Vector that one is indeed

hitting the collider but usually in

games when you move diagonally and you

cannot move in when Direction then it

tries to essentially hug the wall and

move around it so if I press wnd it

should essentially be moving straight to

the right so let's solve that so here in

our code we're making our Capstone cast

okay that's great then we need to test

if we cannot move so let's see if we

cannot move so it can move is false

if so then that means we cannot move

towards this direction

and if we can then essentially we

basically want to split the movement

Direction and just move on the X or just

on the Z so first let's attempt just the

X movement

so attempt only X movement let's create

a new vector 3.

let's call it move the year X and we

make a new Vector three let's take in

the move there dot X then zero on all

the other so we only want the test

moving in the X Direction

and then let's do literally the same

thing so let's get our can move try to

move under this direction so let's go

inside a move there move there on the X

so we do that capsule cast

and if we can move then that means we

can move only on the x-axis

so can move only on the X

and if so let's set the move there

equals the move there X

so if we can move them down here when we

use the move there we're going to move

only on the X

and if we cannot move

then that means we cannot move only on

the X

and if so then let's attempt only Zed

movement so over here again let's do the

exact same thing so let's copy this

let's just change this one so instead of

move to your X we've got moved here on

the Zen so over here we use 0 on the X 0

and Y and axis we moved here and get the

Zen then let's use this movement

Direction over there and finally the

same thing so if we can move

then that means we can move only on the

Zen and let's set the move there equals

the move there Z

and if not then we cannot move in any

direction

okay so that's it now this might seem a

bit confusing but it becomes a lot more

clear When You See It In Action again

remember the scenario we're trying to

solve which is when moving diagonally so

for example when we're moving forwards

into the right if we do that then let's

say this one is going to hit something

so we cannot move so if we are trying to

move both forwards and to the right then

we're going to only attempt the X

movement so we're only going to try

moving to the right and then we're going

to see yep going to the right that does

work so we can move and we're going to

move just to the right all right so

let's test and see if all of this is

working all right so here we are and if

I move straight to the wall and nope

there is 11 so I cannot move anymore

okay great now if I move just left and

just right and it does work now if I

press W and then D and if there you go

now it does hug the wall and continues

to move same thing if I go on the left

over here if I press D no I cannot go

through it now if I press D and S at the

same time and there you go it hugs the

wall and moves around so now our

controller is much more easy much more

understandable

okay so this is great now this is one of

those tiny things that makes your

character controller feel much more

responsive so that's great however we

also do see one more issue right now you

can see that I'm right next to the wall

and if I press A and D then look at that

I'm moving with this spin however now if

I press wnd look at that now I'm moving

diagonally and it's actually moving

slower basically this is the same issue

that we saw previously where we had to

normalize the input so we didn't go

faster in diagonals basically now we

have the opposite problem since we are

normalizing the vector we are cutting

down on the left right vector and with

that basically if we are moving

diagonally then we are essentially going

slower whereas if I stop moving diagonal

and just move left right it moves at a

different speed that solution for this

is really super simple over here in our

code when we are constructing the move

to your X and move the ears in when we

do this very simple let's just normalize

it so if this one is less than one then

it won't be going into one so let's

normalize that one and down okay that's

it let's test and now from here move

forward and hug the wall on left right

yep does work and if I stop moving

diagonally just going left right yep all

still works with the exact same speed

all right awesome okay so that's really

it as you can see it's super simple to

add Collision detection to your movement

scripts you just do a physics query to

testify our character should move and

just move it by the way if you want to

learn more about collisions and physics

queries there's a bunch of interesting

videos that you can watch for example

one is on various methods of finding a

Target then another one is on various

methods of handling projectiles and

finally another one is a very quick

checklist on why collisions are not

working basically there's lots of really

interesting things you can do with

physics so make sure you understand

these functions okay so now that we have

all of this working let's first just

clean up our scene so over here our

default Cube we don't want this so let's

just get rid of this and with this we

are ready to build our first kitchen

counter and let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to begin

building one of our main game mechanics

we're going to make a kitchen counter

and handle the logic for the player to

be able to interact with that counter

okay so let's begin by making our

kitchen counter and just like we did

when we made the player let's first make

an empty game object and place the

visual inside of it so let's right click

on the hierarchy and create an empty

game object call this the clear counter

so it's going to be clear on top so we

can place and pick up objects let's make

sure to reset our transform so let's put

it on zero zero zero let's move it just

a little bit just so it's not exactly on

top of the player okay now inside let's

add the visual so let's go inside the

assets folder and then over here we've

got the prefabs visuals and inside we've

got the counters visuals and over here

let's find the clear counter Vision so

let's go ahead and drag it inside the

game object again make sure the

challenge visual is on zero zero zero

the unlockable position okay great now

just like we did in the online lecture

where we added Collision detection that

shouldn't already be working by default

but in order for it to work it needs a

physics line either however note how the

vision over here there's no collider and

inside there's no collider there's only

visuals again this is the same thing

that relates to separating logic and

visuals basically the visual prefab this

one only has visual components so only

meshes animations and that sort of thing

and the main Parent Game object this is

the one that is going to have all of the

logic components set means any kind of

scripts Behavior as well as any

colliders

so over here on the parent game object

let's add new component let's find a box

Collider again make sure you add a box

of leather not a boxing leather 2D and I

chose a boxing Ledges because this is

the shape that makes most sense for our

counter and now let's scale the boxing

leather again that's the boxing ladder

not the transform so leave that one with

a scale of one one that's good and over

here on the box leather for the size

let's put it up with a size that fits

the visual so 1.5 1.5 1.5 and finally we

just need to lift it up a bit over here

on the scene view you can see those

little green tiny lines these refer to

the boxing leather shape so let's lift

it up by a little bit in order to make

it perfect let's put it up by 0.5 on the

Y alright so there you go that one does

have the perfect shape

if we test just like this it should

already be working it's okay so here's

my player and if I move towards it and

yep there you go it does work so it is a

solid object I cannot go through it okay

great

let's just visually rotate the calendar

so let's do that and again for rotation

let's make sure we rotate the apparent

game object and not the visual we want

the visual to be on rotation zero zero

zero okay great so on the parent game

object let's just rotate it around by

the way here's a quick empty tap if you

want to rotate hold down control and

then click to rotate and now instead of

rotating on every angle it goes on a 15

angle increment so just hold down this

way you can easily get it to 180 degrees

so it's just for fun just make it face

the player okay great so now let's

interact with this counter and doing

this is actually super simple

we already learned how to do a raycast

to handle collisions and for

interactions that's exactly the same

thing

so let's go into our player script and

we're going to do a recast to handle

that

but before we do let's organize our code

here let's make a proper function to

handle our movement

so let's make it private since this is

going to be in local function return

void and call it handle movement

and then inside let's put all of this

code so let's copy all this put it in

there and then on update we simply call

this function okay great and now let's

make another function so private void

let's call it handle interactions

and we just call this function on our

update okay great everything is much

more organized so now here let's do a

raycast

so once again go inside physics do a

raycast

for the origin let's start on

transform.position

for this obviously we want the move

Direction so an approach would be to

make this a film variable sorted up here

so that way we can access it in both

functions however if you remember how we

handled the whole issue with the

diagonals basically we're modifying the

move Direction so for moving diagonally

then this one modifies to only move left

or right we don't want that for the

interaction we want pretty much the

exact same one even if it's pointing

towards a solid object so let's not make

the same member variable only reuse it

instead let's just grab it again create

it again over here so we get it and we

want this one even if it's pointing

towards a solid object so let's use this

as our move Direction

and now for the distance let's define a

fixed distance

so something like two units would work

and also here's another very important

lesson with regards to writing good

clean code so you would think to write

code like this so let's put the two

right in here that would work everything

would work perfectly but then let's say

you get back to this code after one week

would you remember what this 2f means

the answer is probably not you would

probably very easily forget exactly what

this means so because of that you should

never use numbers directly in the code

like this instead you can either make a

field appear if you want to make it

customizable

or much simpler is actually what we

already did previously so let's define a

local variable with a proper name

so let's define a float and this one is

going to represent our interact distance

so let's call it exactly that interact

with the distance and let's put 2f and

over here instead of using a number

let's just use that variable now if we

were to get back to this code after a

long time it would be extremely clear

what this parameter represents

the technical term for what we did here

is called Magic numbers and I've also

covered them in detail in another quick

video

but as I always remember very simply

never use magic numbers

okay so with this we have our recast

it's pointing forwards for this distance

but this is actually not very useful

because the rickhouse this one only

returns a bullion so all this tells us

is if there's something in front or not

it does not actually get as the actual

object reference so for that let's use a

different version of the raycast

function so as you can see we've got all

kinds of versions in order to get the

object reference let's use this version

right here this one which has an out

parameter for a raycast hit note the out

keyword here this is important this

means that this is an output parameter

whereas the other parameters those are

all essentially inputs that you give to

the function whereas this output this is

basically a value that the function

outputs so let's use this so we've got

the origin we've got Direction then

we've got the rake asset in order to use

it we need to make sure to write the out

keyword here and then also very

important we need to write the type

so let's call it break asset and then

the name so let's call it break asset

basically what we're doing here is

essentially defining a variable of this

type with this name we're defining it

and giving it to the function

immediately so we can use it afterwards

if you don't include the type if you

just include the name then you get an

error because this name Rick has said

this was never defined alternatively you

can Define it before you pass it in so

over here you can do recast it recast it

and just like this it works because you

are defining it here and using it here

but in order to make the code a bit more

compact you can just Define it here in

the same place where you get it okay so

let's use this and with this the

function still returns just a Boolean so

just hit something or not but then we've

got the rake asset output this will be

filmed with data from the Collision if

we do hit something

we can inspect this to see what that it

contains so you can right click on top

of the type and then go to definition

and up here we do see the definition for

the rake acid struct you can see this is

a structure to get information back from

a raycast you can inspect this to see

all of the kinds of things that this one

returns for example you have a vector 3

point for the impact point in workspace

where the ray actually had a collider it

can get the normal of the surface and so

on so you can get all kinds of things

for a use case what we want is to

identify the object that we hit and for

that we can use the transform so it's

going to be the transform of the rigid

body or the collider that was hit so

let's just do a quick test if we hit

something lets you unlock on that object

so let's do an if so if this one is true

then that means we hit something so if

so let's do a debug unlock go inside the

rake asset and log the transform okay so

like this we should be able to see on

the console if we do hit something let's

also do an ounce just to be able to

easily see when we hit something so on

else let's just log an empty Dash and in

our game in order to make sure that our

Collision is working that we are

correctly detecting it let's just

duplicate this object but before we do

let's make this a proper prefab if you

have an object of a certain tab that you

want to create multiple instances of it

you should be using a prefab rather than

just duplicate an object that way with

the prefab if you make any changes to

that prefab it applies to all of the

copies of that prefab

so let's first make this one a prefab

and again since this is our first prefab

let's first make a nice folder to keep

things organized so folder for our

prefabs and to make game module prefab

is super simple you just click and drag

directly from the hierarchy and drop it

inside the folder there you go there's

our prefront and now let's just

duplicate this make sure it has a

different name so it has one so that's

enough with this we should be able to

see it just for testing let's put it

just off to the side okay so let's see

so here we are in the console we see a

dash so by default we are not hitting

anything okay so that makes sense now if

I move towards this object and if there

you go it does I didn't find that object

and if I stop moving it stops

identifying okay great now if I move

towards this one and if there we go this

is the one with the name of one and this

is the one with the name of none all

right awesome so just like this we are

correctly identifying what object is in

front except we also have an issue so if

I move towards the object then yep it

does work but if I stop moving once I'm

still facing that object right now it's

returning none now the reason for that

is because of the move data that we're

using here if we're not moving in any

direction then basically this Vector

won't be zero zero zero so we're going

to be firing a raycast towards no

direction at all so obviously it's not

going to hit anything the solution to

that is super simple we just need to

keep track of the last interact move

Direction so let's go up here to find a

film for that so let's make a private

let's make a vector 3 and call it the

last interact Direction

and then down here when we have our

handle interaction so we get the

movement here okay that's great so then

we just check if the move direction is

different from Vector 3.0 by the way

this is a constant a shorthand for zero

zero zero so if it is not zero then that

means we are moving in some Direction

so so let's set the unless in direct

direction to this move Direction and

basically if it is not if move there is

zero then we are not going to modify

this so this one is only going to

contain the unless interact Direction

and then down here instead of using the

move Direction Let's just use this one

so that way even when we stop moving we

are still going to be using the last

indirect Direction okay so with this

let's test so here we are and if I move

towards it yep it works and if I stop

moving and yep it still works alright

great so we can move towards it Point

towards a certain object and then yep it

still works okay great now let's

actually interact with this counter and

to do that let's make a class for the

counters itself so let's make a new

script in the UC sharp script let's come

with the same name so clear counter

okay there's our script

now very importantly for attaching the

script remember that we have two

instances of our prefab if you just

select it in the heart key and you just

drag it on there if you do that then

you're not actually adding this script

to the prefab itself you're only adding

it to this specific instance of that

prefab so if you look at this one yep it

has a script but this other one which is

a copy of the same prefab this one does

not have it also over here on the

inspector you can see the little script

icon has a nice little plus that means

it is something that you are adding on

top of the prefab so that means this

script is not present on the base prefab

basically this is not what we want we

don't want just this object to have this

script we want all instances of this

prefab to have this script so instead

let's get rid of this one from here we

want to modify the prefab itself so one

way to do that is to select the prefab

on the project window so here it is the

actual prefab and now we can drag the

script on there so that works or another

alternative is something like the prefab

in the hierarchy and on the inspector

over here we see a nice button to open

the prefab and if we actually go into

scene view then we can see what that

does so with the object selected so this

is an instance of that prefab but if we

click on open then essentially we are

opening and we are working inside the

prefab so now if we make sure to add our

script and let's go back outside this

prefab so on the top left corner over

here we can see where we are so we were

inside our scene and then we are inside

the clear counter prefab so if we click

on the scenes we can go back now it

tells us that we made some changes to

the prefab so let's save them and if we

add that script and we can see both

instances of the prefab they both have

the same script and we can see on there

on the icon that this is not an override

this is an actual script at on the base

prefab so whenever working with prefabs

always make very sure that you are

adding it on the right place

if you want something on the base prefab

make sure you either add it on the

prefab itself or go inside the prefab by

double clicking on it or select an

instance in there and open to go inside

the prefab so always keep in mind

different switches between a prefab and

an instance of a prefab okay so we have

our script let's open it and over here

let's just make one super simple

function

so let's make it public because we want

to call this from our player class let's

return void and just call it interact

okay that's it super simple for now

let's just do a debug.log and just say

interact

okay so that's it and now over here on

the player when we have our handle

interactions function so interact we do

our raycast and we find out if we hit

something so when we do the first thing

that we should do is identify what this

transform is so is this something just

like a dumb Cube or is it an actual

counter now when it comes to identifying

things this is another place where a lot

of beginner tutorials will teach you to

use the unity attack system so that's

over here in the editor when you select

any object over here in the inspector

you can see a tag so you can see

untagged and you can add all kinds of

tags this is something that a lot of

beginner tutorials teach but Unity tags

are horrible you should never never use

them I covered in more detail why that

is in the advanced concepts video the

main reason is because of well pretty

much the same thing that I mentioned a

while ago when we were handling animator

parameters so you were doing this and I

talked about how this one takes a string

and how strings are horrible way for

identifying objects they are very

brittle very error prone it's very easy

to make mistakes and tags have the exact

same problems because tags are strings

so we do not want to use tags to

identify objects instead over here on

the player script let's use a different

method for identifying objects and the

best way to do that is to Simply get our

counter component

so we have our transform and then from

inside that transform we can call the

function try get component this one then

takes the type of component and again

note how this is an out parameter so

let's put out and we want to test if

this is a type clear counter so clear

counter and call it clear counter

and this one basically does the same

thing as a recast so it returns a

Boolean so either true or false

so if this one is true then that means

that object has that component so over

here we know has clear counter

by the way if you're not familiar with

tryget component this is pretty much the

same thing as the regular get component

except it automatically handles the null

check for you

so if we just did this it's exactly the

same thing as this so you do an if

recast it what's X is a transform get

component

component of type clear counter

naturally this one is not inside now but

let's store this

well your counter equals this then you

do if this one is not known

then we know has a clear counter

so basically what we have up here is the

exact same thing that we have down here

so just using trigate component it's

just a bit more Compact and I find much

easier to read than to always get

component and test if it is not null

over here we just have one function with

a nice out parameter and everything

works perfectly so that's the try get

component I much prefer that method so

let's use that by the way on the trackit

component over here you can see it has a

type inside some angle brackets

basically these are called c-sharp

generics these are an extremely powerful

c-sharp tool I have a dedicated video on

them and I've used them in tons of

videos definitely go ahead and learn

about them basically this lets you write

code that works with many classes not

just one specific type in this case the

target component can work with any type

of component

so it can be Unity built-in components

or it can be components that you made

yourself then if it finds a type it

returns true so for right now it's not

strictly necessary to know the specifics

about how c-sharp generics work but

definitely make sure you add that video

to your queue and watch it afterwards

c-sharp generics are an extremely useful

c-sharp feature okay so we do this and

basically if we are inside of here then

we know this object has a clear counter

and we have our clear counter reference

so over here it's super simple let's

just call the interact function

alright so that's really it let's just

get ready else we no longer want that

log so we should be able to see unlock

whenever we call our interact in a

counter alright so here we are and if I

move around okay that's good over here

the console is empty all right now if I

move towards the counter if there you go

I'm interacting with it and if I move

towards this one if there you go

interacting all right great so with this

we are correctly identifying the object

and interacting with it now let's just

do one final thing over here we are

doing a recast to find the counter

and right now we are doing a raycast

towards any object that has any kind of

physics calendar

so maybe that's our counter or maybe

just a random wall for example if we had

an invisible wall in front of our

counter then this code would not work

that's because this raycast and this

raycast set it only Returns the very

first object that it does hit so if the

counter was behind the wall then the

brake acid object here would be a

reference to that long object perhaps

that's what you want or perhaps not in

that scenario one thing you can do is

instead of using recast you can use the

function raycast all

and difference for this one is instead

of returning just a Boeing just true or

false instead it returns an array of all

of the objects that it hit with that

raycast then you could cycle through

them and identify the object so that's

one approach or another option is over

here on the recast

if we look at these function versions We

can see that some of them has what it's

called a layer mask basically you can

set a certain game object to a specific

layer and then if you're using layer

mask then you can make sure this recast

will only hit objects within that layer

anything not on that layer will be

ignored for that recast this is super

useful so let's learn how it works for

layer mask we can go up here and Define

a type of layer mask so let's make

another serialized field private let's

make it of type layer mask let's call it

the counters layer mask

okay so we have this and then down here

when we have our recast let's use it so

let's find the function that matches up

these parameters with the layer mask so

here it is we have the origin then we

have Direction Drake acid the max

distance and then finally we have our

layer mask and let's use our counters

layer mask okay great now back in the

editor let's select our player game

object and yep there we see our field of

type layer mask and you can see how we

can select all kinds of layers and how

we set these layers to an object is

let's just select our clear counter

although again we want to make sure that

this change applies to all encounters

not just this one specific instance so

let's go inside the prefab and over here

we've got a Film Forum layer and you can

see we've got a bunch of default layers

and then we can add some more so let's

add some layers and over here let's go

to the first empty one and let's call it

counters okay we've added the layers so

let's go back select our object and now

on the layer let's put it on the

counters now it asks you if you want to

modify the layer for all Channel objects

now since we made sure to keep the Dean

logic and physics components only on the

parent object let's just modify this one

and leave the other ones on the default

so let's just modify this object only

okay so with that our counter is now on

the counters layer let's leave the

prefab make sure to save it okay great

and now if we go back into the player

and over here on the counters layer mask

yep we do see the counters layer so

let's just click the selected by the way

this drop down menu can actually select

multiple so you can select all kinds of

layers so this is multi-select but we

only want to counter so only like this

and just like this if we do test and if

I move towards it and if there you go

get the nice interact on both them so

everything still works is only the same

but now if we had another physics on

leather in front of it it would still

work because we're using a layer mask to

only recast against counter objects

alright great now I should point out

another way to work with layers is with

something called a bit mask that's a bit

more advanced usually the layer mask is

much easier to follow but if you want to

learn about bitmask go ahead and watch

that video and also another quick note

in this game we're only going to

interact with one single object type

it's only going to be a counter even

though we're going to have multiple

types of counters but for games where

you want to interact with multiple

objects like for example having an

interact action to talk with an NPC

another one to open a door or push a

button for those kinds of multiple

interactions to build the system like

that make sure you look into my how to

interact with objects video it covers

how to do all of that how to interact

with all kinds of objects it's all based

on c-sharp interfaces which we're

actually going to use in a few lectures

and also have a dedicated video on that

topic so keep following this course but

then make sure to watch those videos add

them to your watch list and make sure

you do watch them watch out how to

interact video it is something that is

necessary in so many games and most

tutorials don't actually teach you the

correct way of doing it anyway so back

in our game we are correctly identifying

and interacting with each counter but

obviously we don't want to interact

automatically just like this instead we

want to press a nice button to interact

so that means we're going to need to

create an interact input action so let's

do all of that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to create a

proper interact input action and in

doing so we're also going to learn about

a very powerful and c-sharp feature

called events

okay so here we have our game so we have

the player and if we move towards the

counter yep we are correctly identifying

it and interacting with it except of

course we don't want the interaction to

happen automatically it should be on a

player input so let's make our interact

action let's go inside our player input

action so let's double click on it and

let's make a brand new action so we've

got to move and now we're going to have

another one so let's click on the plus

icon for this one let's call it interact

and for this one action type we do want

it to be a button okay great then on the

default binding let's go into path let's

listen and by default let's bind it to

the E key just like so many games so

let's go ahead select this one and once

again let's make sure to save the asset

and let the C sharp OS be generated okay

and over here in our game input script

in order to listen that is very simple

so we go inside the player input actions

then inside the player action map and

then we can find the interact action

and then over here we can see a whole

bunch of events that we can interact

with we've got these three cancel

performed and started these are the

three phases of every input again I

cover these stages in detail in the

input system video the important thing

is that these are c-sharp events which I

also covered in another dedicated video

essentially they are a way for how you

can write code to then get notified when

something happens rather than running

code on every single update constantly

testing something for example over here

on the movement movement is a

pre-constant action so it does make

sense to ask the input on every single

update if any movement is pressed but

for an action like the interact the

player is only going to press that say

once every five seconds so it makes no

sense to constantly check for that

action on every single update instead we

just want to be notified when that

action is triggered and that is exactly

what an event does again watch the

dedicated video to learn all about

c-sharp events in detail they are

insanely powerful and we won't be using

them more and more as we go through this

course

for now here are the absolute Basics

events have Publishers and subscribers

the publisher creates and fires the

event when something happens and the

subscriber listens that event and gets

the enlisting function called when the

event is fired now on the generated

c-sharp class we've got these three

events the one that we want for this

case is the performed event so let's go

into this one and basically we want to

add a listener to that event

and we can subscribe to that by doing

plus equals so this assigns a listener

to that event and now Visual Studio has

a nice shortcut so if we press on Tab if

there go it automatically creates a

function now if you're not using visual

studio you can just manually write this

function the only thing you need to make

sure is that the function signature

personally matches the event signature

as usual we can inspect the event so we

can right click on it and go to the

definition and up here is the definition

and you can see that this is an event of

type action with a combat context action

is what is called a dungit I also have a

video on delegates if you want to learn

more about them in detail for now we

don't really need to worry about what is

delegate we just need to use it so in

order to subscribe to the event we need

to make sure that this one returns voyne

because an action returns void and needs

to have a parameter of this type combat

context if I erase this parameter if

there go now we have an error because

the function signature does not match so

it always needs to match the exact same

signature okay and also one more note

over here when subscribing to the event

make sure you only add the function name

meaning you do not add parentheses we do

not want to count function we just want

to pass in the function itself as a

reference okay so now when the player

presses the interact action it's going

to fire off this event which in turn

will call this function so over here

let's do a debug download just see what

this contains for example let's print

out the compact context okay so let's

see so here we are and if I press on E

if there you go I've got a nice event

okay great so with this we know when the

player presses the key now the next step

is how do we get the player class how do

we get this one to know when this is

performed and the answer is we're going

to do the exact same thing we're going

to make an event over here on the game

input class and the player won't listen

to that which in turn the game input

grabs from the input system again the

home point is separating our concerns so

the player does not care about the input

system does not care about the interact

action it only wants to know when

something related to interact happens so

over here let's make that nice event

first of all let's make it public

because we want the player to access it

then we need to add the event keyword

next we add the donkey type like I said

you can learn more about delegates in my

dedicated video you can create your own

custom Delegate for your event or you

can just follow the c-sharp standard and

just use the standard event handler and

this one exists inside system

so let's make sure to go up here and add

using system and this one has the event

handler class this one is pretty much

easy sharp standard for events as you

can see it returns void it has an object

for the sender and an event RX parameter

like I mentioned in the events video you

are not forced to use this target you

can use whatever delegate you want like

for example you saw that the performed

uses an action delegate so you can use

anything you want to choose that the

event handler is the c-sharp standard so

it's easier to follow unless you have a

specific reason to deviate from the

standard you should probably use this

one so let's use this and then finally

for the name usually you start the name

with on and then whatever happened so in

our case let's go with on interact

action

okay so we have defined our event and

now for firing it let's go down here

into when we have the interact performed

and let's go into the event and for

finding it it's pretty much exactly the

same thing as calling a regular function

so we just call it with parentheses then

usually for the object sender this is a

reference to whoever is sending this

event so usually the this keyword and

then for the event RX this is in case

you want to send some arguments with the

event in our case we don't really need

to send any extra data for this one just

firing the event is going to be enough

so for that we can use the constant

event RX dot empty okay so that's it

with this we are firing an event except

just like this we're actually going to

have one potential error if we have no

subscribers no listeners to this event

then essentially this field won't be

known so this one over here is going to

trigger a non-reference exception let's

do a quick test just to see this

happening so here if I press on E if

there go we have a null reference

exception

so when working with events you need to

first test if there are any listeners

and only then do you actually trigger

the event

so you do if this one is not null if it

is not known that means there are some

subscribers so we can fire the event so

like this it won't work but there's an

even more compact way to do this which

is perfect for events so instead of this

we've got our on interact action then we

can add a question mark this is called

the non-conditional operator basically

the code is going to execute from left

to right

and then when it gets to this question

mark it's going to evaluate the left

side and if it is null then the

execution won't stop right here on the

question mark and will not throw any

errors whereas if this one is not null

then it continues executing to the right

except with this syntax we have an error

We cannot put parentheses directly after

the question mark but what we can do is

simply just call invoke and that does

the exact same thing that console

function so what we have here is exactly

the same thing that we had previously

so what we have over here and over here

these are the exact same thing it's just

this one is much nice much more Compact

and especially for events this one is

super useful okay so with this we are

correctly firing for our event now let's

actually listen to it so let's go over

here into the player class

and let's listen to our event

let's do it on a private void start make

it on start not an awake this is a very

important rule which I'm actually going

to cover in detail in the next lecture

but for now just make sure to listen on

start and not on awake so over here we

access the game input then let's access

the on interact action event and as

usual let's listen to it so let's use

press tab to listen to it so it is

exactly over here that we want to run

our interact code so let's go down into

the handle interaction code that we had

previously so this one

so let's copy paste all this code put it

up here

so we get the interaction going to the

object and Trigger the interact now

obviously code duplication is a big

No-No so we're only duplicating our code

just for a quick test just make sure it

works

once again refactoring is super useful

so we're going to refactor this code to

get rid of code duplication in the next

lecture but for now we just want to test

to make sure that this does work

so let's just remove the interact over

here from the handle interactions so the

only interact function being called is

over here when we have our actual input

so let's test and see if we can press to

interact with the counter alright so

here we are and as I move around if I

approach a counter yep there you go we

no longer have the automated interaction

and now if I'm facing the counter and I

press the enter I key if there go here

we have our nice interaction all right

awesome so I can approach I can interact

and do whatever I want

alright so here we learned about c-sharp

events these are super powerful so if

this is the first time you're hearing

about them then you've just had an

awesome new tool to your tone box

definitely make sure you watch my

dedicated video to learn about them in

more detail events are super useful the

next thing we're going to need is just a

visual to highlight the current selected

counter so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to add a

visual to our selected counter and in

doing so we're also going to learn about

the very useful Singleton pattern okay

so over here we already have the logic

to identify the counter in front of the

player and we can interact with it

however once the logic works there is no

visual indicator at all so let's add

that now as usual the super quick and

dirty way of doing it would be pretty

simple over here on the player script we

could just directly enable a visual mesh

on the target counter so down here on

the handle interaction when we have this

over here we can tell the clear counter

to enable some kind of visual

technically that would work but that

would be some pretty dirty code we would

basically be making the player

responsible for enabling some kind of

visual which would mean that we were

mixing logic with visuals again we

always want to try separating the logic

from the visuals as much as possible to

keep our code nice and organized so

instead of doing the quick and dirty

route let's do it properly back in the

editor let's create a brand new c-sharp

script call this the selected counter

visual

and now let's go into the prefab again

let's go inside it so let's select the

clear counter on the hierarchy then on

the inspector let's open up go inside

the prefab and now let's select the

visual inside it and let's duplicate

this so you can press Ctrl D to

duplicate it let's name this when it's

selected and then inside there's a

visual with a mesh filter and a mesh

render so over here let's swap out the

material

so let's click on the circle icon and

now included in the assets is this

material counter selected so it's all

the way yep up here the counter selected

basically it's just a solid white color

within low Alpha so on the kitchen

counter inside the sunlight game object

let's make sure to use this one with

this we have kind of like a ghost visual

so if we enable and disable this game

object we can see the difference Also

let's do one tiny thing which is right

now we duplicated the actual visual

meaning that these objects are exactly

the same they have the exact same size

and when that happens you might end up

with some rendering bugs if two meshes

are on the exact same position you might

sometimes see the colors constantly flip

back and forth

so in order to make sure that doesn't

happen let's make this one deselected a

tiny tiny bit bigger so over here with

the selected game object selected on the

inspector over here we've got the scale

and also we've got this nice little

button here if it's like this then we

can modify each proportion differently

from one another whereas if we click now

these are all linked so now I'm

modifying one will modify all of them so

let's put this on 1.01 meaning this one

is going to be literally just one

percent bigger so that's enough of a

difference to make sure we don't have

any rendering bugs and by default let's

also start with the visual hidden so

let's do that not on the parent select

game object but rather on the kitchen

counter inside of it let's make sure to

disable this game object by the way the

quick shortcut is shift alt and a you

can enable or disable the object very

useful so let's start with this one

disabled so that it's hidden and

basically the goal is that when this

counter is selected we're going to

enable it and show this Visual and when

it's not selected we're going to disable

it okay so over here on the selected

let's add the script that we made so

these selected comes revision all right

so let's open it now here first thing we

need to know is know which counter is

selected meaning we need to know which

counter the player is currently looking

at so let's go over here onto the player

script and let's basically just do some

simple logic to keep track of the

selected counter so over here let's make

a field so a private

let's make it a type clear counter and

just come with the selected counter

then down here we have our handle

interactions logic okay so we do all of

this we try to find the counter in front

and if we do find it then we have it

here so here on let's just check if it's

different so if this clear counter if

the one in front is different from the

current selected then let's set the

selected to this one

and let's also make sure to essentially

unselect so we want to make sure to set

this one to know when there's nothing in

front of the player so if the raycast

does not hit anything then there is

nothing in front of the player so let's

set this like the counter back into null

and also if there is something but that

something does not have the clear

counter script then it's also not a

counter so over here let's also do an

else selected counter equals no so

basically if there's a counter in from

the player then it's going to set it if

not then it's going to be no

let's just do a simple debug download to

check on the selected counter okay and

also just briefly now that we've made

this selected counter logic actually up

here when we have our interact action

like we saw we were previously copying

some duplicated code

but now we no longer need this since we

already know the selected counter so

over here when we've got the interact

action

let's just check if we do have a

selected counter so if it is not null if

so then we go there and we call the

interact function so that's it we no

longer need all of this logic okay

that's great so let's test back in the

editor and let's go back into scenes

let's make sure to save the prefab

make sure the script was attached save

it and let's hit on play and right now

if I'm down here yep there you go we've

got null and as I approach if there go

that one is a clear counter and if I

move towards this one yep it's that one

okay so basically we are keeping track

of the kernel selected counter now

basically we just need to notify the

visual whenever this one changes so when

this one is pointing at that one or

pointing at no or pointing at that one

we need to know when that happens

and for that we basically have two

options now one option is pretty much

what I mentioned a while ago which is

over here we have the selected counter

so we can run some kind of logic on the

sunlight counter we can do that over

here on the player then perhaps over

here the counter would fire off some

kind of event saying it has been

selected and then the counter visual

would listen to that event and update

itself now that approach would be useful

if we wanted to add some kind of logic

on the clear counter while selected and

that approach would also have the

benefit where the visual encounter would

only listen to events on its own counter

so that's one approach pretty much a

very direct approach but another one is

very simple the player would simply fire

off an event whenever the selected

counter changes and then all of the

counter visuals would listen to that

event then they would identify if the

event relates to that counter and if so

update their state

now the benefit of this approach is that

the logic doesn't get bothered with any

selection logic so over here the clear

counter script never really knows if

it's light or not and that's a good

thing because it doesn't need to know

although the potential con with that

approach is that all of these selected

countervisions are only going to listen

to the same event so both approaches

have pros and cons here on let's go with

the second approach where all the

counters listen to a player event

the potential performance con doesn't

really matter on a game of this scale

we're only going to have about a dozen

counters so even if 11 of them are just

wasting on listening to the event it's

really not going to matter and going in

with this approach will actually help us

learn about the Singleton pattern which

is extremely useful so first let's go

over here onto the player class and

let's make the event that we're going to

fire

so as usual let's make it public so we

can access it let's make it an event and

as usual let's also use the standard

event handler let's make sure to add

using system so here Visual Studio adds

it automatically okay

then let's call this on selected counter

changed

also this is a great moment to learn

about the event arcs this is how you can

extend a c-sharp event in order to pass

in some more data so how you do it by

following the c-sharp standard is very

simple we just create a class

so over here let's make a public class

then for name usually you include the

name of the event with eventars at the

end so in this case on selected counter

changed and then event arcs then on this

class we make it extend event arcs

and finally inside the class we add

whatever that we want like for example

we want the current selected counter so

let's make a public clear counter and

put the selected counter

okay so we have this nice event arcs

with a bunch of extra data and then over

here on the event handler we use the

version that takes a generic and we pass

in our event arcs again I covered the

generics in more detail in a separate

video definitely go watch that one if

you haven't seen it yet c-sharp generics

are one of c-sharp's most powerful

features okay great so we now have our

nice event now let's fire it off so

let's go down here to when we're

modifying the selected counter so here

it is we've got all of these ones so

when we modify let's fire off the event

so we go into this event and as usual

let's use the question mark and then

call invoke then for the object sender

it's going to be this so pretty much is

centered and then for our custom

eventarics let's construct an object of

that type so construct a new object and

then inside we pass in the selected

counter and we set it to this selected

counter now don't be confused by the

fact that we're using the exact same

name if you actually Mouse over the

cursor Visual Studio actually helps you

by telling you which object refers to

this so with the cursor here note how

all of these are highlighted but this

one is not highlighted that's because

this field this is the film inside the

unselected counter change event RX

whereas this one out here is the object

that we're referencing in here so even

though these two have the exact same

name here we're accessing the film

inside of that and we're assigning it to

the reference that we have down here

okay so that's really it we're firing

off the event when the selected changes

and we're passing it in and let's also

make sure to do it over here so let's

copy and paste some code and there you

go just like this except of course we

can already see a bunch of code

duplication usually that means it's time

to refactor so let's do that pretty

quickly let's go down and make a brand

new function so let's make a private

Droid let's call it set selected counter

and we're going to receive a clear

counter for the selected counter

then over here we just set this dot

selected counter so we're modifying the

member variable with the one that we

receive on the parameter and then let's

also fire off the event so let's copy

paste the event

just like this the exact same thing okay

so that's it and now up there instead of

code duplication we just do this

so over here we set the clear counter

just call the function pass in that one

and get rid of this and on that one just

pass a null just like this get rid of

all this and here the same thing just

pass in no alright so with this our code

is much cleaner and everything still

works is all the same so here we have

everything done on the player side let's

just get rid of unlock we know we need

this so we're still handling the

selected counter logic and then down

here we're firing off the event now we

need to do is go over here into the

selected counter visual script and here

what we want to do is to listen to that

event in order to do that we need a

reference to the player object now so

far when we've been listening to events

like for example any player class up

here we were listening to some events on

the game input so there you go the

uninteract action so for the game input

reference we just added as a serialized

field

we did this and then we drag the

reference directly and technically we

could do the same thing over here on the

sound like the counter visual but we're

going to have like a dozen counters in

our map so it would be pretty tedious to

drag and drop the play reference to

every single one of them so instead of

using a serialized field another

approach is to use the Singleton pattern

this one is an extremely useful

programming pattern it's very useful for

things where you only have one instance

of something

in this case we're making this game

single players so we're only ever going

to have a single player by the way

here's one obvious quick note like I

mentioned in the beginning of this

course

after this video there's going to be

another one converting this game into

multiplayer and in that case we will

have multiple player instances but this

is also an excellent reminder of how

refactoring code is perfectly fine for

right now for this game it is intended

as single player so for now we're going

to use the Singleton pattern then in the

future when we convert this to

multiplayer we won't simply refactor

that logic again don't be afraid of

refactoring code it's a Perfectly

Natural part of programming and game

development okay so let's implement the

single note pattern this is actually

super simple the name sounds

intimidating but it really is very

simple

over here on the player script

let's make a public field this one let's

make it static

if you don't know static basically it

means that this film belongs to the

player class itself and not to any

instance of a player so for example if

you had a hundred players you would have

a hundred instances of moose mean you

would have one for each player but there

would only be a single static film

because this static film belongs to the

class itself and not to any instance so

let's make a field of Thai player and

then for the name the convention is to

call it instance and the reason why I'm

using Pascal case here so capitalized in

the beginning the reason for that is

because this is actually not going to be

a film but instead it's going to be a

property

remember the naming rooms that we

covered in the beginning of this course

it's very important you follow your

naming rules always be consistent so

your code is easier to understand

so with that said since this is the

first time we're using a property let me

quickly explain what it is

basically it's the exact same thing as a

regular variable except you can add some

logic when getting and setting that

field so here let me write some quick

code just to show difference between a

property and a regular field so for a

regular field you would call this maybe

instance field something like this so

this is a regular field

then you would have some kind of public

static

return the player and call it get

instance field

then over here you would return the

instance field

and then maybe another public static

void set instance field where you

receive a player for the instance field

and you would set the player that

instance film into this instance field

so this is how you do this logic with

fields and now with properties

you would do public static Flair then

call it instance

then on the property itself you open up

the currently brackets

inside the property you put a get then

you return something

so for that something usually a property

has a field underneath it

so you'd have a private static player

for the instance that's a different name

from this one

on the get you would return that

and on the set

you would set the instance equals z

value

if you're confused here don't worry

basically I'm just repeating just so you

can see difference here we have a field

with a get and a set function so regular

functions and up here we have a property

and inside the property the property

itself has a get and set functions which

can also do some logic so you can do

some logic in between or you can just

return the underlying value so basically

using your property is pretty much the

exact same thing as using a separate get

and set function also one more bonus

thing which is that c-sharp is smart

enough to automatically create the

underlying film for a certain property

so if you just want to do a get and a

set then you don't need to Define all

this you can just Define a property and

then inside you can just do get and set

and there you go this code here works

the exact same thing as we had

previously which in turn is the exact

same thing as all the code we have here

with the getter and a Setter function so

here it is a valid functional c-sharp

property now I have to say that

personally I very very rarely use

properties in fact the only place where

I use them is over here on the Singleton

pattern for everything else I normally

use regular films with get and set

functions personally that's just the way

that I like to code but that's really

just personal preference so if you don't

like to use properties then go ahead and

use them anyway so the reason why I like

using a property specifically for the

single pattern is because the implicit

implementation allows you to do

something really nice again remember to

go on with clean code we want to

minimize complexity and the best way to

do that is minimize access here if we

set this property and we set it as

public then that means that any other

class can both get and set so anyone

else can have both read and write access

so we have the exact same problems that

I warned you about when I spoke about

why you should not make everything

public and of course if we make this

private

then at that point we kind of lose the

purpose of our Singleton since no one

else will be able to access this

basically we want to be able to access

this reference from classes outside of

this one we just don't want those

classes to also have right access

now thankfully properties have an

excellent thing which is you can Define

accessors for here both the get and the

set so we can make the property itself

public which means by default both of

these won't be public but then we can

also add the accessor over here private

which in turn means that the get won't

be public so any other class can get

this but private means that only this

class can set it this way we have the

exact level of accessibility that we

want this is the reason why for this

specific use case properties are very

useful with just this one line of code

we already have our instance with the

perfect level of accessibility

so now that we have this field to set it

let's make a simple awake so let's go

over here private void awake and on

awake we just set instance equals this

however remember that a key point of the

Singleton pattern is you only have a

single instance of something

so in this case we should never have

more than one player if we do then

something went wrong

so we can add a nice safety feature here

let's just check if instance if it is

not known meaning it has already been

set to something

if so then that's an error something bad

happened similar to a debug.log error

because this should never happen so

let's say there is more than one player

instance this way we have a nice safety

check just in case something goes wrong

alright so that's really it for the

Singleton pattern we just defined a

property with a public yet in a private

set and on the Wake we just set the

instance that's it as you can see it's

super simple and now for the really

useful part over here on the selected

counter visual now we can access the

Singleton instance in a super easy way

let's make a private void start and on

start we just access the player class

and from the class we can access the

static instance so we can access the

Singleton and now we can listen to The

unselected Counter event and over here

by default Visual Studio gives this

function the name of the event and also

the property

this is in the very descriptive name so

I like to rename this so control RR and

just rename the instance here instead of

instance let's rename it to player okay

great so over here we can listen to this

event

however here is yet another extremely

important thing note how I made this on

start that is very important if you do

this over here on a week instead of

start and over here on the player you're

also setting the instance on awake if

you do that basically there is a chance

that this code won't run before this

code and if that happens well then this

one the player instance has not been set

yet so this will be null and don't throw

a known reference exception now whether

this happens or not it's actually

somewhat random it depends on the order

in which Unity decides to run both these

scripts if Unity decides to run the

player first and this one second

if that happens then there's no problem

but if Unity decides to run this first

and then this one then we have a problem

let me do a quick test and see if in my

case it triggers that error any up in my

case it did trigger that error so here

we have a no reference exception

any app it is being fired on this line

now one solution to this problem is you

can tell Unity specifically which order

the script should run in so you can go

up here into edit then go into the

project settings

then on the left side you've got

something called The Script execution

order and basically over here you can

set the order in which all of these

scripts run so if you were to make the

player script run before the default

time that would make sure that even

though both these scripts aren't awake

this one would run before this one so

that would fix that problem however you

should really only use this approach in

the last case possible where there

really is no other way in this case we

do have another better Wing personally I

have a very simple room that I like to

follow that helps solve this issue as

you know Unity has both an awake and a

start

and all of the awakes on all the objects

will all run before all these starts so

the simple rule that I follow is that I

use a wake for the initialization of

that script and for any external

reference for that I use it on start so

in this case for initializing the player

and setting the instance that will lead

to the initialization of the player so

let's do it on the Wake whereas over

here on the visual

since here we're going to access the

player which is an external reference

for this one instead of doing it on Wake

let's do it on start this way we are

guaranteed to make sure that this

instance has been set okay so with all

of that here we have our instance so

that works great and we have our events

so that's great then here we have our

event and inside we've got our event

arcs so we can go inside the event arcs

object and inside we have our selected

counter so we need to do is just compare

which counter this Vision belongs to

so let's actually make a film up here so

as usual let's make a serialized film of

type clear counter

so we have this one and before we go

into the editor just make sure it

compiles and let's comment this out so

now let's go back into the editor and

over here let's drag the reference but

again remember we're working with a

prefab so let's click on open to go

inside the prefab and now once inside it

let's select the selected game object

and just drag the clear counter

reference okay great let's go back

outside and save the changes all right

so now here in the code it's actually

very simple so we just do an if

if the selected counter matches this

clear counter

if so then we want to show this visual

if not we want to hide it so let's also

add a reference for that visual so let's

add another serialized field of type

game object for the visual game object

then back in the editor again let's go

inside the prefab and on the select

let's drag the channel kitchen counter

so drag down that is the visual game

object okay let's go back save and back

in the code here let's make some simple

show and hide functions so private void

show

and a private void hides

and now on the show just going to visual

game object and call set active so this

enables or disables the game object so

for sure let's set it to true and for

hiding let's set it back into fonts okay

so now it's super simple if the selected

counter is this counter then let's show

the visual if it is not then let's hide

the visual alright that's it super

simple let's test so here we are and if

I approach that counter yep there you go

look at that nice selected Visual and if

I get into this one yep there you go I

can see it all right great so here we

had a really nice visual to our selected

counter and more importantly we'll learn

about the super useful Singleton pattern

as well as learning about c-sharp

properties and a very helpful room for

how to avoid code timing issues so this

was a really detailed really important

lecture if you're feeling confused about

anything go ahead watch it again or just

post a question in the comments and I'll

do my best to help so with all of this

this is all great we have these unlike

the counter and we can see which one is

actually being selected then by pressing

a button we can actually interact with

it so I can move and interact with any

of these counters but right now just

interacting with them doesn't really do

anything so the next thing we need is to

create some proper objects for all of

our ingredients so we can later pick

them up and drop them on counters so

let's begin doing that in the next

lecture

hey again quick intermission your pass

C15 lecture marks so congratulations

looking at my regular core stats it

seems about 80 of people give up by this

point so great job with sticking with it

the difficulty in complexity is

increasing over the lectures so I just

want to check in to make sure you're

understanding everything remember to

post in the comments if you need extra

clarification on anything and I'll do my

best to answer

also check the website to see what

questions others have asked and of

course remember this is your Learning

Journey you're not competing with anyone

but yourself so take your time re-watch

some lectures if you need to just focus

on learning okay let's go to the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to learn how

to create the kitchen objects like the

various ingredients okay so far we have

our player we can walk around I can

approach each of these counters and I

can interact with now the next one is to

create objects the player can pick up

and drop when interacting with a clear

counter so let's begin by making the

actual objects so let's create a new

empty game object call this one the

Tomato then again as usual let's

separate the visual so in the included

assets let's go inside of it then we've

got the prefab visuals and we've got the

kitchen objects visuals and inside we've

got all of the ingredients so let's just

find the Tomato Visual and drag it as a

child of the tomato and again as usual

make sure to put on position low

composition zero zero zero and for the

main one let's put it on a y of zero and

just push it a little bit off to the

side just so we can see okay great

now this one is obviously not going to

exist over here in our world instead

we're going to spawn it so let's make it

a prefab let's just drag it over here

into our prefabs okay there it is let's

delete it from our scene and actually on

our prefabs let's make a nice folder to

keep things nicely separated

so inside the prefabs let's make a

subfolder

currently the kitchen objects

let's put the tomato inside of it and

let's also make another folder

for the counters and let's put the clear

counter inside of it okay so everything

is nicely organized all right now that

we have this let's go inside our clear

counter script and over here let's add a

simple reference to our prefab

so let's make a type transform called

the Tomato prefab

by the way here you could make this

prefab reference of type game object

which type you use in this scenario is

pretty interchangeable I talked about

those differences in another video so

when using prefabs using them as

transforms or game objects that's pretty

much personal preference and personally

I just prefer to use them as transforms

okay so we have this let's just make

this a serialized field so we can set it

in the editor and over here in the

editor let's open up go inside the

counter prefab and just drag the Tomato

reference okay great let's go back

outside save now back in the code here

when the player interacts with it let's

just spawn it so let's call instantiate

pass in the Tomato prefab and now here

is a good question which is where

exactly do we spawn this we don't want

to spawn on this counter's origin

remember that the counter the way we set

it up the origin on the actual object is

over there on the bottom we don't want

to spawn the tomato inside the mesh that

would not make sense instead what we

want is to spawn up here so the next

question is okay so how do we get this

point on top of the counter one approach

would be to use a vector 3 directly in

the code that would work but not very

usable so a more designer friendly

method is to Simply use an empty game

object as a Target so on the counter

let's first go inside our prefab

and over here let's create an empty game

object inside of it let's call this the

counter top point

let's make sure to leave this one as

empty so no components just a transform

and now let's just position it so let's

lift it up by just about enough so let's

make sure we see so there you go just

about that so let's put it on position a

y of 1.3 all right so this point is

going to be our spawn point let's make

sure to save the prefab

then back in the code here let's add a

reference to our point

and for reference let's also use a

transform reference currently the

countertop point

okay now let's just come this line just

so the code compiles so we can drag the

reference back in the editor inside the

prefab let's just write the countertop

Point reference okay great so now here

when we call instantiate let's

instantiate it inside the countertop

point so this one's found the object so

let's say the transform for the Tomato

transform

and then we go inside this one and let's

just make sure we position it correctly

so let's put it on in local position of

vector 3.0 so this one put the object

exactly on top of our countertop point

also here very important don't make a

mistake make sure you're modifying the

low composition and not the global

position okay so with this let's test

over here in the editor let's go back

save our prefab and hit on play so here

we are let's approach a counter and

interact with it and if there you go it

does work the Tomato was indeed spawned

all right awesome okay so with this we

have pretty much our Basics working

we can move up to a counter we can

interact with it and spawn an object but

now let's say that we want to spawn a

different object so let's say now we

want to spawn some genes first of all

let's make the actual object so on the

Tomato let's press Ctrl D to duplicate

this one let's rename this to the cheese

block and let's go inside of it

now in here instead of the Tomato visual

let's drag here it is the cheeseboard

visual so let's use this one instead

okay there's our nice visual

let's make sure to save the prefab and

go back out and now let's say that we

want this one to spawn a tomato and this

one on the left to spawn some cheese so

let's override the prefab and over here

drag the cheese block and now if we hit

on play

can go up to this one yep there's a

tomato go this one any up there's some

cheese okay so it all looks great but

now let's say we want to know what

object we just spawned like what object

is on top of this spawn transform just

like this in the code all we have is a

transform reference so with this the

only way to know what type we spawned

would be if we had different prefabs for

every single object then we could

compare them one by one and see which

one this matches but then let's say what

if we wanted an actual string for the

object well then we would need to add

tons of fields for all these strings for

all of the objects then what about an

icon for each type once again we would

need tons of fields each one for each

icon but if we did it just like that

with a bunch of lists then they would be

separate that's not very good we should

have a proper way of defining our object

types and all the data related to them

so this is exactly where scriptable

objects come in these are objects you

can create in your project funnels which

are perfect for anything where you have

multiple instances of a type like for

example multiple weapons multiple armors

multiple recipes or maybe multiple

ingredients as usual I have a dedicated

video on script along objects they are

super useful definitely watch out for

more detail over here on let's just use

them so the first thing we're going to

need is to actually Define the type and

we do that in a c-sharp script so in our

scripts folder let's create new c-sharp

script call this the kitchen object so

now personally so is just what I like to

open to my scriptable object definitions

just to make it very clear that it's a

script mode object however this is not a

requirement it's just a naming room that

I like to follow and we're calling this

kitchen object because we're going to

use this to Define any kitchen object we

want to interact with

so that's going to be our ingredients

like for example the tomato and cheese

but also things like a plate and then

potentially you could Implement things

like a frying pan or framing signature

or anything like that so it's going to

represent any kind of kitchen object the

player can interact with Okay so let's

make the script and now let's open it

and over here okay first things first is

this is not a monobehavior instead let's

extend scriptable object and then

technically you can have functions

inside a straight ball object but for

now let's just get rid of this so just

an empty class and over here on let's

just Place whatever fields we need to

store whatever that we want so like I

said first we want a prefab so let's

make a public transform for our prefab

by the way here note how I am indeed

using public this is pretty much the one

exception to the room I only use

scripting objects as read-only data

containers I never write to them so

since I found that rule I usually make

the fields in the description object

public that way I can access them

directly without having to make a public

getter but if you want to feel free to

keep following the general rule of not

making anything public you could

definitely make this just a regular

serialized film then exposed with a get

function that would work personally I

just find it simpler to make it public

since I know that as a personal rule I

will never write to a script mode object

field okay so we have a transform for

our prefab let's also add a Sprite for

the icon Sprite and finally let's just

add a simple string for the object name

all right so we have our scribble object

definition we have all of the fields for

all of the data we want to store now how

do we actually create a scribble object

for that let's go up here before the

class name and we're going to add the

attribute so let's add the square

brackets and the attribute is the create

asset menu this takes some optional

parameters again I cover them in detail

in the dedicated script and objects

video for now let's just leave all the

parameters as empty just use defaults

and close the attribute okay so that's

it let's save this and go back into the

editor and over here if we go into the

project window click on the plus icon

and right up top yep we do see a kitchen

object so

so if we selected if there you go it

creates a brand new object inside of our

project files let's name this one tomato

and obviously let's keep our project

nice and organized so we don't want this

inside the scripts folder instead let's

make a proper folder so create a new

folder come with our scriptable objects

and then inside let's put a different

folder for each type so let's make

another subfolder call it the kitchen

object so and let's place the tomato

inside of it okay now with the Tomato

selected we can look in the inspector

and you can see yup it does have all of

the fields that we Define okay great so

now we can just assign them so this is

the tomatoes let's drag the Tomato

prefab for the icon Sprite let's find it

so there are Sprites included in the

regular assets so here is the Tomato

Sprite so it's inside the acids then

inside textures icons and we have all

the icons and finally for the readable

name let's just call it tomato alright

so that's it here we have a really nice

scribble object containing all the data

required for our tomato okay awesome

with that then we can now go back into

our clear counter script and here

instead of having a field for our tomato

prefab instead of this let's sort of

reference of type kitchen object so and

let's go on with kitchen object so and

then when spawning let's go inside our

scriptball object and just spawn the

prefab reference so this is going to be

the kitchen object transform then over

here in the editor let's go inside the

clear counter and let's assign the

Tomato Kitchen object okay so let's save

it and test

so here we are on let's approach hit any

up there you go it still spawns eat

tomato okay great now let's make another

type for our cheese block so let's

create a brand new kitchen object so

called the cheese block and again let's

assign first of all the prefab there it

is then for the Sprite of the cheese

walk and finally this is the cheese well

okay so now for example let's go into

the second one and on the second counter

let's override and say this one spawn a

cheese block so let's test so here we

are approach this one yep there's tomato

this one any of there's some cheese okay

great so everything is working so far

however the original problem that we're

trying to solve identifying the spawn

prefab we still don't have a solution

for that basically when we spawn a

prefab we need to know from which script

No Object this prefab came from so

essentially what I like to do is just

attach some reference to the scripting

object in our prefab however again

remember that scripting objects are not

mono behaviors so if I select the prefab

and I try dragging the description

object nope it does not work so what we

can do is just create a new script so

let's make a brand new c-sharp script

let's call it kitchen object

let's attach this to both prefab so both

the cheese and the block attach the same

one to both of them and let's open

and over here very simple let's just add

a serialized film for our kitchen object

so a serialized film of type

kitchen object so for the kitchen object

the cell

then let's also make a quick function to

expose it so we're going to return

kitchen object as so get kitchen object

so and we just return the kitchen object

as well yep just like this so now here

in the editor for the Tomato yep we've

got the film so let's say this one is a

tomato and the cheese block this one is

a cheese block now here obviously we

need to make very very sure to drag the

correct reference to the right scriven

object if you drag the wrong one like

for example over here on cheese you

would say this one is a tomato if you

did that then obviously you would get

some very weird results so make sure to

check and double check that you drag the

right preferences both over here on the

prefabs make sure they are referencing

the correct Circle object and on the

script module itself make sure they are

referencing the correct prefont okay so

now if you go here on the clear counter

we spawn our object okay great then on

this object we can do get component of

type kitchen object and then we can just

ask it to give us the kitchen object as

well so for example let's do a debug

download on this one

so inside you get the kitchen object to

sew and then let's print out the object

name all right so here we are let's

interact with this one and if there you

go interacted and spawn the tomato and

on this one yep interacted and spawned a

cheese block okay awesome we spawned a

transform prefab and we identify the

spawn object is indeed this type of

object all right so here we'll learn

about one of the most powerful ENT

features scribble objects these are

extremely useful for defining a type and

then creating multiple instances of that

type with whatever that we want so there

can be some ingredients like we have

here or it could be some weapons could

even be some NPC data maybe some Quest

data and so on it really is an insanely

very useful feature definitely go ahead

and watch a dedicated video on script on

objects then if you want you can also

watch some more videos where I've used

scriven objects for example in the

Minecraft crafting system using

scripting objects or the hydrogenated

crafting system which again also uses

scribdon objects okay so this is done

it's working great now let's continue to

the next lecture where we're going to

help the kitchen object know where it

belongs and help each counter know what

kitchen object is on top of it

hello and welcome I'm your code monkey

in this lecture we're going to create a

kitchen object parent meaning that the

kitchen object will know where it is and

the counter will know if something is on

it this is important so that later on we

can pick up a kitchen object from one

place and drop it in another okay so

here we have our player I can move

towards this counter interact with it

and yep spawn a tomato then on this

one's want some cheese okay great but I

cannot do anything else in fact if I

interact a bunch more times really all I

did was just spawn a whole bunch more

cheese so instead I want to be able to

spawn some cheese and then pick it up so

let's think about exactly what that

means we want a kitchen object to

essentially be placed on a specific

Place based on the design that we're

trying to implement we're never going to

have a kitchen object just randomly

thrown around the world we're not going

to have tomatoes all over the floor

instead the objects will always need to

be placed somewhere and that somewhere

can be either a counter or it can be

being held by the player so essentially

that means that each kitchen object is

going to have some kind of parent that

it's attached to we're going to make

sure the counter knows if there is a

kitchen object placed on top of it and

we're also going to make sure the

kitchen object itself knows where it is

so first let's do that logic over here

on the counter

so on the clear counter script let's

keep a field for a kitchen object

so just a simple private of type kitchen

object kitchen object

then when the player interacts with it

by the way we can get rid of these debug

transforms debug logs in all you need

them okay so when the plane interacts so

if the kitchen object is known

if so then we're going to spawn it then

when we spawn it let's assign it so this

one equals the kitchen object get

component of type kitchen object okay

so if that one is no we spawn it and we

assign it and just with this we should

have fixed the issue where we can spawn

infinite objects

so over here I can interact and now I've

interact a bunch more times

and now look in the hierarchy inside the

clear counter

and I go inside the counter top Point

nope there's only one tomato okay great

so with this basically we made the clear

counter know if there's something on top

of it

now let's do the other side so let's go

into the kitchen object and make sure

that it knows where it is so over here

on the kitchen object script

let's add a simple field for a counter

so private of type clear counter for the

clear counter

and now let's just basically make two

functions one to set it and one to get

it so a public void set clear counter

and we're going to receive a parameter

of type clear counter okay great and

then we're going to have a public return

a clear counter for the get clear

counter

and we're just going to return our clear

counter and on this one just set this

dark layer counter equals this layer

counter

all right so on this function we're

assigning this field and on this

function we're returning this field

so now back on the counter script we get

the kitchen object reference so on this

one let's call set clear counter and

pass it in this one

and if it is not known so if there's

something on top of this let's just do a

debug.log let's go on to the kitchen

object and get the clear counter

so we should be able to click once and

spawn an object and click twice and the

second time we should be able to see the

name of this layer counter

all right so over here let's approach

and click and yep it's spawn now click

again

and if we've got the message this one is

on the planet counter okay great so far

so good

so the counter knows if there's a

kitchen object on top of it and the

kitchen object itself knows where it is

now let's add some logic to be able to

change a parent counter it's over here

on the clear counter script we basically

just need to call the set layer counter

function with a different counter

reference so just for testing let's add

a serialized film for the second counter

so clear counter for the second clear

counter

now we're doing this just for testing

just make sure the logic Works before we

come up with a more General system

so just for testing let's come up with

some input and again for testing using

the lazy input manager to get something

quickly up and running is a great thing

so let's quickly get a button input on

the counter so let's make a private void

update

and for testing we only want the testing

to work on one counter so let's also add

up here just a ball testing

and then on update if we are testing and

we have the input.getkeydown on let's

say the T key

so if you have that then we can run some

kind of testing code so let's say for

example if the kitchen object does not

know so if we have something on top of

this kitchen counter let's go into the

kitchen object and call set counter and

let's pass in the second clear counter

so basically with this we should be able

to interact to spawn an object and then

press the T key and we should be able to

see that object be set to a different

parent

so here in the after I'll let you set

down let's say this one is our main

counter so let's drag a reference to the

second one the second higher counter

drag it and make this one the testing

script and also just to verify that it

worked over here and lets you a get on

the clear counter all right so let's

test and see

okay so here we are let's approach this

one interact and there you go spawn

tomato and now if I interact again yep

it says the tomato is on the similar

counter now if I press the testing key

if there go the Tomato was moved onto

the other counter

okay so the parent change the logic

worked however obviously we have two big

issues the first one is just a visual

you can see the object is still placed

on top of this counter even though

technically now it belongs to this one

and the second issue is that this

counter still thinks that it owns this

kitchen object and this other counter

does not know that it now owns this

object so we need to sort all of that

first for the visual it's actually very

simple

here when spawning we are spawning it

inside the counter top point and then

setting the alarm position to zero so

whenever we move to a different second

parent when we do that we can just ask

that second parent to return the

countertop point and move it there so

for that let's make a function to return

that

so public we're going to return

transform so get the kitchen object

follow transform so it's going to be our

countertop point

so let's return the counter top point

then let's go into the function on the

kitchen object when we set the clear

counter so over here on the kitchen

object on this function so we set the

color counter

then let's modify this transform.parent

go into the nuclear counter in order to

get the kitchen object funnel transform

and again let's make sure to set the low

composition back into Vector 3.0

okay so with this when we set the clear

counter to a different one it should

automatically teleport to the other

counter so let's test so here we are in

first let's interact with this one there

you go it's Pawn now if I press C

testing key and if there go it does move

visually okay great so far so good

however the counters still have the

wrong data by the way here's a quick

empty tub on the inspector you already

know that you can only see the public

and the serialized Fields however there

is actually a way to look at private

fields on the inspector on the top right

there's these three dots and if you

click on it over here you can modify it

into a debug inspector

and when you go into this one Yep this

one does show all the private fields

so you can see for example on the clear

counter so that's the right one this one

over here the kitchen object is indeed

assigned and we can go into the other

one and we can see this one has it as

null so debug inspector is really useful

in these kinds of cases if you want to

inspect any kind of private Fields you

can go to this and see it now let's swap

back into the regular inspector and

let's fix that issue by notifying the

counters that the object has changed

so over here basically we have two

options over here on the calendar

counter when we modify the parent when

we tell the kitchen object to go to a

new parent when we do that we can make

the new parent responsible to updating

itself or we can just make the kitchen

object itself be the one responsible for

notifying the new parent both approaches

can work personally I think it makes

more sense for the kitchen object to

handle itself

so we just call this function to set the

new parent and when this happens

basically this kitchen object needs to

tell the old parent that it is no longer

there and needs to tell the new parent

that it is on there so on the counter

let's make some function to set and get

a kitchen object

so over here on the calendar counter

script let's go down

let's make first one to set so public

void set kitchen object and receive a

kitchen object

and just do this dot kitchen object

equals this kitchen object okay great

then let's make a getter so public

return a kitchen object get the kitchen

object

and just return this kitchen object okay

then let's also make one just to clear

it so probably avoid clear kitchen

object

and this one just sets the kitchen

object into null

and finally just a nice sample function

to test if this counter has anything on

top so just a public Bowl has kitchen

object

and over here we just return if the

kitchen object is not known

okay so some four very simple functions

now if we go into our kitchen of the

script

over here when we tell it to change the

parent let's first go into the current

parent and clear it

so let's first of all do a quick test

for null so if this documentary counter

which is the current parent so if this

one is not null then we go into the

current parent so the clear counter and

we tell it to clear the kitchen object

and then we go into the new parent

and we tell new parent to set the

kitchen object and the kitchen object is

this one

now here will be very very important

don't make the mistake of clearing the

wrong counter keep in mind that over

here this documentary counter this

refers to the previous player counter

whereas the one in the parameter this is

the one this is the new one so make sure

you clear the kitchen object from the

previous clear counter before you assign

it and then you set it on the new clear

counter so be very very careful here

make sure you don't make mistakes

between the quote unquote old color

counter and the nuclear counter

okay so that's it basically we have this

function to set the nuclear counter so

set the new parent we clear the kitchen

object from the old player counter we

added a new one and we update the visual

now we can also add some nice safety

checks here just to make sure we never

make a mistake the kitchen object should

never be set to a parent that is already

holding something so before we set the

kitchen object before we do that let's

make sure that one is empty

so over here just do an if if the clear

counter so that's a new one if this one

has a kitchen object then it already has

something on there this should never

ever happen so let's see what debug.log

error and say counter already has a

kitchen object

we're going to eventually add tests to

make sure that this never ever happens

but having the air here won't be helpful

just in case we missed something

so far as the kitchen object we're going

to fire an error but this should never

happen so we just set the error update

to visual and so on

okay so finally let's just go over here

into the clear counter script and down

here we have the interact action so we

instantiate the kitchen object we're

currently repositioning it and then

we're setting this field assigning it to

this one now we made the kitchen object

responsible for doing all that for

modifying the position and for setting

the field so we don't need to do this

instead we really just need to go and

get the component of that

and just pass in set for your counter

and pass in as this one

so we no longer need all this now our

code is much more simple also

importantly up here we were previously

setting the color counter and then doing

a debug.log but when we set it a new one

that is actually going to clear this

field so if we leave this then this is

going to throw a null reference

exception so let's just get rid of the

slog here we normally need it okay so

let's test and see if all of our logic

is working

all right so here we are let's go to

this one interactive spawn it okay great

and once again we can look in the debug

inspector so let's put it on debug look

at this layer counter so that's the

right one and yep there you go it does

have the kitchen object and if I'm

looking the other one Yep this one has

no okay great

now if I press the testing key yep

visually it did change and if you look

at the counter so if you look at the old

ones that's the right one this one is at

no okay that's great correct and if you

look at the new one Yep this one does

have the reference all right awesome

so now that we are correctly changing

the kitchen object parent for example we

can now interact again with this one and

yep it does spawn a brand new one and of

course if we try moving it to the other

one then we should have our error as

intended this one is currently already

occupied the kitchen object so we should

not be able to drop something on there

but if I press the testing key if there

go nicer okay so that's great

we're basically going to fix this error

later on when we check to make sure the

object can only be spawned when it can

be spawned but for now all of our basic

logic is working we can spawn an object

and change a parent alright so with that

here we have added a really important

feature to our game that is the ability

to know where a kitchen object is now

the next step is to enable the player to

be able to pick it up and drop it

somewhere so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to enable

the player to pick up a kitchen object

and in doing so we're going to learn

about another awesome c-sharp feature

called interfaces

okay so right now with our game I can

already move the player I can approach a

counter and try to spawn an object and

with the testing key I can move it to a

different parent

so all of that logic is working now

let's make it work actually with the

player let's say when we interact once

we want to spawn it and if there's an

object already on top of it and I

interact again then I want to give it to

the player

okay so here on the clear counter script

we've got our interact function in order

to make that work we need to have a

reference to the player so I just passed

it in over here as an argument for our

interaction so just pass in the player

reference

now over here let's do the logic that I

send so if the kitchen object is known

so if there's nothing here then let's

spawn it okay great but if there is

something

then let's give the object to the player

so how we change the object parent is

just like what we did up here so let's

go into that one set the clear counter

and pass in deploy a reference except of

course this obviously does not work the

parameter on this function is supposed

to be of clear counter it does not work

with the type of player recently on the

logic that we built for setting the

parent and change the parent this whole

thing only works with the counter so it

does not work with any other type so we

cannot set the player as a parent now to

solve this problem is exactly where

c-sharp interfaces come in again I have

a video going through them in detail

definitely watch it and learn everything

about interfaces basically what it is is

a contract you define some functions in

the interface and then any type can

Implement that interface and you can

write some code that works with the

interface which in turn means that the

code won't work with any type as long as

it implements that interface

so in this specific example we're going

to make an interface to represent a

kitchen object parent then we're going

to implement that interface on both the

counter and the player and that way both

of them won't be able to be parents of a

kitchen object so let's do exactly that

now the first thing we do to Define an

interface is Let's Make a c-sharp script

so let's right click create new c-sharp

script and now the standard is to start

interface names with the capital I and

then the name so in this case let's name

it I

kitchen object parents

and let's open it okay so now to make an

interface first of all this does not

extend mono Behavior nope and secondly

this is not a class instead this is an

interface now like I said an interface

is essentially a contract where each

class that implements that interface

must follow that contract

what that really means is you can define

a bunch of functions here by the way

quick note you can also define

properties but not Fields I cover all of

that in the dedicated interface video

but for now here we just want some

functions like for example let's just

put all of the parent functions that we

made previously on the counter

so over here on the corner counter a

while ago we made all these functions

that we needed to make it work as a

kitchen object parent

so we got the transform set kitchen

object get it clear it then has it so

let's just copy all this and paste it

over here on the interface

however one important note is on the

interfaces you don't actually include

any function implementation

the implementation is up to the class

that implements this interface although

again I should also point out another

quick note as of c-sharp 7 you can

include a default implementation but

that's for more advanced use cases so

for here let's just use the basic and

not apply any default implementation

right here so we just defined the

function

and put a semicolon so just like this

just the function definition with the

exact signature so just like this okay

so now that we have defined our

interface and all the functions that we

want to have with this now let's go on

to the counter script so over here on

the clear counter script over here let's

implement the interface and the way we

do that is pretty much exactly the same

as by extending a class so over here we

are already extending Model Behavior

then let's set a comment and let's say

we are also implementing the ikitchen

object parent interface

so right now you might be wondering so

this is pretty much the same thing as

extending a base class and kind of

except for one huge difference

when extending a base class you can only

have a single Base Class like for

example over here we have monobehavior

you cannot extend multiple base classes

there can only be one however when it

comes to interfaces you can Implement as

many interfaces as you want so over here

we have defined our interface and right

now we don't even have any errors that's

because we already implemented pretty

much all the exact functions also Visual

Studio has a really nice software icon

over here on the left side it is

basically saying that this function this

implementation is based on the interface

but let's see what happens if I decide

to comment out these functions so if I

comment out all of this

and if there we go over here we have an

error it is telling us that this class

does not implement the members for the

interface like I said an interface is

like a contract so you must write all of

the functions included in the interface

so we must Implement these so let's get

rid of the comments okay

with this our interface is perfectly

working over here on the calendar

counter

now let's just go into the kitchen

object over here on this script

for now we're still working with the

type clear counter so let's just

refactor this to instead of working with

a clear counter let's make it work with

a kitchen object parent

so let's just change this from type that

to Kitchen object parent let's also

rename this so let's use Ctrl RR for the

kitchen object parent

then we've got a function to return the

kitchen object okay that's good for this

one instead of setting your counter and

let's once again rename this to set

kitchen object parent

and inside again we receive of type I

kitchen object parent

then let's also rename the parameter to

Kitchen object parents

okay so all the names here I have

changed okay they're all correct we set

it we assign it over here instead of

counter let's say kitchen object parent

already has that so just like this

and finally down here let's return I

kitchen object parent and rename this to

get kitchen object parent

and we return that

all right so we have changed everything

I can even do control F to search for

counter and nope there's no instance of

any counter so all this code has now

been Rewritten to work with a kitchen

object parent

something like this everything should be

working it's only the same as previously

we have no errors here

and over here on the clear counter we

just have this error on the player and

let's fix this in a little bit for now

let's just comment it let's just test it

out to see if everything still works

exactly the same as previously also one

final thing since we modified the

interact function over here on the

player class when we have the interact

we just need to pass in this reference

okay so let's test

all right so here we are let's approach

this one interact yep there it is now

let me press the testing key and if

there go it does move okay so everything

is still working exactly the same as

previously once again another successful

refactoring now here comes the magical

moment so right now again everything is

still working exactly the same as

previously so we can only have counters

as parents but now let's go over here

onto the player script and over here

let's also implement the same interface

so let's implement the eye kitchen

object parent

and again as usual we have our error so

we need to implement this

also again Visual Studio is very helpful

so we can click on the light bulb icon

and let's say implement the interface

and if we scroll down here it will

automatically create all these functions

so let's just actually Implement them

so for implementing this interface the

code is really going to be exactly the

same

so let's go up here into the clear

counter let's go down find all of these

functions let's copy them and on the

player let's paste them down here at the

bottom

so we just need to also pick up the

kitchen object as well as a reference to

the top point so over here on the clear

counter and let's just grab both those

so let's just grab the kitchen object so

go into the player and over here let's

add a film for the kitchen object and

finally let's add another one for the

counter top point so over here a

serialized film for the counter top

point

except obviously the player is not a

counter so this name makes no sense on

the player so let's just quickly rename

this and set call it kitchen object home

point

okay here we have our new name we've got

the kitchen object and down here all of

our functions they're all working no

errors all right now let's just assign

this in the editor

so over here let's just go into our

player there's a player script and

requires a reference to the kitchen

object home point

so for that let's do it just like we did

for the Counterpoint so inside the

player let's create an empty game object

currently the kitchen object hold points

and I always just position it just

slightly in front of the player

so let's put it on a x of 0 on a y of

1.3 and on a set of one so there you go

just ahead that's where the player is

going to be holding the objects finally

over here on the player let's just drag

that reference

okay so far so good also one note here

like I mentioned previously in order to

implement the interface it requires you

to write the function code

basically what this means is that

different objects can implement the

exact same interface whilst having

different implementations

so for example over here on the player

when setting the kitchen object

perhaps over here you could play some

kind of item grab animation or maybe

when clearing a kitchen object you could

do some kind of logging

the only thing that needs to match

perfectly is just the function signature

and the function signature that means

the return type as well as the name and

any parameters the implementation itself

that is up to the class that wants to

implement that interface but in this

case we wanted to behave pretty much

exam the same way so like this it should

be working

so we can now go back here onto the

clear counter script and okay we have

our interaction all right great

so if there's nothing we're going to

spawn it and if there is something on

top of it we want to give it to the

player so now let's go into the kitchen

object and call the function set kitchen

object parent and pass in the play

reference

and that's it no errors because again

this takes a parameter of type kitchen

object parent and the player does

implement that interface so that's all

valid

now with this let's says and see if our

code is working

alright so here we are and let's

interact with this counter and there you

go the object has been spawned and now

if I interact again if they're going to

look that the player picked up the

object and since our logic is using a

transform home Point as the parent the

player is automatically carrying this

tomato alright awesome so this is really

great

now over here on the counter we no

longer need all of this testing code we

now have the ability to actually pick up

objects from the player so let's get rid

of all this so we don't need this

testing code don't need a reference to

the second color counter or the testing

okay great so here you can see the power

of interfaces by just implementing the

interface we can now place an item

anywhere we want and importantly on any

type we want

so the counter can hold a kitchen object

the player can also hold it we could

make a dog character and make it hold a

kitchen object we could make a vehicle

hold it or anything again interfaces are

really really awesome one of the best C

sharp features definitely go ahead pause

this course for now and watch a

dedicated video on them you should be

very very familiar with interfaces they

will help you in making all kinds of

systems and games

if you want to see a clear example of

the power of interface you can go watch

my how to interact with NPC's video that

video takes advantage of interface to

make sure that the player can interact

with any kind of object alright so

thanks to interface we can now change

the parent of the kitchen object and put

it on either a counter or the player now

in the next lecture let's make a proper

different counter type

hello and welcome I'm your code monkey

in this lecture we're going to create a

different counter type from where we can

grab some ingredients

okay so far here we have our character

working and we have an empty counter and

by interacting with it we can spawn an

object but obviously that's not the

behavior we want in the final game we

want different counter types that do

different things the cleaner counter

should only be used as a place for

putting down and grabbing objects it

should not spawn anything

so let's build a new counter type

and for that one option is to make a

brand new prefab and build it on from

scratch another option is we can

duplicate this counter and change a

bunch of things or there's a third

option that was added in recent TNT

versions

you can now have what is called prefab

variants meaning that we can have a base

counter and then we can make variants

for all the types so let's do exactly

that to learn about prefab variants now

first let's duplicate this one just so

we don't lose any changes

let's rename this prefab to underscore

base counter

no I'd like to add an underscore just so

that the bass prefab is on top since

this window is sorted alphabetically

now let's go inside the base counter

let's go into the scene view so here it

is

and recently over here we only want to

have all of the things that all of the

counters will have so all the counters

will have a boxing ladder only the same

shape so that's good they will also all

have a counter top point

however for the visual different

counters will have different Visions so

let's get rid of this same thing for the

selected let's get rid of this

and on the actual object different

encounters will have different Scripts

so let's also get rid of this

okay so that's it this is the base

counter it only has all the things that

every single encounter will have so

let's go ahead save this prefab go back

outside and now let's right click on the

base counter

and go into create and over here let's

scroll down and find the prefab variant

now let's name this the clear counter

except obviously we can't have two

different names so let's put this one

into backup we're going to get rid of

this one in a little bit

so on the very end let's name it clear

counter

let's open up this variant

and now here let's add everything just

like we had on the own player counter so

since it's going to be exactly let's

actually go inside the backup one so

here let's just copy the visual in the

selected so let's copy this

go back inside the clear counter variant

and over here only let's paste it so

Ctrl V

see if there it is he selected any

visual

finally just scripts over here let's add

the clear counter script

and now let's just write the references

so the kitchen object we're actually

going to remove this in a little bit but

for now let's assign it the counter top

Point Let's drag it and on the selected

we also need to drag the kitchen counter

reference

okay so here is our clear counter as a

variant of the base counter so let's go

ahead save this and go back outside

and now we can finally delete the owned

prefab of the clear counter so let's go

ahead and delete this

and of course over here on the scene

we've got some broken prefabs so let's

get rid of both these and let's drop the

clear counter variant so let's drop it

place it over here so let's put it on X

of 0 y of zero and Z of 3.5

okay so that's the clear counter and

let's just put another one to the side

and perfectly on the side so on an X of

minus 1.5 okay now we can begin making

our container counter

so for that once again let's make a

variant so right click on the base

counter and go into create and let's

create a prefab variant

call this the container counter

and let's go inside of it now here first

thing we need is the visual so let's go

inside our assets we've got the prefab

visuals inside we have the counters

visuals and let's find the container

counter so let's drag it inside again

for the low composition make sure it's

on zero zero zero okay great

then we need to make the selected so

let's duplicate this visual let's rename

this to selecton

let's go inside on all of these

then let's modify the material for the

selected material so let's click on the

circle icon and select the counter

select material okay we've got our nice

little ghost icon

and just like we did previously let's

start with these disabled so all these

game options disabled so they are hidden

and on the selected let's make sure the

scale is one percent bigger so 1.01

also in the selected this one does not

need an animator so let's get rid of

this

now let's add the selected counter

visual and obviously for this one we're

eventually going to need to refactor it

to support multiple visual objects as

you can see this selected has multiple

but for now just make sure that it works

let's just drag just the first one okay

great

so our container counter has been built

the only thing that we need is the main

logic script so let's do that

let's go into our scripts folder let's

create a brand new c-sharp script

name it the container counter

and let's select the main game object

attach a script and let's open it

alright so now here let's first think

what we want for this counter we want

the player to interact with it and when

it does we want to spawn an ingredient

and give it to the player so that means

that we're going to want pretty much the

exact same behavior that we made over

here on the clear counter so when the

player interacts we spawn and we give it

to the player so let's actually copy all

of this code let's go into the Container

counter and over here let's face this

we just need to grab the references to

the kitchen object and the kitchen

object as so so again just like we did

on the container counter let's copy all

these references

and over here let's paste all of them

and of course here we have an error in

order for this work this needs to

implement our interface and let's do

exactly that so let's implement the eye

kitchen object parent

and back in the clear counter let's just

copy the exact same code so all of these

functions let's just copy them and on

the container counter just paste them

okay great

so we don't have any more errors here so

everything should work we should be able

to interact with the container counter

and we should be able to see an object

being spawned on top of it

over here in the editor let's just make

sure to assign it so let's assign a

default kitchen object so let's say

tomato and the counter top Point Let's

drag the reference and okay everything

else should be working so over here on

the selected we've got the visual game

object on the container counter we've

got this okay great so let's go outside

into scene View

and over here let's just Place some

container counters so let's drag one up

there

let's place it on an X of 1.5 on a y of

0 and Z of 3.5 and let's also Place

another one down here so let's rotate it

to face it upwards

okay so on position zero zero minus five

okay great

and let's make them spawn different

things

so on this one up here let's actually

spawn a cheese block and on this one

down here let's one tomato so let's also

modify the icon here

so from cheese block and let's put a

tomato icon so here it is

okay we've got two counters and two

clear counters so let's test

so here we are and if I approach a

container counter and I press the

interact button and nope nothing

happened we cannot interact with that at

all even the selection visual even that

one is broken so as I approach note the

visual is not showing up

now the reason for this is actually

pretty obvious

if we go over here on the player script

down here when we're handling our

interactions so let's go into the handle

interactions function

over here we are doing a recast and we

are trying to get component of type

clear counter

so basically we're not doing anything if

that object has a container counter

instead of a clear counter so again we

have a similar issue to the one that we

had in the object parent logic basically

we have two types a clear counter and a

container counter and we want the player

to be able to interact with both them

so as a solution for this exact same

problem we could also Implement an

interface just like we did that would

work that would enable the player to

interact with multiple counters but in

this case since the counters are all

very similar very related objects

they're all going to be kitchen counters

as opposed to object parents where the

player and encounter are completely

different

in this case since they are all very

similar a better approach is actually to

use inheritance now here I should point

out that inheritance is one of those

things that is simultaneously very

powerful but also very dangerous usually

beginners get really excited when they

first hear about inheritance but after

gaining some experience they start to

see the massive downsides

one funny joke about it is let's say you

want to write some code that all it

needs is a Banana class but because of

messy inheritance you end up with a

monkey and the entire jungle behind it

basically the banana extends a monkey

which extends a tree which extends the

jungle and so on so you just want a

small thing but because of a complex

inheritance you end up picking up a huge

object some of that to say inheritance

is something you must use very very

carefully it's a powerful tool

definitely but you need to make sure

that you absolutely use it in the right

approach for the problem you're trying

to solve now in this case like I said

since all of the counters are going to

be very closely related in this case it

does make sense

and of course in the future if that does

change we can always refactor

if you're a beginner definitely go ahead

and research a bit more on c-sharp

inheritance the pros and cons

I don't have any dedicated video on that

topic myself but if you search I'm sure

you'll find tons of content again it's a

very powerful but also very dangerous

tool so definitely use it wisely

over here let's make sure we rise so

let's use it

first thing we need to do is to find the

base counter class so let's create a new

c-sharp script let's call it the base

counter

so over here on the script let's get rid

of the functions we don't want any

default functions and let's also make

sure that we do extend mono Behavior we

do want that we still want to use this

as a component

so let's leave the script just like this

let's save it

then let's go over here into the clear

counter script

and on this one instead of extending

Model Behavior let's extend the base

counter

okay that's it that's the only change

and now let's go into the Container

counter and over here same thing let's

extend the base counter inside of Model

Behavior so now both these counters

extend the exact same base counter

script so now if we go into the player

score so here we are on the player

script and on the handle interactions

function over here instead of trying to

get a component of type player counter

let's try to get component of type base

counter so let's also rename the so

control RR to rename rename this to base

counter and of course we need to rename

all these references that expect a clear

counter instead of the base counter so

over here for the selected counter let's

modify the type to base counter then

also up here when we've got the event RX

let's modify the type okay

so over here we have the interactor

let's leave this for a bit let's go down

and let's fix this issue so let's go

down into that function to set the

selected counter instead of this time

let's receive a base counter

okay so all of these errors have been

solved there's only one left and it's

this one the interact

we see this error because obviously the

base less does not have any kind of

interact method so let's add that

now for adding methods to a base layer

it's sectionally very simple it's really

just like any other method so first the

accessor for the interact we want the

player to be able to access it so let's

make it public

and also since we're talking about

inheritance I should probably mention

the other accessor now you already know

about public and you also already know

about private but there's another one

you might not know which is called

protected

basically this one means that whatever

function we defined with this successor

it is going to be accessible to this

class and any class that extends it so

for example if we had a function that

was protected the clear counter could

count this function because it does

extend this Base Class however the

player would not be able to call this

because it is protected now in our case

for the interact action we do want to

play the comet so let's make it public

just like we had previously then another

keyword for every function that we want

the chunk lesses to be able to implement

in their own way we can Define it as

virtual

and finally the function signature as

normal so for the interact we made a

return void call it interact and we

received a player argument

okay so that's it that's our basic

signature

for the implementation let's leave it

empty over here on the base counter so

by default it's not going to do anything

in the game design that we're building

we're never actually going to end up

with anything like this

so if you want for safety we can just

add a debug.log error

to say just base counter.interact

because this should never be triggered

also I shouldn't point out for a more

advanced method

instead of making it virtual you could

make it abstract and basically what that

does is that forces all the classes to

implement their own implementation

so you would make this extract and just

put it just like this as if this were an

interface but in doing so you would also

need to define a base counter as

abstract and so on so basically this is

a more advanced method so don't worry

about it for now let's keep it a bit

more simple so let's make it just

virtual void interact okay great

so we have this let's save this and now

if we go on the calendar counter

over here on the interact notice how we

have a green screen line

basically this is a warning it's telling

us that we are hiding the base function

now in reality we don't want to hide it

instead we want to override it so before

the void before the return type we just

have the keyword override

and Yep this will now override the base

function so when the player interacts

with an object of type based counter and

that object is actually a clear counter

when the player calls the interact

function instead of running this code

it's actually going to run this code

now let's do the same thing on the

container counter so over here let's

also add the

keyword override to override the base

function okay great so we have no errors

here and on the player we also don't

have any more errors since that one does

now implement the interact function

so with this one it says and everything

should still be working so over here

let's approach the entire counter and

let's interact with it any up it does

work it spawn some cheese and down here

yep it's on the tomato and then if we go

on to the empty counter and interact and

yep it still works okay so here we added

the ability to interact with two

different counter types alright great

now knows how the selected logic isn't

really working well you can see the

container counters they are both

selected even though the player is not

looking at them and actually if I

approach it then it actually becomes

deselected basically the reason for that

is because these selected square of that

one is still referencing the clear

counter inside of the base counter

so right now it's only being selected

when the sunlight the counter is known

so that is why as I approach it actually

hides itself so let's fix this let's go

inside the container counter prefab and

inside we've got the selected any up

over there we have a reference to that

so let's open up this script and over

here all we need to do is just modify

this time so let's make it a type base

counter and let's rename this to base

counter

okay that's the only change we need

and by the way since we're here let's

also fix the other issue the issue we

had where we need to support more than

one visual game object

so instead of having a field of type

just game object let's receive a game

object ring

so let's modify this to game object

array

and then down here on the show hide is

actually very simple so let's just do a

four inch game object for the visual

game object

in the visual game object ring we go

inside set it to true and on this one we

set it to false

okay that's it super simple

now let's just update the prefabs so

first over here on the container counter

let's write the container counter

reference as the base counter okay great

and for divisions let's just drag all of

them

so let's write the counters only drag it

on top then the counter hole drag it on

top then the single door drag it and the

black drag it and also by the way over

here on this counter this one actually

has an objects right

this is the actual Sprite in there but

for the selected we really don't want

that so if I enable this game object

here we've got the object Sprite let's

actually delete this

we don't need the actual icon Sprite to

be highlighted so let's leave it just

like this so we only have these four

objects and all four of them are on the

list

okay that's right so all the references

in here they're all working perfectly

so let's go back outside let's save the

prefab let's go inside the empty clear

counter

and on this one same thing on the

selected let's Drag The Insider

reference and for the base counter let's

also drag that reference

okay so let's go outside save it and

let's test

and now let's see if the selected Works

once I approach this one yep it works

yep it works and on this one yep it

works and down here yep it works all

right awesome so we can interact and we

can highlight our selection okay

everything is working great so now that

all the code is working we can inspect

the code to see if we can refactor

anything

we can see for example if there's any

kind of common logic that all of the

counters share that we should probably

write in the base counter

and you can see right away that both the

clear counter and the container counter

both of them implement the kitchen

object parent interface that behavior is

something that all of the encounters

will share

so instead of defining it on each

counter itself let's actually do it on

the base class instead

so let's get rid of the interface

implementation here and also on the

container counter let's get rid of that

and set on base counter and let's

Implement that one so I catch an object

parent and for the functions let's do

the same thing so let's cut this one

from here and let's paste it on the base

counter

it's okay now we need these two points

so let's go ahead copy all of this let's

go into the base counter and paste in

except for the base one doesn't need a

kitchen object so so just the counter

top point and the kitchen object

okay so there are no errors on this one

let's go into the container

let's get rid of the kitchen object and

the counter top Point okay great

now we see an error but before we worry

about that let's actually go into the

clear counter and let's do the same

thing so let's get rid of this get rid

of this and down here get rid of all

these functions

okay so now the counter scripts are much

much more simple

all of the common code is now written

directly on the base counter

now for solving this the container

counter needs to know if there's a

kitchen object on top of it so now here

we have an interesting question with two

possible approaches

basically we need access to this object

so one approach would be to make this

protected like I said protected means

that any classes that extend this base

counter class any of those classes can

then modify that field something like

this yep there is no more errors that's

one approach

and the other approach is to instead

keep this one as private and whenever we

want to interact with it we simply

interact through these functions both

approaches can work and when in doubt as

usual you should probably go with the

more limited option so let's leave it as

private and work with these functions

and send

over here on the container counter

instead of testing if the kitchen object

is no let's just test has kitchen object

so if it does not have a kitchen object

then we're going to spawn it and for

spawning over here we could grab the

actual transform funnel

so this one up here we could call this

function to get it or since that is

actually going to be handled

automatically when we call this function

to set the parent then let's actually

not use this at all

so we just spawn it and set the kitchen

object parent okay great

so now let's just look at the clear

counter for this one like I said it's

not really meant to spawn anything solid

sectionally remove all of this code

this one is only going to serve to pick

up and drop items we're going to handle

that in the next lecture but for now

let's just go back into the Container

counter and let's do the proper logic

that I mentioned in the beginning

basically on this one we want to spawn

the object and we want to immediately

give it to the player so when we call

set kitchen object parent instead of

passing in this let's pass in the player

reference

and that's really it for the container

counter this is all we're going to do so

the player interacts and it spawns an

object and gives it to the player okay

so that's it with this as you can see

the code for all of our counters is much

much more simplified so basically it

only handles the logic related to that

specific counter everything else is on

the base counter so let's test this

so here we are and if I approach the

counter interact any of their go spawn

some cheese and gave it to the player

okay great now just for fun when I made

these assets I shall include a nice

animation

so if you go inside the container

counter over here on the visual note how

this already has an animator with an

animator control and attached to it

you can double click to open it up and

over here you can see it's very simple

basically just has two animations one is

the container close and one is container

opening and closing these transitions

are basically triggered by this

parameter this is a trigger parameter so

when triggers goes into the open close

and when this one ends goes back into

closed so let's just quickly add these

nice animations however again as usual

let's make sure to write some good clean

code so let's not add the visual over

here on the logic script instead let's

make a proper new script over here let's

create a new c-sharp script

call this the container counter visual

okay now we want to attach this only to

the visual game object so only this one

let's attach okay

and over here the first thing we need is

to get the animator

so let's sort of film for the animator

and since it's on the exact same object

we can just make an awake and get

component of type animator

and we just assigned this field okay

so with this we have the animator now we

just need to know when we should play

the animation so let's go over here on

the container counter script and

basically let's make an event that we're

going to fire when the player grabs an

object

so let's make a public event of time

let's stick with the standard so let's

use event handler inside using system

okay

let's name this on player grabbed object

then down here when the player interacts

and gets an object let's fire off this

event so invoke

let's invoke with this and event RX dot

empty

okay so we are firing off this event

and over here on the visual first we

need the film for the container counter

so let's set it up here let's add a

serialized field of tribe container

counter

okay we have this build now let's listen

to the event but again we're accessing

an external reference so let's make sure

to do it on start and not on awake

so let's go into this one and listen to

the on player grabbed object event okay

so here we have the event and it's over

here that we want to access the animator

and call set trigger in order to play

the animation again when working with

animator parameters suddenly we do need

to use strings there's no way around

that but at least we can make it a bit

more clean by defining a constant

so here a private con string call it

open close and let's make sure to use

the exact same parameter name so open

close

and then down here on the set trigger

let's call this trigger

okay so that said some very simple

visual logic

and now over here inside the prefab all

we need is to drag the container counter

reference so let's drag it also make

sure that it has the animator and the

animated controller so with that

everything should already be set up so

let's go back into the scenes save the

changes and let's hit on play

so here we are and if I go towards the

tomato and interact any of that I go it

plays a nice little animation alright

awesome okay so here we created a brand

new counter type and we refactored our

interact code to be able to interact

with any counter type the player can

interact with the container counter to

pick up an object now the next obvious

thing that we need is to enable the

player to drop an object on the clear

counter so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to enable

the player to pick up and drop objects

okay so we already have the player

working I can approach this container

counter interact with it and yep the

player picks up something now that's

left is being able to put our shade

clear counter and being able to drop

this object so let's do that

let's go over here on the clear counter

script and when we interact with it

we're going to do a bit of logic first

let's just check if this counter is

empty meaning if there is no kitchen

object on it so let's test if has

kitchen object or if not so let's say if

we don't have a kitchen object then

there is no kitchen object here

and if not then there is a kitchen

object here

okay these are the two valid options

so if there is nothing here then let's

check the player itself so we go into

the player and we can ask the same

question so it has kitchen object

so if the player is carrying something

so over here the player is carrying

something

if so then basically we just want to

drop that object from the player and

drop it in here so that's very simple we

just go into the player we get the

kitchen object that the player is

holding and we just modify the kitchen

object parent onto this object

all right so that's it just with this it

should already be working let's do a

quick test before we handle the rest of

the interactions

okay so here moving the player and if I

just interact with a clear counter and

nope nothing happens okay great since

the player is not carrying anything nope

nothing happens all right great

now let's pick up something from the

container counter okay so now the player

is carrying a tomato approaching clear

counter press a button and yep there you

go there it is alright Awesome

everything worked

now this is an excellent point to know

just how easy this was to implement and

the reason why it was so easy was

because we focus hard on running some

good clean code for how the object and

the appearance system works because we

took some time to think about that it

was now very easy to implement this

brand new action so this is a very very

clear example of the power of writing

good clean code okay so with that now

let's implement the rest so over here

there's no kitchen object here and the

player is carrying something but if not

we've got the L so player has nothing

so if the player doesn't have anything

so let's not do anything so player not

carrying anything

so those are all the possible States up

there and then down here if there is a

kitchen object on this layer counter if

so then let's check if the player has a

kitchen object

so in this deep layer is carrying

something

and if not

then the player is not carrying anything

so basically if there is a kitchen

object here and the player is carrying

something if so then we don't want to do

anything since we can't give the player

two items however if there is a kitchen

object here and the player is not

carrying anything then we want to give

it to the player so let's just get the

kitchen object the one that is on this

clear counter

and let's do the exact same thing so set

the parent and set the parent onto the

player okay so that's it as you can see

some very simple logic so let's test

okay here we are and if we interact nope

nothing happens okay great now pick up a

tomato go there drop it yep there it is

now if I interact again yeah there you

go I picked it up again so I can go

somewhere pick it up drop it and

everything works perfectly all right

awesome

now the last thing that we need to fix

is the container counter

right now it's giving out an object

every time even if the player has

something so if I pick up the other

works now if I pick up again there you

go we've got our nice helpful error this

should never happen

so let's add some nice checks

so over here on the container counter

okay we have our interaction

and before we spawn anything let's just

see if the player can pick up something

so once again very simple let's just go

into the player and we check does the

player have a kitchen object if so we're

not going to give it anything but if the

pointer does not have a kitchen object

then yep the player picks it up and we

give it the object

okay so that's it it's this simple Let's

test

so here we are let's pick up some cheese

okay great now pick up another one and

nope nothing happens okay great we're

already carrying something so we cannot

drop anything now drop it in there now

pick up a tomato any of it works I can

pick it up drop it and yep everything

works okay great let you see one more

thing

over here the container counter is

spawning the object and the object is

the one that we assigned

so over here in scene view we've got the

container counter this one is placed on

the scene and we made an override to

spawn a cheese block

technically we could keep doing this

pretty much just duplicate objects

modify the Sprite modify over here the

kitchen object that would work but

another better approach would be to

Simply make some prefab variants and yep

that does work you can make a variant of

a variant so let's do examine that over

here on the container counter let's

right click going to create and let's

create another prefab variant and let's

say container counter this one will be

the Tomato now let's go inside the

prefab and over here make sure it has

the kitchen object for the Tomato okay

great and over there on the Sprite so

let's find the object Sprite and choose

the Tomato Sprite so there you go this

one okay let's exit and Save

all right now once again let's right

click on the container and let's make it

another one this is going to be the one

for the cheese block

so let's go inside of it and over here

modify it for the cheese block and

inside the actual visual let's modify

the Sprite and sectionally down so the

cheese block okay great let's go back

outside

and since we're here doing this let's

make all of the other grab my objects

from the containers

so let's first make the kitchen object a

so so let's go over here we can right

click go into create create new kitchen

object so let's make one for the brand

then let's see if we get this one we're

going to have a cabbage and finally

we're going to have the meat Patty

uncooked

all right so now let's make sure to

assign all the data for all these script

along objects

first we need to make the actual kitchen

object so let's duplicate tomato name

this one bread let's go inside of it

and first for the kitchen object the

song Let's make sure to drag the correct

one okay there's the bread and for the

visual this one is not a tomato so let's

go inside our visual acids inside the

prefab visuals let's pick up the bread

visual okay there it is

that's all we need so let's go outside

save the changes and then select the

bread scripting object drag the prefab

reference okay for the Sprite this is

the bread and finally just call it bread

okay let's do the same thing for the

other one so next up for the Cabbage

let's do the Cabbage drag the Cabbage

script object let's go inside and modify

the visual so the Cabbage visual

okay that's it

then on the Cabbage scorpion object drag

the reference for the prefab let's

assign the Sprite and finally give it a

name cabbage

and finally the meat Patty and cooked so

let's do that one so let's duplicate it

name it meet Patty uncooked

let's go inside modify the kitchen

object so for this one and for the

visual let's select here it is the meat

Patty uncooked

okay let's go back outside and on the

escort mode object

let's just drag the prefab

assign the Sprites so this one is the

uncooked so it's this one

and finally meet Patty uncooked okay

great so we added all of these squared

more objects

we also have the pre-files with the

visuals and the electric scripts now

let's just make the container counter so

once again let's create another variant

so prefab variant this one is for let's

say for the brand

then let's make all the other ones

already so let's go make another prefab

variant

this one is going to be for the meat

Patty uncooked

and finally another variant also here

make sure you're creating a variant of

the container counter don't make an

accident of creating a variant of

something else let's make another

variant one final one

and this one is going to be for the

cabbage

okay we have all the variants now let's

just sign them so let's go inside the

bread and over there modify the

description object for the brand and for

the icon modify for the bread icon okay

let's go to the Cabbage save the changes

modify that one for the cabbage

go into the icon and modify the icon and

finally the meat Patty uncooked let's go

ahead modify this one for that one and

the icon put it on that one all right

everything is working

now let's just place them over here in

our scene so let's get rid of the ones

that we made some overrides

so let's get rid of that container

counter and set for that one let's drag

the cheese block put it right in there

let's put it on X 1.5 y of 0 Z of 3.5

okay

then down here for this one let's put

the Cabbage next to it let's rotate it

to face upwards

so like that let's put it on next of

minus 1.5 y of 0 and -5 on the Zen then

for tomato let's get rid of this one and

use the proper tomato one

so let's rotate it put it on an X of 0 y

0 and -5

okay next we want some bread so let's

put the bread up here on the left side

let's put it on X of minus three zero on

the Y and 3.5 on the Zen

and finally the meat Patty and Coke

let's put it over here a bit more on the

side

let's put it over here on X of 7.50 and

3.5 alright so we have positioned all of

them let's just make some more clear

counters so we can actually place the

objects so let's put this one over here

on minus 4.5 this one over there let's

also put some counters let's say one on

the right side and a bunch more down

here let's rotate them upwards

let's put this one on 1.5 minus 5.

and one more over here on the side

okay great so we have all of our

container counters as well as a bunch of

clear counters so let's test and make

sure that everything works okay so here

we are let's go down pick up a tomato

yep there's tomato now a cabbage yep

there's a cabbage now some bread there's

some bread and some cheese there's some

cheese and some meat and yep there's

some meat all right Awesome everything

works

so with this over here we added the

ability to pick up and drop objects on

an empty container and spawn them from

all kinds of container counters now in

the next lecture let's build the counter

we can interact with in a very

interesting way

hello and welcome I'm your code monkey

in this lecture we're going to create a

cutting counter so this is going to be a

counter where we can place an object

like for example tomato and after doing

a secondary interaction we can slice it

however before we do that let's just fix

one slightly annoying issue

so right now the player is walking

around okay that's great I can approach

a counter and interact with it that's

great however if I approach account from

the sign look how the player is pointing

towards the right and if I press the

double key I can indeed select it but

the player does not rotate to face the

counter so that's just a minor visual

issue but still I'd like to fix it so

let's do that very quickly basically the

issue is over here on our player script

so we scroll down and find our handle

movement function okay

so here we were doing a bunch of

Capstone cans in order to fix the

problem with the diagonal movement so

you try to move in One Direction if not

try to move in just one of those and if

we can move then we assign a move

Direction and then move it basically the

problem that we have here is that if I

press W to face towards the counter then

over here when we do this logic so it's

going to first attempt the X movement

only and the x is going to be zero so

the move there X is going to be zero

zero zero so it won't actually move

anywhere which means it won't be able to

move so this one becomes true which then

sets the move direction to zero zero

zero which then down here when we have

our rotation it's not actually going to

rotate to anything so we want the player

to still not go through any objects but

we only want to modify the move there

over here if we actually move in any of

these directions so the solution is

actually super simple it's over here for

the can move we can move if there's

nothing on there and if the move

direction.x is not zero

so that's really it if we are attempting

to move in the X at all and if there is

nothing on there then we can move which

means we then assign the move direction

if not then we don't touch this and same

thing down here so we can move if

there's nothing on it and if the move

there dot Zed is not zero

so that's it just this one simple change

and now the player should be able to

rotate

so here we are and if I look over there

and the player is currently unlocking to

the left and if I press W to point

towards the container counter and if

there you go the player does rotate a

little bit so that feels a bit more

natural

all right so that's just a tiny visual

thing that I wanted to fix okay so let's

keep going

now let's handle the actual cutting

counter

so first of all as usual let's make a

counter variant so let's right click on

the base counter create a new prefab

variant call it the cutting counter

let's go inside of it

and over here first thing we need is the

visual so let's pick up from the assets

The Cutting countervision so here it is

then we need the selected so let's

duplicate this one let's rename this one

to seal lectin and on the animator let's

get rid of it and instead at the

component the selected counter visual

okay great now let's write divisions for

the visual game object array and by the

way here's a quick tip on the right side

on the inspector you can see this nice

little lock icon

so if you click on it then that means

this inspector will not change as you

select other objects

so I can click on and select something

different and this one does not change

it is still showing the selected object

now this is this one when you want for

example to drag multiple things so you

can unlock the inspector then the

hierarchy you can use shift click to

select multiple objects and then just

drag them all directly inside the array

that's it just a nice quick tip so

everything is done let's unlock it there

it is okay so that said let's just

assign the selected material so the

counter select material let's make it

just one percent bigger so let's select

them all 1.01 okay and let's start with

all of them disabled okay

so the basic setup is done

now let's make our script to run this so

let's go down let's create a brand new

c-sharp script for The Cutting counter

let's select the apparent game object

and attach a cutting counter and let's

open

now here as usual instead of all this

let's start off by extending the base

counter okay

once again thanks to how we set things

up using such clean code this is pretty

much all we need to make a counter

with this the counter already works as a

counter then next thing we need is to

customize any logic specific to this

counter by just overriding the interact

function so that's it now over here we

can put whatever logic we want just for

the cutting counter and for this one for

star is actually going to be just like

the empty counter meaning we're going to

be able to drop objects on this

so let's just go directly into the clear

counter so here it is and let's just

copy all of this code go into the

cutting counter in Payson okay so the

exact same logic so checks if there is a

kitchen object or not checks if the

employer's carrying something or not and

picks up or drops in with this let's do

a quick test just to make sure this one

is working exactly like the clear

counter

so over here let's just make sure to

drag in less references so on The

Cutting counter let's make sure to drag

the countertop point so drag that

reference and then on the selected Drag

The Cutting counter reference okay

everything is good let's exit this

prefab make sure to save all the changes

and over here in the scene view let's

Place one of our cutting counter so

let's Basin right in there let's put it

on X of 4.5 0 and 3.5

okay so let's test

all right so here we are now if I

approach and I interact nope nothing

happens okay great pick up some cheese

and drop it on there any of there it is

I can pick it up I can pick up some

bread drop it and yep everything works

okay so far so good

now the next goal is to use the knife

and actually slice the object that is on

there and for that the first thing that

we need is we're going to need a

different input right now we only have

the movement and the interaction so

let's add another alt interaction

for that let's go into our input action

so let's open it up

let's make another action so create a

new action call it interact alternate

and for The Binding let's put it on

another key so let's listen and I think

on F makes sense

so let's go ahead select this one

then as usual let's make sure to save

the asset which in turn is going to

generate C sharp plus and compound the

code okay great

now we can go here into our game input

class and let's do the exact same thing

with it for the interact action so first

of all let's listen to it so let's go

inside the player input actions inside

the player action map so this one is the

interact alternate and let's listen to

the performed event

okay and when we have that let's fire

off an event pretty much the same thing

so interact alternate action

and down here let's just fire off this

event so

let's invoke using this and even RX dot

empty

okay so we have the input for the

interact alternate

now let's go on the player to listen the

same way we're listening to the regular

interact action

so over here on the player script let's

see how we're doing things so we go into

game input and listen to that so it's

the same thing game input and on

interact alternate action let's listen

to this one and when this one happens

lets you pretty much exactly the same

thing except we're just going to call a

different function

so instead of interacting let's call

interact Alternate which in turn

obviously means we need to Define this

function

so let's go into our base counter

so here we are on the base counter we've

got the interact and let's make another

one exactly the same just different name

interact alternate

okay that's it and now we are only going

to implement this in the ones that need

implementation

so for example on The Cutting counter

over here let's write down so public

override

and let's override the interact

alternate

and now here let's check check if

there's something placed on here so if

there's a kitchen object placed on this

counter

if so then let's basically cut it

and for cutting it the simplest way is

really to destroy whatever object is on

there and just spawn the slice object

so let's handle destroying a kitchen

object

for handling that let's go over here on

the kitchen object script

and let's make a simple function for

this object to destroy itself so let's

go up here make it public return void

and for name I like to use the name

destroy itself to make it destroy this

object

and really all we need to do is just

destroy and call destroy on this game

object

however before we do let's make sure to

clear the parent so let's go into the

kitchen object parent clear it and then

destroy the game object okay that's

great it's really this simple

and then on the cutting counter let's

get the kitchen object that is on here

and tell it to destroy itself okay so

let's raise the object

and after we do let's just spawn the

slices object so for now just keep

things simple let's make a direct

reference up here let's make a

serialized film

let's make it a type kitchen object so

and for the cut kitchen object the cell

okay so we have this then here in the

editor and let's make sure to drag the

reference so let's go inside the cutting

counter and let's open up the prefab and

inside let's assign this one that means

we need to create the object so let's

actually do that first

so let's create a brand new kitchen

object to sell let's come out for the

tomato slices

then if we do this we need to create the

prefab so let's once again do the same

thing tomato slices make the prefab

let's go inside this prefab let's modify

the visual so use the tomato slices

visual okay and drag the reference for

the other kitchen object for the tomato

slices okay

so the visual prefab is good and let's

just go into the kitchen object let's

just make sure to drag the prefab

reference then let's assign the tomato

slices icon and just come with tomato

slices

okay so we have the kitchen object so

now we can go into the kitchen counting

counter and over here let's open up and

set this one to the tomato slices

okay so we have all the references let's

go back outside save it

and back over here in our code so we

have this now we just need to spawn this

object

so we're really just going to spawn it

pretty much exactly like we did over

here on the container so we just go into

the description object spawn the prefab

and set the appearance so let's do

exactly that

over here we destroy the object then we

instantiate the cut kitchen object and

instead of getting into the player let's

put it on this

okay so that's it we should be able to

place a tomato directly on top of the

cutting counter and it should be able to

transform from a tomato into a tomato

slices

okay so here we are let me pick up a

tomato go up there drop it and okay that

works now if I press the onton track key

press it and if there go it did work the

Tomato was destroyed and the tomato

slices were spawn and I can pick them up

place them anywhere and yep everything

works alright awesome so with this the

basics are fully working let's just

briefly clean up this code

we already saw a little bit of code

duplication so the cutting counter is

going to spawn an object and the

container counter is also spawning an

object so we're copy pasting these two

lines of code in multiple places so

instead of doing that let's put it in

just one place

and actually a good place to put this is

on the kitchen object list itself so it

makes sense that this one is responsible

for spawning more objects

so let's put it over here however let us

not make it a regular function instead

let us make it a static function again

just like we saw for The Singletons by

making it static it means that the

function is going to belong to the class

itself as opposed to any instance so

let's go all the way down to the bottom

of the file personally I like to put

settings at the end and over here let's

make public make it static we're going

to return a kitchen object and let's

call it just spawn kitchen object

and for our parameters let's receive the

kitchen object that so

and let's also receive the kitchen

object parent

okay so that's it and we're going to do

the exact same thing so let's go into

the cutting counter and copy the code

that we're using and over here just

paste it in there so we go inside here

spawn the prefab and set it on this

parent

and finally let's return it

so let's return the kitchen object over

here let's pick it up so the kitchen

object

we get it and then we do kitchen object

set the parent and finally we return the

kitchen object

all right so that's it here we have a

super simple function that we can call

very easily it won't automatically spawn

an object and set to parents so now

let's just call this from somewhere so

over here on the cutting counter instead

of doing all this let's just go into the

kitchen object again remember let's go

through the class name itself and not

any instance and over here let's call

the function pass in the cut kitchen

object the cell and for the parent it's

going to be this

all right so that is now much much

simpler and let's do the same thing over

here on the container counter so if the

player is not carrying anything

let's give the player this object and

give it to the player just like this

as usual when we do some kind of

refactoring let's do a quick test make

sure everything still works exactly the

same

okay so here we are and if I go to the

counter and pick it up yep it does work

to spawn the object now I can drop it in

there I can cut it and yep there you go

everything does work all right so far so

good

so with all this basically we have

created a brand new counter where we can

cut objects however right now there's

obviously one huge layering funnel if I

now pick up a cabbage and I drop it on

the cutting counter and I interact with

it that cabbage has suddenly magically

turned into tomato slices now that is

obviously not intended so for that let's

define a proper cutting recipe and let's

do that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to create

another scriptable object type this one

is going to be for handling our cutting

recipes

so here's our game I can pick up a

tomato drop it on the cutting counter

cut it there you go slice Tomatoes

however if I could pick up a cabbage go

there cut it and there you go cabbage

turns into tomatoes so we have an

obvious issue The Cutting object is

currently hard-coded instead of being

based on the object we put on top of it

so to solve that let's make another

scribble object type like I mentioned

scribble objects are excellent for

storing and organizing data so it's

perfect for this use case basically we

want a script mode object to hold a

reference to the regular object and the

cut object so we can then identify the

input in order to spawn the output okay

so let's build that let's create a brand

new c-sharp script

call it the cutting recipe so

and let's open it

okay so now here on let's do exactly

that so something extremely simple so

instead of modern behavior this one is a

script mode object let's add the create

asset menu and finally for the fields

let's do just an input and output so

we've got of type kitchen object so

let's go for the input and another one

for the output

okay so that's really it super simple

now here in the editor before we create

and let's keep things organized so let's

make another folder

let's make it for the cutting recipe so

and inside let's frequently create a new

cutting recipe

let's call it tomato two tomato slices

and over here let's select the reference

so the input is going to be our tomato

and the output the tomato slices

okay so this is how we're going to

handle things

so let's go ahead and make actually the

final kitchen object that sews

so let's make yet another one a kitchen

object to sell

let's make it for the Cabbage slices

and then let's have another one for the

cheese slices

okay so now let's make these so as usual

let's if we get tomato make the cheese

slices and another one for the Cabbage

slices

let's go inside of it and first of all

drag the kitchen object as so so this

one is the Cabbage slices

and let's go modify the visual so

instead of this one the Cabbage slices

okay

so we have this let's save the prefab go

outside then the other one we made the

cheese slices so let's swap this out

let's find the cheese slices

and modify the kitchen object as well

okay

so finally just assign the references so

on the cheese slices drag the cheese

slices prefab let's assign the icon and

call it cheese slices

okay so finally on the Cabbage slices so

these are the Cabbage slices

let's pick up the icon and let's drag

the prefab reference okay so far so good

we have created our new icons

and over here let's just make all of the

other cutting recipes so we've got two

more so one is going to be the cheese

block onto cheese slices and the other

one is going to be cabbage onto cabbage

slices

so we need is just to drag drop the

scriptable objects so for this one

cabbage let's drop the cabbage on the

input cabbage slices on the output for

cheese mug that's the cheese Wok on the

input and the cheese slices on the

output

okay great all of our data is now stored

in some really nice script mode objects

so now let's go here into our cutting

counter

instead of having a hard-coded kitchen

object let's receive a field of type

cutting rest BSO except we're going to

have multiple so let's actually make an

array of this

call it the cutting recipe so array

now for the interaction this is picking

up and dropping things so let's leave

that the same for now and over here on

the alternate

basically we need to find out which

recipe we should apply to this

so how I didn't find that is pretty

simple so we've got the kitchen object

that is placed on this object and we've

got a list of cutting recipes which in

turn has the input so we just need to

cycle through all the recipes in order

to find the one where the input matches

okay so let's go down here make a

function to do just that let's make it

private we're going to return a kitchen

object as so let's come with get output

for input so we give it a certain input

and Returns the one that matches that

one

so it turns a kitchen object as so for

the input kitchen object as well

here on let's cycle so do a for each

cutting recipe so in the cutting recipe

so right so let's cycle through all

these and just check if the cutting

recipe so if this one dot input matches

the input that we received

if so then this is the one we want so

let's return the cutting recipe

so.output and to make sure that the

function Works down here let's return no

okay so that's it we give it an input

and we get back the output

so now here we just need to make sure to

do it before we destroy the current

kitchen object

so let's store a kitchen object as so

for the output kitchen object SL and we

just get the output from the input and

for the input pass in the get kitchen

object so that's the one inside of this

cutting counter and let's get the

kitchen object this out so that gives us

the output and then we just spawn that

output

okay so that's it let's test

finally back in the scene let's just go

inside the prefab and over here on

cutting counter we need to make sure to

add all the recipes

so let's add so the cabbage

then a second one for cheese Mock and

finally for the Tomato okay so there are

of our recipes let's go outside save the

changes and let's test okay so over here

let's pick up a tomato go up there slice

it there you go got some tomato slices

now pick up some cheese go here slice it

and there you go got some cheese slices

and finally the Cabbage go up there

slice it and there you go some cabbage

slices all right awesome

so everything is working perfectly

however now let's say that I want to

pick up some bread and bread should not

really be able to be cut so if I go

ahead and I cut it and there you go

there's our air we have no recipe that

takes bread as an input So that

obviously leads to a known reference

exception

now here we have two options for solving

this problem

one option is simply over here when we

do the interact alternate

we get the output for the input and if

this one returns null then we just don't

cut it

so we don't destroy it and we don't

spawn it or alternatively we can

actually add some Foundation over here

when dropping objects so we can make

sure that we only drop valid cutable

objects now both approaches are valid

and actually we do need to implement

both them we'll see why in a bit

so let's do both starting off with the

validating the drop

so first we check if there is no kitchen

object on this cutting counter then we

check if the player is carrying

something and then we drop it from the

player on this

so over here let's just check if there's

any recipe that has whatever the player

has as an input

so let's go down here make a function to

do that private let's return a bone and

call it has recipe with input

and we're going to receive a kitchen

object episode for the input kitchen

object lesson

and over here lets you pretty much

literally the same logic so we have this

and if we find a match then let's return

true so there is a recipe with that

input if not return false so now up here

when the player is carrying something

let's check

if has recipe with input and give it the

player get the kitchen object the player

is holding and get the kitchen object as

so

so if there's any recipe that takes

whatever the player is carrying as an

input

if so then we drop it

okay so like this let's test and see if

we can drop the bread

okay so let's pick up some bread go

ahead drop it and nope does not work

pick up some cheese and yep that one

does work

however now we actually also need the

other validation that I mentioned the

reason is because if we place a valid

option like for example the cheese there

so that works and I can cut it and yep

that does work however Now the recipe

the cheese moth became cheese slices and

now cheese slice is no longer an input

to any cutting recipe so now if I try

cutting again

I've got another no reference exception

so we need to validate putting objects

on top of it and also actually cutting

them Technologic is also pretty simple

so let's go down to the interact

alternate so we just check if there's a

kitchen object on The Cutting counter

and has recipe input

and let's get this kitchen object get

kitchen object as so just like this

so we're only going to cut if there is a

kitchen object here and it can be cut

okay so let's test

so first of all the other one let's pick

up bread and nope cannot travel okay

great now pick up some cheese and I can

drop now interact cut now cut again and

yep there you go no more errors all

right awesome okay so here we have

everything working perfectly I can pick

up a cabbage go up there cut it into

slices I can slice some cheese and I can

even slice some Tomatoes everything

works perfectly now the one thing

missing from our design is we don't

actually want this action to be instant

we don't want to just press a button

everything slices instantly instead we

want to have the player press the button

a few times in order to actually cut so

let's do all that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add the

mechanic for the player to be able to

cut multiple times in order to actually

cut an object

okay so we have our cutting counter I

can drop a tomato and press button there

you go it cuts it straight away now we

want the exact same logic but we want it

to take a few Cuts before the cut object

is spawned

so let's start off by going here onto

the cutting counter and basically let's

keep track of some kind of progress

basically the way we do that is pretty

arbitrary it's up to you to decide for

example you could use a normalized float

however for cutting since this is going

to be a discrete action let's actually

count the numbers with an end so let's

store a private end just call it cutting

progress

okay so now let's begin by actually

initializing this progress so when the

player drops something on there let's

set this one to zero

and then down here when we have the

interact alternate we do our logic and

when we do let's just increase this by

one

and now we need to know if the object

has been cut so we need somewhere to

Define some kind of maximum

and for that we can actually do it

directly on the recipe so so inside the

cutting rest PSO over here we've got the

input we've got the output and let's

also Define an end

for The Cutting progress Max

okay that's it

and back here in the editor let's go

into the Tomato to tomato slices let's

say this one takes just three Cuts then

for the cheese let's also take three

cuts and for the Cabbage let's say it's

a bit thicker so let's say it takes five

cuts

okay so back in the cutting counter here

down here we are adding to our cutting

progress

so then we just need the recipe so in

order to grab the maximum so on

sectionally go down here and actually

make a different function so this one

just returns a Boolean this one a

kitchen object or so let's make another

one this one is going to return a

cutting recipe so

so get the cutting recipe so with input

and we're going to receive as usual the

kitchen objects so for the input

I'm really going to do the exact same

thing that we did up here next time

instead of returning the output let's

return the recipe itself

okay so now that we have this more

logical one we can actually get rid of

all this copy paste code

so over here we just get the cutting

recipe so

and we just get it and pass in the input

so we have this one over here if this

one is not no then we're going to return

this on the output

and if not we're just going to return

null

okay so we're doing the exact same logic

just a bit similar okay and up here

pretty much the same thing

so has recipe with input let's get the

cutting recipe a cell

and basically just return if this one is

not known

okay so we have our three nice sample

functions so let's just use this one to

get the cutting rest BSO so let's

actually copy this and go up here so we

do the cutting progress then let's pick

it up the one for this input so the

input is going to be this one the object

currently on the cutting counter and

over here we already know that there's

going to be a recipe with this input

since we've gone through this if

so then we can just check if the cutting

progress is bigger or equal to The

Cutting recipe so and let's grab the

maximum

if so then yep we do spawn it

okay so that's it some very simple logic

Let's test

so here we are let's pick up a tomato go

up there and okay now I'm going to press

enter direct okay press once and yep

okay so far so good nothing now two

times and Alpha press a third time boom

any up there you go got the nice slices

now for cheese same thing one two three

yep it works and finally for the

Cambridge this one should be five so one

two three four and five any up there you

go everything does work perfectly all

right awesome

so with this we now have progress in our

cutting logic although of course just

like this it's not very good for the

player the player has no way of knowing

what exactly is going on so we need some

kind of visual feedback so for that

let's add a really nice visual progress

bar and for doing this we're also going

to learn about a really awesome Unity

feature these are World canvases

so before we make the world canvas on

The Cutting counter let's actually set

something up over here on the scene

itself

let's first create a regular canvas

we're only going to use this in a couple

of lectures but let's first do that one

just for now

so let's go on the plus button go into

UI and let's create a brand new canvas

okay so there you go that creates a

canvas and an event system

like I said we're only going to worry

about this in a little bit but for now

let's just leave those as is

and also since we're here creating some

objects let's also take some time to

organize our hurricane

Unity suddenly doesn't really have any

folder objects so you can't organize the

hierarchy in any folders however you can

use empty game objects essentially as

folders

so let's make a brand new empty game

object let's call it counters

and now very importantly for empty

folder objects make sure you put them on

zero zero zero so nothing breaks

so make sure you put it on there before

you drag the counters

and now let's just drag on the counters

inside so all the clear counters put

them outside this one also drag it

inside and all of these counters put

them all inside so there you go now

hierarchy is quite a bit more clean

okay so now let's make the cutting

progress so let's click on the cutting

counter

and let's go inside our prefab so let's

go inside of it

now over here let's right click on the

hierarchy and we're going to create a UI

let's create another canvas

now for this one let's give it a name

let's name it the progress bar UI and

for this one over here on the inspector

for the settings instead of being screen

space overlay let's make this one a

world space canvas

basically screen space means that it

would occupy the entire screen whereas

World space means that this exists in

the world in whatever position it is

so let's make it World space and over

here the fields actually unlock so let's

put the positions on zero and for the

width and height let's also put it on

zero

so basically the canvas is going to be

exactly over here by the way the

shortcut that I just used was the F in

order to focus on the object

so this useful if you're zoomed out or

zoomed in way too much okay

so we have this and we want the bar to

be a little bit above so let's actually

lift it up on the Y by a little bit so

over here let's put it on y of 2.5 okay

now I said the going with this is to

make a progress bar so inside the

progress bar UI let's create a new UI

image let's name this one our bar

let's put it with a width of one and a

height maybe of 0.2

so there you go just a really thin bar

and for the color you can play round

tinted with any color you want now for

progress I think maybe a blue or a

yellow something like that makes sense

so let's go with the yellow kind of like

this

okay so there's our really nice progress

bar

and for this let's actually use one

really nice trick for making a super

easy progress bar the image component

has a really easy way of making a slider

image however it only actually works if

you assign an image over here

so let's assign one in order to be able

to see those options

and for that in the project files

there's a texture white one by one this

is literally just a one by one white

pixel

so here it is just a one by one image if

only white

and as soon as we assign it we do see

over here the image type so we see a

bunch more options and the one that we

want is to set the Sprite as filled this

one lets you do some really cool really

easy effects for example you can make it

radial and look at what happens in there

as I modify over here on the film Mount

so as I go down look at that it's

radiantly filling so for some kind of

circular progress bar this would be

excellent but in our case what we really

want is just a horizontal bar so we're

here for the film method instead of

Radion let's go with horizontal

and if there you go now by playing

around this we have a really nice

progress bar

then if you want you can modify on left

to right right and left but yep like

this it looks great

now in order to modify this visual

really only we're going to need is

modify over here the film Mount this one

is a normalized value so between 0 and 1

so 0 is commonly empty one is commonly

full however one issue with this is when

the bar is empty then we can pretty much

not see so we can see the actual size of

the bar we can see what size it should

be

so with this it's pretty difficult to

see how far along we are but something

that is pretty simple we can really just

add some kind of background

so let's duplicate the bar let's name

this one the background

for this one for the image type we don't

want anything so let's leave it on

SIMPLE and for the color let's put it on

kind of a dark gray okay great and now

here's one very very important thing is

over here on the hierarchy let's click

and drag and place it above the bar

the reason why that is super important

is because the Sorting order and how it

works in unity basically when it comes

to UI elements inside a canvas the

Sorting order is based on The Horde in

the hierarchy basically it renders from

top to bottom

so the bar on top the background this is

going to render first and then the one

below it the bar is going to render

afterwards which means it's going to

render on top

so for the background we want to be

behind so place it above on the

hierarchy and that way it renders the

background and then renders the bar also

by the way for 2D Sprites Unity has

another different sorting method it's

all based on sorting layers and sorting

orders

I have video on that topic if you're

interested in 2D games

okay so with this we have the background

and then we have our film bar this way

we can see if the progress is being

filmed or not

also one more tiny thing that I like to

add is Unity has some really nice really

easy to add effects

so you can go into that component and

let's search for a shadow

this one does exactly what you expected

as a nice drop shadow over here on the

effect distance let's put it on 0.1.1 in

order to see

next one let's not do it on this one

we'll do it on the background so let's

get rid of this instead of going to the

background over here let's add the same

shadow

so if you put it on point one and minus

point one you better go a nice simple

and drop shadow or the other one that I

prefer so instead of the Shadow let's

add a really nice outline once again for

the effect distance 0.1.1 or maybe

actually 0.05 just to be just a tiny bit

and let's raise it on the alpha so there

you go nice little outline tour bar this

is just a visual thing so you don't have

to add this but personally I find that

it looks pretty good

so with all of this we have our Visual

and perfectly set up we've got our nice

bar all we need to do is play around the

filament in order to fill it

so now all we need to do is to connect

this to the logic but as usual let's

make sure to write some good clean code

so we do not want the cutting counter to

directly touch on this image

instead let's make a script to handle on

that so let's right click create a new

c-sharp script call it the progress bar

UI

and just personally as a rule I like to

open the UI to any UI script

you don't have to do that it's just a

rule that I personally find helpful to

follow that way just by looking at these

scripts I can immediately see this one

is a UI this one is script and logic and

so on

so on the progress bar UI on the main

game object let's attach the script and

let's open it

okay so now here we're going to need a

reference to our image

so let's add a serialized field private

and we're going to need the image type

and importantly this is inside using

Unity engine.ui so let's go up here

using Unity engine dot UI so we have our

image component okay great let's call it

the bar image

so we have a reference and now with this

obviously we need to have some kind of

reference to the counter so we know when

the progress changes so it's really the

same thing that we've already done so

many times throughout this course so

let's set a film up here serialize film

private cutting counter for our cutting

counter

then over here in the editor let's write

new references so drag the reference to

The Cutting counter and another one to

the bar image okay great

now we just need some kind of event to

update the bar image

so let's go over here into our cutting

count script let's make an event to

spawn that so public event let's use the

event handler the default standard

let's go with on progress change

and let's also make a nice event artist

to be able to send the current progress

amount

so let's make a public class on progress

changed event arcs and let's extend

event arcs

and then inside and let's put the

current progress

however let's also pass in the progress

as normalized since that's the what the

bar will use

so public Cloud progress normalized

and we're going to make this event of

this type

okay great so we have our event

now whenever we modify the progress we

just need to fire this event so over

here when resetting the progress let's

fire it so let's invoke pass in this

instantiate our event args and pass in

the progress normalized and to get the

normalized progress sectionally very

simple basically we just need to divide

the current progress by the maximum so

cutting progress divided by cutting

progress Max which is actually inside

the rest BSO so we need to pick that one

up

so let's go down there to pick up the

cutting progress recipe

so we picked this one up and we go in

there and get the maximum

however over here we also need to be

very careful because there is one sneaky

issue here this has to do with how

c-sharp works and how instar divided

with other ends

for example if we had a cutting progress

of one and cutting progress Max of five

you would think one divided by 5 would

equal 0.2 however if we actually did

that over here we would actually get a

zero and the reason for that is because

we are dividing two ends cutting

progress is an end cutting progress Max

is also an INT and if you divide an end

by an end then the end result will also

be an end

since you cannot Define 0.2 in an end

the decimal gets cut down and you end up

with just zero so that would not be

correct in order to get the right value

from this calculation we need to make

sure to convert one of these values onto

a float so that's really simple we just

cast one of them so just cast this one

to the float just like that

basically now this one will first be

cast to a float and then we're going to

have a float divided by an end and the

end result won't be afloat so if you

ever do some math and you get some weird

results always make sure to check the

type of your numbers

okay so here we are correctly firing the

event and then down here when adding our

progress let's do the same thing let's

also fire on the event

so now we can go back into our progress

bar UI

and over here let's listen to the event

and again remember that if we're

accessing an external reference let's do

that around start and not an awake

so cutting counter listen to the on

progress changed event

when that happens let's just go bar

image and set the fill amount to what we

received from the event so the progress

normalized

okay so that's really it and also appear

on start let's initialize it as 0f so

the bar is nice and empty

okay so let's test

back in the editor let's just go back

into the scenes make sure the prefab has

been saved and let's head on play

and right away yep we do see the bar yep

it is empty now pick up some cheese drop

it and if I cut and if there go add a

little bit of progress now a bit more

and there you go there's our cheese

okay great everything does work now

let's add just one more tiny bonus thing

we can add some extra logic in order to

hide this visual if the bar is either

completely empty or completely full that

is actually pretty simple

over here on the progress bar UI script

let's just make some basic show and

height functions

so private void show and then we're

going to have

a private void Hind

on these one just game objects that

active this one set it to true and this

one set it to false

now on start we subscribe to the event

and then let's hide it okay

also here it's very important make sure

you hide it after you listen to the

event if for example You Can't Hide on

awake that would disable the game object

and the start would never run so it

would never listen to the event

so if you have reset the game object as

inactive make sure you do it only after

you're listening to whatever events you

want so we have this that's great and

then when the progress changes

let's just do a basic test so if e dot

progress normalized equals zero f or if

the progress normalized equals one F so

if the bar is similarly empty or

completely full

if so then let's hide it and if not then

let's show it

okay that's it let's test

okay and yep by default starts off

hidden let's pick up the Tomato go up

there and yep still hidden now I cut and

there you go there it is cut again and

yep there you go it hides itself okay

great so we've got a nice little visual

let's do just one more final thing let's

add a really nice animation

if we go inside the cutting counter and

we'll look at the cutting counter visual

over here note how it already has an

animator

just like we did for the container

counter it's all very simple

so basically just has a cut parameter

when that happens it just cuts the

counter so just plays a simple animation

since it's going to be pretty much

exactly like the container counter and

let's actually duplicate that script so

let's go down find that script so the

container comes to visual let's

duplicate this so Ctrl d

let's rename this to The Cutting counter

visual

okay let's open

and over here let's rename the script so

the cutting countervision okay great

then for the parameter let's rename this

instead of open close is going to be

called cut

and for the string it's cut again make

sure you write it case sensitive make

sure it's all correct

then instead of having a container come

through we've got a cutting counter and

a cutting counter

and finally we just need to listen to

the correct event so technically we

couldn't listen to the unprogressed

changed however that one also gets fired

over here when the cutting progress is

zero we don't want the current mission

to play when this happens so let's just

make another simple event so a public

event event handler

let's call this just on cut

okay and then down here when we have our

cutting progress so we cut and let's

just invoke this event

okay that's it super simple

so now on The Cutting counter visual

let's go into the cutting counter and

into the uncut event let's listen to

this and we're going to set the trigger

example like this so get rid of the

container counter like this

okay there you go a very simple script

so now here back in the scene view

inside the container counter prefab

let's just go inside the visual let's

attach The Cutting counter visual just

need to drag The Cutting counter

reference and that's it let's exit the

prefab save it and let's play okay so

now let's pick up a cabbage go up there

drop it and aren't interact and if there

you go we've got a nice little animation

all right awesome so I can drop things I

can cut them and everything works

perfectly

all right

so here we added a cutting progress to

our cutting counter and we also learned

about yet another very useful ENT

feature called World canvases

and at the same time you might have also

noticed that the canvas is looking at

the camera in kind of a weird way

basically just pointing straight forward

this can sometimes make it difficult to

see so let's work on that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to build a

very simple but very useful script to

make an object look straight at the

camera with various options

okay so we previously made the cutting

counter and when I placed something yep

there's a nice progress bar

so now that this is working let's do one

more thing right now look at how the bar

is oriented it's looking quite a bit

slanted that's because we have a

perspective camera and it's looking from

top down

now this is one of those things that is

kind of personal preference so maybe you

don't like it just like this

but a lot of the times you want these

World UI elements to face the camera

just like a regular UI

one example of this problem is for

example let me pick up the cutting

counter duplicated and let's put one

down here so rotate it upwards

okay let's put it on 4.50 and minus 5.

now if I place something on there and I

cut it yep like that the bar is Now

inverted so let's make a simple script

to solve this problem

let's go into our scripts create a new

c-sharp script call it look at camera

let's go on to The Cutting counter

prefab let's open it up go inside on the

progress bar let's attach the script so

the unlocked camera okay now let's open

so from here let's use an interesting

function so let's use a private void

late update so not update we have the

late update so if this is the first time

you're hearing about this like the name

flies this one is going to run after the

regular update so every single update

and all the objects is going to run and

then on the late updates so kind of like

you've got awake and start you have

update and late update why this is

useful specifically for this script is

because for this element you really want

us to run the orienting logic you want

that to be done after whatever that

object does in the update in this case

this object will never move so it's not

really an issue

but for example if you had some kind of

moving vehicle with a warm cameras on

top if you have that you would want to

set the Warren canvas and location to

unlock the camera after the vehicle had

moved otherwise the canvas would not

look perfect so anyways because that

here we're doing on late update and now

we can just look straight the camera so

we can just do transform dot lookup

and for the Target passing the camera

Dot main.transform

this function makes this transform look

at another transform or another point so

this will make it look straight at the

camera

also by the way one quick note here in

some other tutorials you might see

people telling you not to use

camera.main the reason for that is

because this field did not used to be

cached so every time you use this it

would cycle through every single game

object in the scene until it found the

main camera so that was obviously really

bad for performance but nowadays this

field is now cached by default on the

ENT backend so you no longer need to

Cache it yourself accessing it directly

just like this is now fine

okay so with this let's test

just make sure to save the prefab and

let's hit on play

let's go ahead pick up a cabbage put it

up there and if they're young look at

that how it's looking straight at the

camera and for this one down here same

thing cut it any up there you go both of

them are looking straight at the camera

okay so that's great

you can also see exactly what it's doing

if we try to move the camera again we're

using cinemachine so let's move the

virtual camera

so over here if I just play around with

the position.x look at that look how as

I move the camera yep the objects are

perfectly looking straight at the camera

so that's great that's what we want but

also you might notice one thing notice

under the bars are actually inverted

instead of going left to right they're

actually going right and left basically

this has to do with how the canvas by

default assumes you are essentially

going to look at it from behind instead

of looking forward so that is why when

this game object is pointing straight at

the camera it's essentially inverted

so to sum this is actually quite simple

we basically just need to look in the

exact opposite direction

but at the same time sometimes we might

want this exact Behavior having

something looks right at the camera

maybe we do want it to be inverted

sometimes so for that let's make a nice

complete script with all of our possible

options and for the finding options it's

also an excellent way to learn about one

more thing which are c-sharp enums enums

are an enumeration meaning a fixed set

of options that you can have of

something

so these are really useful when you have

a fixed set of something like for

example maybe a fixed number of options

so for example up here let's make it

private make it an enum and let's call

it mode and then inside we can Define

all of our options so let's say we have

the regular look at it and then look at

inverted

okay so we have these two options in our

enum now let's do a field of this type

and expose it in the editor

so let's make a serialized film private

of type mode and call it mode

okay let's save this and look what this

looks like in the editor and if we go

inside the cutting counter and we'll

look at the progress bar

even look at that the mode shows up and

it shows up as a really nice drop down

menu so since we have a limited number

of options we've got a really nice menu

where we can choose each round if you

want

so that's really awesome that's one of

the benefits of enums they are really

easy to use over here in the editor

now back in the code here and let's

decide which one to use

so on The Late update let me just do a

switch on our mode in case we are on the

regular look at mode then let's see

exactly this let's simply look in in

case we are on the look at invertent

for this we just want to look at the

inverse position so that's actually

pretty easy we just calculate the

direction Vector from the camera to this

object

so a vector 3 call it deer from camera

and to get direction from the camera we

start from this object so this

transformed that position subtract the

camera dot main transform position

so this gives us the direction pointing

from the camera and then just to

transform down look at

and instead of looking at the camera

let's look at the opposite position so

let's look at transform that position so

our current position points the

direction from the camera so we're going

to be looking at the exact opposite

point

okay so that's it let's test

and right now by default we have the

regular look at so let's just see it

let's just play some objects okay so

right now it's still inverting

and something real nice is you can play

around the enums even as the game is

running so let's go inside the cutting

counter on the progress bar UI for this

one let's swap from Lookout to unlock

inverten anything like that that one is

now looking perfectly

so this one is using Lookout and this

one using look at inverted

okay great it's all working

however yet another thing that is all

about personal preference

note how the visual has a slight slant

this is due to how the visual section

looking directly at the center of the

camera

so you can really see it if I move the

camera left and right how it Slants

going left or going right

again the Zone personal preference it's

just a visual so maybe you do want this

look but let's see another method so

over here in our modes let's add two

more let's add camera forward and Camera

forward inverted

and then down here on our late update

let's add those so the camera forward

and then we have the camera forward

inversion

so for this one for the camera forward

super simple let's just take this

transform use the forward which again

you can get or you can set it and let's

set it to the exact same one as the

camera Dot main.transform.4

and for the inverting example the same

thing X7 set of four do we do minus four

okay so let's see what this looks like

okay so here's the game with both

counters they're both currently using

the unlockit mode now if we put a look

at inverting yep that one goes left to

right okay great now if I put camera 4

in give a look at that now that one is

perfectly straight

so even as I move the virtual camera on

left and right look how that one is

always perfectly facing the camera as if

it was a regular UI owned

and for the inverter does the exact same

thing but invert and so just like that

so that's it these are the four modes

again these are all just visual elements

so pick whatever you prefer for me I'm

going to be using this one the camera.4

so that everything is perfectly

horizontal so I'm just going to make

sure to go inside the prefab and on the

prefab itself modified and set it as

camera.4

and now if I add the cheese there yep

looks great and if I had a cabbage here

and yep it also looks right

all right so here we created a really

nice useful generic script to make an

object look straight at the camera in

various ways note how this one has

nothing to do with canvas or a progress

bar or anything it's really a generic

script to look at the camera so you can

apply this to anything where you want it

to look at the camera

okay so with that the cutting counter is

fully done

now let's handle the trash counter in

the next lecture

hello and welcome I'm your code monkey

in this lecture let's create the trash

counter this one is actually pretty

simple it's how we're going to drop

something and just destroy it okay so

making the trash counter is going to be

super super easy once again going to be

another great practical example of the

power of writing good clean code and

having good organization in your project

so let's do the same thing that we've

already done a bunch of times so first

of all let's make the prefab variant so

let's right click on the base counter

and create a brand new prefab variant

come with the trash counter

okay let's go inside and first of all

let's drag the visual so find the visual

prefab on the trash counter okay then

let's duplicate it to make the selecting

so let's rename this to selected

let's add the selected counter visual

let's add the visual inside of it and on

the visual let's select the other

material so the counter selected and

finally on the selected put it one

percent bigger 1.01

and start off with visual disabled okay

so that's the basics just like we've

already done so many times now let's

make this script to run this so let's

frequently create a new c-sharp script

call it the trash counter

and by the way here we're already

starting to have quite a bunch of

scripts so we should probably organize

the scripts folder so let's make a new

folder let's come with counters

and let's make another one and call it

scriptable objects

so on the counters let's drag the base

counter clear counter the container the

container visual The Cutting The Cutting

visual then down here the trash counter

okay let's drag them all onto the

counters folder and on these critical

objects let's put the cutting recipe and

the kitchen object as so okay now our

phone there is a bit more organized so

let's open up the trash counter

and over here as usual let's begin by

extending the base counter okay great

then let's implement the regular

interaction so override the interact

and on this one again it's going to be

super simple we just check if the player

is holding something and if so we

destroy it so just check if player that

has kitchen object so if the player is

holding something go into the player get

the kitchen object the player is holding

and simply call destroy itself

and that's it it's this simple back in

the editorial let's just attach a script

let's make sure to drag the countertop

Point reference and on the selected drag

the base counter reference

okay with this it should be working so

let's exit the scene let's save the

prefab and let's drag it over here onto

our scene so let's drag the trash

counter and put it maybe somewhere over

here on the corner

so let's put it here on an X of 7 y 0

and -3.5

then let's also fill out these spots

down here so let's duplicate the clear

counter put one in there put another one

in there

let's put another one on the side and

for the crash counter and let's align it

so let's put it a bit more to the side

so on 7.5 okay great and let's put it

inside the counters and now we can test

okay so let's see if we can interact

with it and yep as I approach yep I do

see it highlighted okay great and if I

interact obviously nothing happens since

the player isn't holding anything now if

I pick something up let's say a tomato

and I don't want this tomato so I want

to trash it and if there you go it does

get trashed all right awesome so this is

literally it like I said this is once

again another excellent example of the

power of writing good clean code this

was super simple to implement because we

have a really nice structure for how all

of our Counters work also because our

interaction system is very well built

also because the kitchen object system

is very well made it's because of all of

that great very clean code that we were

able to implement a brand new counter in

literally about 60 seconds

so once again I hope that by following

this course you know understand why I'm

always talking about the importance of

writing good clean code it's exactly

because this if you write your code

correctly it makes developing the game

so much easier at first it might seem

like the quick and dirty approach is

faster and usually in the beginning it

is faster but as soon as you add some

complexity the quick and dirty approach

suddenly won't scale whereas the

well-built clean code approach this one

will continue scaling very well so here

we have a fully functional trash bin so

we can dispose of unwanted objects next

let's build a much much more complex

Hunter let's build a stove counter which

also requires building a really nice

State machine so let's do that in the

next lecture

hey again another quick intermission

you're past the halfway point so

congrats again by now I really hope

you've already learned a ton from the

course we've already covered lots of

topics and built a ton of systems I hope

you've been following the website as you

go through the lectures and I hope

reading the frequently asked questions

that I sent you in some way let me know

in the comments how you've used the

course website did you just read the FAQ

or did you also download some project

files let me know I'm curious to know if

you enjoy my teaching song also look at

my other courses after finishing this

one especially the turn-based strategy

course that one is an excellent

follow-up for this one okay there's

still quite a bit more for us to build

and learn so let's continue in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to build the

stove counter so we want to place some

uncooked meat then we wait for a bit for

it to be cooked however if we weigh too

much it's going to get burnt so let's

Implement that alright so as usual let's

first begin by making our counter so

let's go inside the prefabs the counters

let's right click on the base counter

and create new prefab variant call this

the stove counter and as usual let's go

inside of it let's find the visual so

inside the prefab visuals it counters

visuals here is the stove counter so

let's drag it then let's duplicate this

rename this one the selecton let's set

the component the selected counter

visual

then let's go inside on all of these and

by the way this visual actually has some

nice visuals that we're going to

implement in a little bit but for the

selected we really just want the static

objects so let's pick up all of these

and let's select the counter slide

visual okay nice and white then let's

lock over here the parents so I can

select all of these and drag all of them

okay great and start off with all of

them disabled okay so that's the basic

setup as usual

just for the Counterpoint

since this one has a nice little sub on

top let's lift it up by a little bit so

put it on a y of 1.456

okay that looks pretty good just move it

a little bit to the center okay great

so now let's make our script so let's go

inside our scripts folder we've got our

counters so in here let's create the

brand new c-sharp script for the stove

counter let's wait for it to compile

let's attach the script and open okay so

here as usual let's extend the base

counter

now like I said the going for this one

is to be able to cook our meat and for

that it's going to be based on a timer

and to actually cook the meat we're

going to need to know which one is the

uncooked meat type and which one is the

cook me type

so for that we really want the exact

same logic that we did for the cutting

action we want some kind of place where

we can store an input and output as well

as a cook timer so for that let's

actually just duplicate so let's go

inside our scribble objects for The

Cutting recipe and let's duplicate this

one so Ctrl D and let's name this one

the frying recipe so

okay let's go inside

and over here let's rename the object

then we have an input we have an output

and then a set of progress let's have

the frying timer Max and since this one

is a timer instead of an in let's make

it a float okay so that's it pretty

simple then back here in the editor

let's create our script mode object so

let's go inside let's make a nice folder

so a folder for the frying recipe so

and inside let's create one so let's

create a brand new frying recipe so for

this one let's call it meat Patty

uncooked into meat Patty cooked

then for the inputs let's choose the

meat Patty uncooked now we have to make

the other one so let's go ahead and make

that one let's duplicate this one rename

it to the meat Patty cooked

and the object name meat Patty cooked

let's select the different Sprites so

this one is going to be the meat Patty

cooked okay

and finally for the prefab let's also

make it so for the meat Patty cooked

let's go inside of it and also make sure

to save changes on our stove counter

it's okay now in here let's get rid of

this Visual and use the other visual so

we want to meet Patty cooked and let's

make sure to drag the script monk object

okay so it's all good here and let's go

back outside save it and finally over

here on meat Patty cooked let's just

grab the prefab reference so there you

go that one okay so this one is working

and since we're here and let's actually

make the other one right away

so let's make the meat Patty burned so

the prefab and let's also duplicate this

to make the meat Patty burned then on

the text let's rename this to Burnt

let's choose the burn icon

and for the prefab let's go into our

meat Patty burned and swap it out for

the burned one so there you go nice and

charred and over here swap it for the

meat Patty burned okay let's save it and

finally down here just make sure

everything is correct

object the transform prefab just like

that okay so all of our burn references

over here all of our cooked and over

here all of our uncut and again when

going through this process always make

sure that you match all the references

on the certain objects and also over

here on the kitchen objects so meet

Patty burn yep meet Patty burn for the

uncooked the uncooked and for the coke

there it is okay everything is good

great so now we can go back over here

into our frying recipe so and for the

output let's output the meat Patty

cooked and for the frying timer let's

put it on three seconds

okay so that's it great now back in the

code here on the stove counter let's add

an array of our frying recipes so a

serialized field private it's going to

be an array of frying recipe so frying

recipe so array make omelette frying

recipe so a ring okay great then back

here in the editor let's go inside the

stove counter let's make sure to drag

that so let's drag the mid Patty from

uncooked into cut okay let's also drag

the counter top point and finally since

we already made the script over here on

the selected we can also drag the

selector okay so our stove prefab should

be working okay let's go outside make

sure to save the prefab okay now let's

continue with the rest of the script

so let's make our override so override

the interact action

and when we interact with it let's

validate dropping the object just like

we did on the cutting counter

so let's go over here into our cutting

count script and let's just copy pretty

much the exact same thing so let's copy

all of this interact code let's go over

here in the stove counter and just paste

it now we also need to copy in our

recipe

so over here on the cutting counter

let's copy paste those functions so

these functions go into the cell counter

and over here on let's face them they're

going to work pretty much the same thing

so we get an input except instead of

being a cutting recipe so we're going to

have a frying recipe so so let's replace

all the cutting recipe references with

frying recipe reference

then for the array this one is the

frying rasps array and obviously let's

rename these so Ctrl R to rename all of

them into frying recipe so

let's also rename the function instead

of get cutting rest BSO it's the frying

recipe so okay so there's no more

mentions of cutting over here so let's

use this function up here and up here

and just make sure to rename these the

frying recipe as so

and down here on same thing so the

frying recipe so okay so down here we

have no more mentions of any cutting

let's just go up here and solve all

these problems so first we check if

there's no kitchen object here and if

the player is carrying something then we

see if what the pointer is carrying

matches any kind of frying recipe if so

then the player is carrying something

that can be primed then we set the

parent and for now let's not worry about

the progress

so let's just get rid of all this just

like this okay so with this we should be

able to drop but only in uncooked meat

so back in the afternoon let's just set

up our scene so let's drag a stove

counter onto our scene let's put over

there on X of 6 y of 0 and 3.5 alright

so let's test okay so now if I pick up

some cheese I go up there and I drop it

and nope doesn't work okay great but if

I pick up some uncooked meat and I go

and I drop it and yep that does work

okay great so it works and I can only

drop the actual objects and matchy

recipe now unlike the cutting counter

this one will not be based on a player

alt interaction and actually over here

and let's fix this minor issue

basically we added this debug.log error

to the base interact because pretty much

every single counter is going to

implement this interact function but not

all encounters are going to have the

interact alternate action

so this one lets us do nothing let's not

spawn error okay just a quick fix

so like I said the stove counter this

one is going to be based on a simple

timer and for making some time based

logic basically we have two approaches

one approach is to use a simple foil

timer or you can also use a co-routine

now a lot of tutorials will teach you

how to use a co-routine and that's not

necessarily a bad practice it does work

it does achieve desired result so to do

that you would just make a function like

Freight timer

so you'd make a private you have to

return I in numerator

then call it something like handle fry

timer

then inside you can do a yield return

and return a new weight for seconds

and to start this co-routine you would

do maybe on start you would call start

Co routine

and start the handle for right hammer

so this one approach this is definitely

perfectly foundly timer code

however personally I am not a fan of

co-routines it's not because of

performance or anything it's simply

because I don't like the pattern that

they force you to use I don't like being

forced to make a function that returns I

numerator I don't like using yield

return I don't like having to use the

start core routine function I don't like

being forced to use this on a

monobehavior object those are all

requirements for making a CO routine

work and personally I find those are way

too many requirements that create a very

strange pattern that I really don't like

so that's really the only reason I don't

like Co routines because I find this

pattern to be quite a lot convoluted so

instead of core routines what I like to

use are simple basic flow timers so just

make a simple and private void update

then we just need to keep track of a

certain timer so for example a simple

private float frying timer

then on the update let's first check

that we have an object so it has a

kitchen object if we have a kitchen

object then let's increase the timer by

time dot of time by the way here when

working with a timer you can increase or

decrease it's pretty arbitrary both ways

work the obvious difference is only if

you test if it's above the max or if

it's under zero in here for frying it

does make sense to start at zero and

then the defraying timer Max

so either that and if the frying timer

if it is bigger than the maximum

so let's get the frying rest PSO frying

recipe so

let's get the frying recipe so with

input so let's get this kitchen object

and get the kitchen object itself okay

so we go into the frying rest BSO and we

get the frying timer Max okay so if it's

above the max then this one has been

fried so here I'll let you see what we

did on the cutting counter

so let's get this kitchen object and

tunnel to destroy itself

and then let's go into the kitchen

object class in order to spawn another

kitchen object let's go into the frying

recipe and spawn the output

and we're going to spawn it inside of

this counter

right so that's it this should already

be working we don't have a visual yet so

let's add a debug log

so here just say debug.log on the frying

timer

and up here let's also just reset the

timer so frying time now let's put it on

zero f and let's also do a debug.log and

say fried

however like this you might already be

guessing that we're going to have a

bunch of bugs but still let's just test

it just like this

okay so over here I can move around I

can pick up some uncooked meat I can

drop it there and after a little bit

there you go there's the timers and if

there you go it did work you can see the

timer increase until three then it was

fried then it was reset and then we've

got a known reference exception

basically this is the exact same problem

that we had on the cutting counter where

first we put an object like tomato and

that is indeed an input for a recipe so

we cut tomato into slices but then the

slices are not an input for any recipe

so over here we put some uncooked meat

so that's great we frying which means we

destroy the uncooked meat and we spawn

the cooked meat but then next time the

cooked meat is not an input for anything

so obviously this one is going to return

no one thing we can do to sort of solve

this problem which is also going to be

beneficial in terms of performance is

simply caching this field so let's go

here to find a frying recipe a cell

frying recipe so

instead of constantly getting it on

every single update which might be a bit

costly in terms of performance instead

of this let's just get it over here when

the player drops something so the player

drops something and we assign the Frank

rest BSO so we sign it cache the value

and then do this okay that should have

fixed the non-reference problem but we

still have a bunch more problems but

still let's test it out okay so here

let's pick up some meat put it there and

let's look at the timer and if there you

go everything is cooking great any of

their yo it finished it cooked and the

time was reset and now it's finishing

it's cooking and so on so this is

obviously another pretty serious problem

basically it's constantly frying the

meat and spawning more and more objects

instead of constantly spawning from the

same recipe what we want is for the

stove to First fry the object but then

if the object is fried then we want to

burn it so really that means that we

want the stove to have multiple States

meaning that we're going to need to make

a simple State machine so let's do just

that now if you're a beginner the

concept of a state machine might seem

daunting at first but it's actually

extremely simple at least to make a very

basic one all we need is really just a

bunch of saints so to define those

States let's go up here and make a

simple enum so let's make a private enum

call it state

and now let's put all the states for our

state machine now for the server let's

say we have idle when there's nothing on

top

then let's say we have a frying state

for when the ingredient is actually

being fried then we have fried for when

the ingredient has already been cooked

but it's still getting some heat and

finally if we leave it too long in that

state then everything ends up burned

okay so these are all of our states for

our state machine

and how to make the actual stick machine

it's actually quite simple first of all

we just need to store the current state

so here make a private of type State and

sort the current state

and then on update let's just do a

switch on the current state

okay now here basically we're going to

do different logic depending on the

state that we're at

so let's say if we're I don't we do

something then if we are frying we're

going to do something else then if we

are on the front also something else and

finally if we are on Burn do something

else

so here are all of our states and the

logic that we did down here this is the

frame logic so let's actually just copy

on this

and let's face it inside the frying

logic and for the seed machine we're

only going to run any of these states if

there's a kitchen object inside of it so

it's actually put that switch in there

just like this

okay so that's it so when I don't we're

not doing anything and when frying we're

going to run our frying timer we're

going to fry the object let's also get

rid of the low we no longer need this

then we destroy the current object and

we spawn a brand new object now what we

need is to handle over here the State

field we need to modify this winching in

Saints so first of all let's handle the

start so let's make a private void start

and on start let's begin with the state

on state DOT Idol okay great then down

here when we interact when the player

drops something when the player drops

something that can be fried

over here on let's set the state and put

it on state DOT frame

and over here we should also probably

reset the timer so let's set the frying

timer back into zero f okay we set the

timer and we reset the state finally up

here let's not reset the timer since

we're resetting the timer down there

since it makes more sense down there so

we do the frying the frying timer we end

the frying and then obviously we need to

modify the state so modify State and put

it on state DOT fright

okay so that's the basics of our state

machine with this everything should be

working just the same as previously

except we're only going to fry once so

let's actually just put them out here

debug the hog

object Pride

and let's put one down here outside of

the save machine just do a debug.log on

the state

okay like this let's test

okay so here we are let's pick up some

meat and drop it on there and there you

go it goes from idle directly into

frying and then it's fried and after you

go now it stays on fried so it no longer

goes on frying and it's no longer

spawning any more objects it went from

frying into fried and yep everything

worked alright awesome

so we have the Frank State working

perfectly now let's handle the burning

in terms of logic it's really going to

be the exact same thing

we're going to have a frying timer so

let's copy this code and paste it down

here now technically we could reuse the

exact same float timer but that would be

a bit confusing so let's keep our code

as clear as possible and really just

make a different timer with a more

descriptive name

so pure a private float called The

Burning timer

then let's initialize this timer so when

we go into the fried State let's set the

timer the burning timer into zero then

down here let's use this Burning timer

okay great when timers and lapse and the

object is spawn let's go into the

Burnside

and obviously we need another recipe

so let's make another scriptable object

back in the editor let's find the frying

recipe so let's duplicate this call it

the burning recipe so

then over here let's modify the name

instead of frying timer Max let's call

it burning timer Max okay great so now

over here on the stove let's use pretty

much the exact same thing and let's make

over here private of burning recipe so

the burning recipe so

then down here we just need a function

to get the burning recipe so so let's

copy this and paste it over here this

one's going to return a burning rest BSO

so let's replace this and this

rename this into burning recipe so we're

going to need an array and over here

let's just change the name instead of

frying recipe so the burning recipe so

let's just find a new array so let's go

all the way up here make another array

an array of burning recipe so and this

is the burning recipe SL ring and

finally if we go down here let's use

this array okay that's it so now let's

use this function to set our burning

rest BSL so when we set it to find let's

set the burning recipe so and let's get

it with the input and the input is going

to be the object that is on here so the

kitchen object dot get the kitchen

object.so

okay so we're initializing our fright

State and setting up the burning recipe

so and over here we use that one dot Max

and we get into that one and use the

output so over there object frying over

here object burned all right so that's

pretty much it we modified everything to

say burning timer over here we are

correctly initializing so we go through

the burning timer through the burning

rest PSO which we are grabbing up here

then we spawn the output on the burning

rest BSO and we go into state.burn okay

so all that's left is just filling in

this array so back in the editor over

here on let's make the object so let's

make a brand new folder for the burning

recipe and so and now inside let's

create a new Burning recipe so call this

one the meat Patty cooked into meat

Patty burned and over here let's set the

input so the meat Patty cooked onto the

meat Patty burned and for timer let's

make it take a bit longer to burn so

let's say five seconds okay that's great

let's just drag the reference so let's

go into the stove counter and let's make

sure to open up and go inside the prefab

and over here on the prefab just write

the burning recipe okay that's great

let's go outside save the prefab and

let's test alright so here we are let's

pick up some meat drop it on there and

look over there it's frying and after a

bit yep it's right there you would spawn

that one and now if we wait for five

seconds it should go from frying to burn

any up there you go that one is charred

everything is burned everything is great

all right awesome so everything worked

as intended with this song of our logic

is working now let's handle on picking

up objects from the stove now

technically it's already working so I

can approach yourself and pick it up the

object and there you go drop it in there

so that does work however if we look

over here in the log the state machine

is now in the wrong state so over here

let's do a quick fix let's go down into

the interact action okay so here it is

so if there's no kitchen object then the

player places it okay that's good but if

there is a kitchen object so if there's

something on the stove counter when the

player picks it up let's also manually

set the state

and put the state back into idle just

like this okay that's it so let's test

okay so over here let's pick up some

meat put it in there it's cooking and

let's wait until it gets finished yep

there you go it's done pick it up and

there you go out now if I want I can put

another one and if there you go the

logic is reset and everything is back to

normal okay great so often logic is

working perfectly now let's just get rid

of our logs so we don't need this so

let's get rid of that debugging log this

one and this one okay great everything

is nice and clean and now let's add some

nice fun visuals so if we go inside the

stove counter and over here is the

visual and I include these two prefabs

inside the visual so one of them this

one the stove on visual this one is just

a glowing red square now again there's a

weird bug on this specific empty version

so post processing isn't showing over

here on scene view but if I leave it

enabled and I go back outside

and now from work in the game view if

there you go there's a nice glowing red

square if you don't see glowing make

sure you add the balloon post Crossing

effect

so if you missed something you can go

back into the post-processing lecture

and make sure everything is set up

correctly so there's a nice glowing red

square and there's also a bunch of

particles so you can name on this one

press on restart and there you go just

some nice particles just jumping up this

was made with the unity particle system

so for example on the hierarchy you can

right click go up here into effects and

you can create a particle system

so that's what this is it has a particle

system over here you can see all of the

various settings for these particles

they just jump up and fall down so for

jumping up that is the emission you can

actually see a visual over there of the

cone that is the spawning cone which you

can find over here on the shape so in

the shape it has the shape of a cone

then you can see the radius radius

thickness and so on so that is from

where the objects are being spawned then

up here you can see the lifetime of each

object so each particle is going to last

for 0.7 seconds

you can all see the speed so that's

speed at which they come from there the

start size that's how big they are on

start

and note how the particles are spawning

jumping up and falling down

so that Falling Down is over here the

gravity modifier if you put it at zero

then they just keep going up and if you

put a two yep they go up and they fall

down

next down here on the emission this is

how many are being spawned so if I put

this on 200 there you go tons and tons

of particles next is over here the size

of our lifetime so this one has just a

basic curve so they started off on font

size and over the x-axis this one is in

a lifetime so as the particle goes from

the beginning until the end their life

they basically go down on size so that

is why they become quite a bit smaller

also by the way this one down here this

one is called an animation curve this is

another really useful ENT feature I have

a dedicated video on animation curves

and finally down here just have the

renderer so it's just using some basic

particles so we can inspect the material

simple in the assets and there you go

we're just using the default particle

material just with the alpha on half and

that's pretty much it so as you can see

just a very basic very simple particle

system now all we really want to do is

just for both of these we want to enable

or disable them depending on if the

stove is on or not so let's make a

script to handle the visuals so let's go

down and create a brand new c-sharp

script let's go with the stove counter

visual then let's go into the stove

counter Visual and let's attach the

script

so here it is attach it and open right

so now here we just need references to

those two objects so as usual let's make

a basic serialized film let's make it of

type game object

for the stove on game object and the

other one is the particles game object

okay let's save and back here in the

editor let's drag the references so the

stove on Visual and the sizzling

particles okay great so now all we

really need to know is know when to turn

these on or off and for that is really

going to be based on the state over here

on the stove counter so if it is on the

state frying or fried then we want to

show them if it is on idle or burned we

want to hide them but as usual we don't

want to mix the logic and Visions

directly so let's do that through a

really nice event

let's make a public event let's use a

standard event handler let's call it on

stay changed

and let's also include the state on the

event Arc so let's make a public class

call it on state change event args and

let's expand event arcs and then in here

let's just put a public state

for our state

however here we also have a really nice

error so this one is telling you there's

inconsistent accessibility basically

that's because we made this one public

so any class link for his Mr visual

class can indeed see this class however

from outside that class cannot see the

private state

so that is why we have inconsistent

accessibility we cannot have something

public which inside has something of a

specific type which is private

so in order to make this work we need to

modify this state and make it public so

that the other classes can see it okay

so that's great now let's just fire this

event whenever the state changes so over

here when you go into the frying State

let's go and invoke and as usual just

this

and I actually forgot to add that so

let's go up here let's use the one with

generics so the on state change event

arcs okay great so then down here we

invoke the event let's create of this

time

and inside passing the state equals this

state

okay so this one we need so then down

here go into the burn State let's fire

the event and down here frying fire the

vent and on idle fried event alright

that's it so we have all of our state

logic and over here on the stove counter

visual obviously we need a reference to

the counter so let's add that so a

serialized field private

maker of type stove counter for the

stove counter and then we can do an as

usual for accessing external references

let's do it on start go into the stove

counter and let's listen to the on say

change event

and over here it's going to be very

simple we just want to show if it's on

the state frying or fried and if not we

don't want to show so let's define a

bone called show visual

and this one is going to true if the E

dot State equals the state DOT frying or

E dot State equals

the state DOT fried

so if it's either of these then this is

going to be true if not it's going to be

false so then let's just go into the

stove on game object

and constant active and pass in this

and same thing for the other for the

particles game object okay that's it

super simple let's just drag this

reference so over here inside the prefab

just drag the reference let's leave the

prefab save the changes and let's hit on

play and all right so it starts off

disabled okay so there's no visuals now

if I pick it up and I drop it and there

you go a nice visual so the glowing red

hot and the particles and now it's

running and if I leave it until it burns

when it burns and it's going to turn it

off and if there go turns off

all right awesome so now if I pick it up

wait until it gets cooked so let's go

pick it up and the other you go turns it

off

all right awesome we've got a really

nice visual all that's left is to have a

proper visual progress bar and with this

we actually have another interesting

clean code question

right now the progress bar that we made

over here on the cutting counter that

one is great so we would like to reuse

that however if we look over here on the

progress bar UI we can see this is only

working with the specific type cutting

counter

so by default this will not work with a

stealth counter so as usual we have

multiple approaches to solving this

problem one option would be to Simply

commonly duplicate the script then we

would make a completely different

progress bar UI class that would work

only with the stealth counter so that's

one approach that would work and that

approach might be good if you want the

progress bar to behave very very

differently

but over here I want both of them to

behave exactly the same so instead of

having some code application we can

write some good clean code but doing

exactly what we did with regards to the

kitchen object parent meaning we can use

a nice interface we can then Implement

on anything that has some kind of

progress so let's do exactly that first

of all let's actually go inside the

cutting counter so let's go inside the

prefab then over here we've got the

progress bar and this one is just a

regular game object but since we're

going to reuse this let's make this a

proper prefab so let's find over here

all of our prefabs and just drag the

progress bar UI inside the prefabs

folder okay great so this is now a

proper prefab now let's define our

interface so let's create a brand new

c-sharp script as usual interface start

with I so let's go on I and for this one

we wanted to represent anything that has

progress so let's just call it literally

has progress

personally I like to use the word has to

indicate that a certain object has

certain Behavior so in this case objects

that implement this interface will have

some kind of progress Behavior so now

over here for the interface let's first

make it so this one does not extend

amount of behavior instead of a quest

this one is an interface okay great so

now for the functions that we're going

to need if we look in the progress bar

and we'll look at the cutting counter

references we can see the only one is

literally just this so we just have to

listen to the event and then the rest of

progress bar Works inside of it so real

and interface is the only thing we need

to Define so let's actually go inside

the cutting counter so here we have the

unprogress change event and then we have

this so we can literally just copy this

go into the I has progress and let's put

exactly this

okay that's it that is literally all we

need now if we wanted we can also make a

function to expose the progress amount

but since we included over here on the

event then we really don't need it just

this is enough now let's go over here on

the progress bar UI script instead of

working with the type cutting counter

instead let's work with a type that has

I has progress so let's rename this Q

has progress

and it's going to have the exact same

event the only difference is over here

instead of the event RX being the one

inside the cutting counter is the one

inside the eye has progress so let's

make sure to change this I has progress

okay so the signature matches let's just

obviously rename this

so let's rename instead of cutting

counter let's rename has progress on

progress change and that's pretty much

it we don't have any more errors so

everything over here is now working

nicely with our interface and back here

in the editor once we're still inside

the cutting counter

suddenly interfaces do have one downside

when it comes to Unity

if we look in the progress bar UI down

there we can see the progress bar UI and

previously we had the counter field

exposed in the editor however now by

changing into an interface there we have

the issue the film does not show up here

interfaces do not show up in the editor

because Unity basically has no way of

knowing that the interface won't be

implemented by some kind of game object

so sadly this is the one thing that

doesn't work very well with unity the

solution that I normally do is actually

pretty simple instead of exposing the

interface which does not work and said

let's just make this a regular private

field

and then let's make a serialized film

and for this one let's make it a type

game object and let's call it has

progress game object

okay so like this we have a regular

serialized field with a regular game

object so if you look here yep we do

have that field so now we can indeed

Drag The Cutting counter reference and

then over here in the code in order to

get the has progress that is super

simple has progress we just go into the

hash progress game object and get

component of type I has progress

okay so that's it now our code does work

however of course one big potential

issue with this is that over here we

have a field of type game object meaning

that we have no guarantee that this

field does have a component that

implements the interface so we cannot

make sure that we drag the correct

reference we can drag any reference

doesn't have to have our progress

interface so in order to keep our sound

safe let's add a nice safety warning so

over here if has progress equals no so

if this one is known that means that

that game object does not have any

progress interface if so let's do a

debug download error

and let's say the game object and let's

pass in this game object

does not have a component that

implements I has progress

so this way if we make a mistake we

won't have a nice error message

basically this is the one workaround

that you need to use since Unity does

not support dragging references in the

editor if they are interface references

okay so with that everything is good so

all of our progress bar UI this should

all be working perfectly we just need to

go over here into our cutting count

script and let's make it so that we

Implement our interface so I has

progress and we got an error just

because even though we did Define that

interface remember the on progress

change again keep in mind that the types

depend on not just their name but where

they're at so this type that we have

here is the one that we Define here

which is not the same one that we have

here so even though they have the exact

same name because they are in different

places they are actually different types

so we need to make sure to use the type

in the interface over here let's just go

into the I has progress and use that

exact type and get rid of this one okay

so that's it that's the change we need

and down here when firing let's just

fire with that type and down here the

same thing with that type okay great so

like the this The Cutting counter should

still be working exactly the same as

previously again when refactoring any

code always do a quick test and let's do

that let's make sure to save our counter

save the prefab go back outside head on

play now let's pick up some cheese put

it there cut and there you go the

progress bar still does work okay great

now let's apply it to the stove and that

is actually going to be very simple

first let's go inside the stove so let's

find the stove counter let's open it up

go inside the prefab and over here let's

drag the progress bar UI prefab so let's

drag that then down here we already have

the has progress game object so let's

drag the stove counter and that's it

there's nothing else we need to touch

here we just need to go over here into

the stove counter and as usual let's

implement the interface so the eye has

progress

and now let's implement it pretty much

just like we did on the cutting counter

so we can actually just copy this so we

just need to implement the event so

that's it and now for firing the event

let's go down and see where we are

modifying all of our timers so let's go

down to when the player drops something

so we do the on say change and now let's

invoke this event so this and for the

progress bar for the progress normalize

this one is very simple so just frying

timer divided by the frying recipe so

dot frying timer Max

okay that's it we are modifying the

progress now let's go up here when we

are in the Frank State and when we do

let's fire off the on progress change

event okay great and finally down here

when we have defined over here let's

also fire except obviously we have the

burning timer and the burning timer Max

and then just to make sure that the bar

actually hides itself when we go into

burned let's also find an event this one

doesn't have a timer so let's just put

it on xeraf okay that's really it

we don't need to touch the progress bar

UI at all Let's test this just make sure

to save the prefab let's go back outside

and hit on point and right away yep the

bar is indeed hidden now if I pick up

some meat and I drop it and there you go

got a really nice bar going up any up

going up on the burning site and let's

get to the end let's see if the bar

hides so it gets to the end and you have

to go the bar that's high all right

awesome and if I pick up something

actually this was the one event that we

forgot so let's fix that so let's just

copy the one where we set the progress

normalized to zero and over here if the

player picks up something let's add the

progress back into zero

so here we are let's pick up some meat

drop it on there okay let's wait for it

to be cooked okay it's cooked now before

it burns pick it up and there you go the

bar is gone all right awesome okay so

here we have again another example of

the power of writing good clean code we

made a nice generic progress bar and we

very easily made it work with a

completely different counter which of

course would also work with literally

anything that implements that interface

doesn't have to be a counter now let me

make one note here basically I showed

you how to make a generic progress bar

and reuse it but let's say you want to

do something specific just for the solve

well one approach like I mentioned is to

duplicate the code and make a progress

bar that works only with the solve but

another approach is to Simply add more

elements on top

for example during the Polish stage

we're going to do exactly that

we're going to add an extra UI element

that won't show up to one of the player

when the food is about to burn so I just

want to point out how you can mix and

match both them you can have both

generic components coupled with specific

components

but for now our progress bar everything

is looking pretty good so let's leave

that burn warning just for the police

age now the next very important thing we

need is some points so let's do that in

the next lecture

hello and welcome I'm your kudmaki in

this lecture we're going to create the

plates counter this one is just going to

spawn some points which we can then pick

up to grab some objects okay so let's

begin making the counter as usual so

let's go inside our prefabs inside our

counters right click the base counter

make a new prefab variant

called the plates counter

let's go inside and let's drag the

visual for the plates counter let's go

into scene view so we can see it okay

let's duplicate this make this the

selected let's go inside and we can

actually hide the Eternal Sprite we only

need this one so on this one let's

modify it for the counter selected on

the selected let's make it just one

percent bigger and let's add the

selected counter Vision okay then inside

obviously drag the reference for the

kitchen counter okay that's our basic

setup now let's make our script to run

this so let's create a brand new c-sharp

script for the plates counter let's

attach the scrub to the plates counter

and open okay now here as usual let's

extend our base counter and then first

let's handle the spawn timer logic so

basically we want to spawn some plates

every once amount of time

somewhat sorry simple float for the

spawn plate timer then let's make a

simple update on timer let's increase

the spawn point timer by time dot of

time

and then just check if it's above a

certain maximum

so if it is above something in this case

we're going to have a fixed value

but still like I mentioned in the very

beginning of this course let us not use

magic numbers here you should never use

magic numbers

instead if you wanted to make it edible

you could also make it up here as the

serialized field but in my case for

design that I'm going for I'm perfectly

content with having a fixed value so

just appear pretty simple the spawn

complete timer Max and let's define it

to 4f

and let's use it over here okay great so

this is what we want

however for spawning it's actually going

to be a bit tricky the plate is supposed

to be a kitchen object the player should

be able to carry the plate and right now

for design that we Define is that each

kitchen object can only have one parent

and each parent can only have one object

but over here we want to spawn multiple

objects now let's quickly see what

happens if we try spawning multiple as

usual so let's just go into the kitchen

object spawn a kitchen object which

means we need the plate so so let's do

it up here as usual a serialized film

private kitchen object so for the Plate

Kitchen object SL

so we're going to need to make this and

then we're just going to spawn this

object on this

okay so this is going to throw an error

but so let's see let's first create the

object

over here let's go inside our objects

our kitchen objects let's create a brand

new kitchen object call it just the

plate for the object name this one is a

plate for the Sprite let's go with the

plate Sprite and for the prefab let's

make it so let's duplicate one of these

called the plate

let's go inside it and obviously make

sure to change say the changes then over

here let's drag the plate visual get rid

of the tomato and on the plate let's

make sure to assign the plate and

finally let's exit this let's make sure

to save it and on the plate let's drag

the plate prefab okay so we have the

kitchen object so now let's just go

inside our plates counter and over here

let's drag the reference so the

reference to the play kitchen object

let's also drag the reference to the

counter top point then on the selected

drag the reference to our base counter

and finally start off with a selected

disabled okay so this should be working

let's just add a plate counter over here

onto our scene so let's pick up a police

counter and put it somewhere in here

over there on the side so on an X of 7.5

then 0 and let's say on zero Maybe

let's make sure we have space for one

more counter over there so let's

duplicate this empty counter and let's

put it over there pointing to the side

so this one is on 7.50 and -2

okay so now let's just make sure that

they perfectly match so let's put this

one on a set of minus 0.5 okay so let's

test all right so here we are and look

at that and after four seconds if there

go it spawns the object and then it

immediately tried to spawn another one

and there you go we have the error

kitchen object parent only has a kitchen

object basically the way we designed our

game and set up the code assumes that a

single encounter will only hold a single

kitchen object so we cannot have

multiple plates on the same counter now

when solution for this problem is

actually quite simple when we spawn the

plates instead let's not spawn a kitchen

object instead we're just going to spawn

a dumb visual then when the player

interacts with the counter that is when

we're going to spawn the proper kitchen

object so let's do that although again

let's keep the logic and division

separate so over here let's first just

handle the logic so we just need to keep

track of how many points respond so for

that let's start up here you private end

for the plates spawn amount and let's

also do another private end for the

plates Pawn amount Max

and let's say we can spawn at most four

plates

okay so over here instead of spawning

the object let's first of all actually

reset the timer

so let's put it back to zero zero and on

the plate spawn the mount let's check if

this one is under the plate spawn Max

and if so

let's go into the plate spawn amount and

increase it by one okay so that's logic

super simple now let's send the visual

so let's first make our script so let's

create a brand new c-sharp script for

the plates counter visual

now let's make sure that the visual so

let's go inside the prefab and over here

we've got the visual let's attach it

okay open now here basically the first

thing we need is we need to know where

to spawn the visuals

so let's actually add a reference to our

counter top point

so let's add a serialized film for

private transform for the counter top

point then let's also add a reference

for the prefab we're going to spawn so

let's call it the plate visual prefab

then here in the editor let's drag the

references so the countertop Point Place

it in there and for the plate vision

prefab let's go a pair and find the

visuals for the kitchen object so these

are just the visuals and let's write the

plate visual so the plate visual not the

Plate Kitchen object okay now back in

the code here we obviously need to know

when I play this Bond so let's go into

the plates counter and make a nice event

so fun week event event handler as usual

on plate spawned

and down here let's just find the event

so we just invoke

with this and eventar is not empty

okay that's it very simple and then on

the other script over here let's just

listen to it which also means that we

need a reference to our counter so let's

add up here the plates counter for the

plates counter so we're going to need to

drag the reference and then on start

let's listen to the on plate spawned

event

and when that happens then let's spawn

so let's call instantiate on the plate

visual prefab

let's put it inside the counter top

point so this is the transform for the

plate visual transform and that's pretty

much it okay so unlike this it should be

working

when the plate is spawned we should be

spawning a brand new visual back in the

editor we just need to drag the plates

counter reference like that let's exit

save the prefab and let's test okay so

here we are and if we wait for four

seconds we should be able to see a play

spawn yep there you go and if we wait

for a little bit more we should also be

able to see some more play Swing spawn

except we can't really see them that's

because we're spawning them on the exact

same spot every time but if we pause the

game and over here I'm looking the

hierarchy and find the plate counter and

inside the counter top Point yep we do

have four visions and if we wait for

longer then nope it's not going to spawn

anymore it's only going to spawn four

plates okay great

so some of the visual let yourself set

them by a tiny bit to know how much we

shouldn't offset let's keep track of how

many plates haven't spawned

so let's store up here on the visual

script in list of Game object

call it the plate visual game object

list

let's also make sure that you initialize

this so it lets you on awake let's

initialize this list

and then when we spawn them okay so here

we have the object that we spawned now

basically we just need to modify the low

composition

and let's put it on new Vector 3 on the

X so let's put it on zero then on the Z

we're also going to have zero and then

over here on the one let's offset it by

a certain amount and basically it's

going to be based on how many plates

have been spawned

so let's define up here a float for the

plate offset y let's put it at save 0.1

f

and over here we're going to offset it

by this much multiplied by how many

plates have been spawned so we can go

into our visual list account so you can

delete this and then we just need to add

it to the list so let's add this plate

visual transform.game object okay so now

each game object should respond at a

different height so let's see so here we

are and if we wait for four seconds we

should be able to see a plate and there

you go and now after four seconds we

should be able to see another one placed

slightly above and yep there it is okay

great

so everything is spawning perfectly both

in the logic as well as the visual now

let's actually pick up a plate so on the

plates counter as usual let's implement

the interact

so let's do a public let's override the

interact function

and now for picking up let's first see

if the player is actually empty-handed

so if and we check the player has

kitchen object so if the player does not

have a kitchen object

then the player is empty-handed okay

great then let's see if we have a plate

that we can give them so if the plate

spawned the mount if it is bigger than

zero

then there's at least one plate here and

if so let's give it to the player so how

we do that is one over here for logic

let's just increase it by one then let's

actually spawn the object so on the

kitchen object let's spawn the Plate

Kitchen object so and spawn it on the

player

and finally we just need to update the

visuals so let's make another event

so up here on plane spawn and on plate

removed

okay we have this event and then down

here on let's just whenever the player

picks it up let's invoke this with this

an event RX dot empty

okay great so now the visual let's

listen to this so we're here on start

for the plates counter listen to this

event

and when this event happens we just want

to destroy the very last plate

so let's grab the game object for the

played game object and recently just

going to go into our list so the plate

visual game object list

and let's pick up the very last one

so let's go into the list.count minus

one so this is going to be the very last

element of the list then let's remove

this one from the list so Point dot

remove this one that we just grabbed and

then we simply call destroy on this one

all right so that's it super simple

so we're here on the plates counter we

do all of our checks we cut it down by

one

we spawn the actual kitchen object then

we fire the event and over here the

event listens and updates a visual okay

let's test

so here we are let's wait for a play to

be spawned and when this phone there it

is I'm going to pick it up and if there

go the player is now carrying a plate

let's drop it here and there you go

there's another one now let's wait for a

bunch more to be spawned okay so the

plates counter is full now if I pick up

it should only eliminate the last visual

pick it up any of there you go it'll

eliminate that one now I can drop it in

there any other ones one all right

awesome okay so that's really it for the

basics of the play counter it

periodically spawns some points which

the player can then pick up

now in the next lecture we're going to

add the ability for the player to be

holding a plate and pick up another

object onto the plate

hello and welcome I'm your code monkey

in this lecture we're going to add the

ability for the player to be carrying a

plate and pick up objects onto that

plate okay so here we already have the

plate counter working it has some basic

logic after a bunch of time it spawns a

plate it spawns up to a certain maximum

and I can pick up a plate and if the

player is carrying a plate so I can put

it anywhere

then I can for example pick up some

Tomatoes slice them and pick them up

however now I am not able to place the

tomatoes on the plate so let's add that

logic let's begin over here on the clear

counter script first we're testing if

there is no catch an object here and the

player is carrying something that the

player drops something in there but then

we're testing if there is a kitchen

object here and if the player is

carrying something so it's over here

that we want to check if there's

something that the player is carrying if

it is a plate now our plate is also

going to have a bit of custom logic so

to help both identify and hold that

custom logic let's make a proper script

to handle it

so back in India let's create a brand

new script currently the Plate Kitchen

object

and let's open this now over here on

this one instead of extending Model

Behavior we're going to extend kitchen

object

so the plate is really just a more

specific type of a kitchen object

again like I mentioned quite a while ago

you want to be very careful with

inheritance you need to have a very good

reason to do it here we want the play to

behave exactly like a kitchen object

just with a tiny bit of extra logic so

in this case it makes perfect sense

let's just go ahead and save this and

wait for ENT to compile and over here

let's find our kitchen object with the

plate so here it is the prefab as you

can see we have a kitchen object now

instead of having that one let's replace

that with the play kitchen object and

since we are extending kitchen object we

have the same Fields so let's make sure

to add the kitchen object as so and get

rid of the other one okay great so now

back here on the on your counter when

there is a kitchen object here and the

player is carrying something we can

check if the player is holding a plate

and for that we can check the type

so if let's go into the player and let's

get the kitchen object the player is

holding and we test if this object is of

type Plate Kitchen object

if so then that means player is holding

a plate and if that is the case then we

basically want to give the player

whatever object is over here we want to

add it to the plate so let's go into the

plate script to add that function so

over here let's make a public Point

let's call it add ingredient

as a parameter we're going to receive a

kitchen object as so we really only care

about the type we're going to destroy

the actual kitchen object like we've

been doing when creating different types

so the plate is really just going to

store in list of types so here let's

store a list of kitchen object a cell

for the kitchen object that sell list

then when we add the ingredient let's

just add it to the list so this kitchen

object is so let's also make sure to

initialize the list so let's see what

I'm awake let's initialize our list and

now from the other side we just need to

call this so over here on the clear

counter if the player is holding a plate

let's first get the type of plate so

play kitchen object or the Plate Kitchen

object we go into the player to get the

kitchen object and we cast this as a

plate kitchen object

okay so we have this and then over here

let's call add ingredient

and let's add whatever is currently on

this counter so let's get the kitchen

object and get the kitchen object itself

okay so we're adding it to the plate and

then let's destroy what is here so get

kitchen object and destroy itself

okay so that's it so if there is

something here and if the player is

holding something and that's something

the player is holding as a plate if so

we're going to add that ingredient to

the plate and then destroy the object in

here so let's test okay so here let's

pick up a tomato let's slice it let's

put it on a clear kitchen counter

because that's the only one where we

added logic so on this one let's pick up

a plate and now whilst I'm carrying the

plate and if I approach and I interact

with it and if there you go it does work

the object vanished from the counter and

supposedly was added to the plate again

we can use a really nice debug inspector

to see it so let's pause the game Let's

select the plate let's see the play

kitchen object so here it is this one

and let's change the inspector into

debug mode and down here yep we do see

the kitchen object that's on list and it

does have some tomato slices okay

awesome so with this here we have our

basics

we can have some ingredients and we can

basically pick it up from a plate now

one thing about our plate this is where

we're basically going to carry the final

recipe that we're going to deliver to

the customers and based on the design

that I defined I want something pretty

simple meaning for the design that I'm

going for there won't be any kind of

double burgers or double cheese so each

final recipe will only have at most one

of each ingredient

so let's add some basic logic just to

prevent adding duplicates over here on

the Plate Kitchen object when we add an

ingredient

since the function will now not

necessarily succeed every time let's

actually rename this and again use a

very useful Visual Studio shortcut so

you can press Ctrl RR or right click and

let's rename

since this function will no longer

succeed we're just going to try to add

an ingredient so try add ingredient and

then let's also make it return a buoying

basically for any function where you're

not sure if it won't succeed I like to

add try and make it return ball so this

way it works pretty much exactly like

the try again component that we've

already seen so many times so it tries

to do something and returns whether it

succeeds or not so over here instead of

always adding the ingredient let's see

if this one is a duplicate so let's do

an if and let's go into the list and

check if the contains and if the list

summary contains this kitchen object as

well

if though then already has this type so

let's return false and if not

then that means it's a brand new

ingredient

so let's add it and return true okay so

that's it now let's go over here onto

the clear counter so we try to add the

ingredient but then we only want to

destroy if this one succeeds so let's

put this one inside an if so if we do

manage to add the ingredients

then yes let's destroy itself if not

then we don't destroy anything okay so

let's test

so let's go ahead and slice two tomatoes

so one slice it put it here then another

one slice it and put it here now let's

pick up a plate go up here try to pick

up this one and yep it does work now for

this one and I hope it doesn't work okay

great now one more thing in our logic we

only want to pick up certain things like

I said only things that won't be used in

the final recipe

for example no customer is ever going to

request a full entire tomato the recipes

only have sliced tomatoes so we should

not be able to drop a foam tomato

directly on top of a plate so let's

change that so over here on the plate

script let's basically just create a

list of our valid ingredients

so let's make a serialized film private

make it a list of kitchen object SL

ope and call it the valid kitchen object

SL list okay so we have this list and

over here in the editor let's just write

the ones that we want so let's first of

all select the plate object okay here is

the flight prefab and over here we've

got all of our kitchen objects so let's

just write the ones that we want to add

to the point

so the final recipes will have some

bread yep but they will not have entire

cabbages they will only have cabbage

slices same thing no cheese only slices

for the meat we're only going to be able

to add meat cooked but also meat burned

then we're not going to be able to add a

plate onto a plate of course not and

finally inside of a tomato just tomato

slices okay that's our Vellum list and

over here again it's very simple

so we can just go if the evaluate

kitchen object that's on list if this

one contains the one that we want to add

then we can add it but if not then let's

return phones

not a valid ingredient

okay so let's test alright so let's pick

up a tomato and also some tomato slices

and now if I pick up a plate and I go

into the Tomato nope doesn't work but

the slices yep it does work okay great

so here we have all of our basic plate

rooms everything is working perfectly

but it's only working over here with the

clear counter so let's do a little bit

of code cleanup and then let's add this

logic to all the other counters so first

to clean up this cone over here we are

testing if this is a plain kitchen

object then we cast to an object and

then we count the function so let's

simplify all this

and let's do it just like yinty does

with their try and get the component

function so let's make a custom function

that takes an output parameter the best

place to put it is on the kitchen object

so here we've got the kitchen object

script okay great let's scroll down and

make a nice function here so let's make

it public we're going to return Boolean

in case this succeeds or not let's

currently try get plate and over here

let's make an out parameter so don't

forget the out keyword let's return of

type Plate Kitchen object for the play

kitchen object then over here we do

examine what we did so we test if this

object is a plate kitchen object

if so then let's set the play kitchen

object equals this as a play kitchen

object and we return true but if not

then this is not a plate so let's return

false and one thing when working with

output parameters you always need to

make sure to set the output before you

exit the function

so over here that's the error that it's

telling us

we must assign it to something when we

return so over here we don't have a play

kitchen object so to solve this we just

set this to no okay great now over here

on the clear counter instead of doing

all this basically let's ask the player

if this is a kitchen object

so let's try to get the plate

out Plate Kitchen object for the Plate

Kitchen object

so you try to get it then we try to add

the ingredient and so on now obviously

we could further simplify things by

making a function that would try to get

the plate and try to add the ingredient

that could work but since some counters

are going to have a bit more custom

logic I think keeping them separate like

this makes more sense so first we try to

get the plate then we try to add the

ingredients so let's apply the same

logic to The Cutting counter

so over here on the cutting counter

let's scroll down to where there is a

kitchen object here and the point is

carrying something so on the earlier

counter we just want to copy all of this

so let's go over here and we do the

exact same thing okay that's it and the

other counter from where we can pick up

things is from the stove counter

so here we are on the stove let's scroll

down until we find the interaction okay

there's something here The Player's

carrying something so it's over here

let's do that and do the exact same

thing except on the stove again let's

remember that this is using a save

machine so when we pick up something

let's do pretty much the same thing that

we did here so let's make sure to reset

the State Fire the events and so on okay

so those are the only counters that we

need to implement we cannot drop things

on top of a container we cannot drop

things on top of the plate counter or

the trash so these are the only three

types that we need to implement so with

this let's test okay so let's begin with

some meat so let's pick up some meat put

it on the stove let's pick up a plate

wait for it to cook pick it up any up

there you go it does work now it says

the cut encounters and let's pick up

some cheese and let's slice it pick up

some plate and go any up there you go it

does work and again if we inspect we can

make sure that it is indeed working so

let's get into the plate and let's put

this on debug inspector and if there we

do see this one has a meat Patty cooked

and some cheese slices okay great now

the last piece of logic that we need is

pretty much the opposite so right now it

works if there's a sliced object on the

plate and the player is holding a plate

object but now we want the opposite so

let's say there's a plate in here and we

slice some cheese and now I want to drop

the cheese on the plate so let's do that

and basically for this one this one is

only going to happen on the clear

counter that's the only counter type

that can have a plate on top of it so

over here on the clear counter then we

check if there is no object there but

that's not what we want we want if

there's a plate on the counter so if

there is an object there and if the

player is carrying something

then we check if the player is holding a

plate but if not so if the player is not

holding a plate

so player is not carrying plate but

something else over here we need pretty

much exact same logic except just

testing for the object on this counter

so let's do if let's get the kitchen

object on this counter this one try to

get the plate so out play kitchen

objects for the Plate Kitchen object so

if so if so there's a plate over here

that means the counter is holding a

plate

so then let's go into this play kitchen

object let's add the ingredient

and we're going to try to add whatever

the player is currently carrying so the

player dot get kitchen object

and get the kitchen object as so

so we're going to try to add this

and if we can add then we're just going

to destroy whatever is on the player

okay that's it and over here we've got a

nice error just because we've defined it

with the same name appear so up here

we're already defining the variable and

over here we're defining the same

variable with the same name

so we can either give this a different

name or just not Define a brand new

variable here so just it's a fine up

here and we're using it here okay so

while logic is working now here make

very sure that you're not mixing

references keep in mind when you're

referencing the kitchen object on this

counter and the one on the player those

are two different things so over here if

the player is not carrying a plate but

something else then you check the

kitchen counter so over here you're not

checking the player but checking the

counter then you go into that point and

try to add the ingredient and you try to

add the one that the player is carrying

and then you destroy the one the player

is carrying so again be very careful

here make sure you don't mix references

so with this it should work so let's

make sure to save our script and let's

test okay so here we are let's first

pick up a nice plate let's drop the

plate in there pick up some bread drop

the bread any of there you go it does

work alright so now we can do a bit more

natural interactions so for example

let's pick up some meat and put it on

cooking and there you go the meat is

fried so now I'm currently carrying just

some meat so I place it there then I

pick up some bread and put some bread on

top of the meat and yep everything does

work policy okay so here we created the

plate and we created some custom logic

to Define what the plate can and cannot

account no that's left is actually being

able to see what is on the plane so

let's do that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add a

nice visual to our plate okay so right

now we can already pick up ingredients

under the plate so if I pick up the

plate and I pick up some cheese there

you go there's some cheese on the plate

but we cannot see it so let's solve that

and we were going to do that it's

actually in a very simple way

if you look in the included assets

inside the prefab visuals there's this

nice plate complete visual that I built

basically it's a foam burger that

contains all the ingredients what we're

going to do is actually very simple

we're just going to enable or disable

these game objects that's it so let's do

example that let's make a new c-sharp

script quality plate complete visual

let's attach a script over here and

let's also make sure to put this one

inside the plate so let's save this

prefab let's go inside the play prefab

so inside the prefabs here the kitchen

objects we've got the plate so inside of

the point let's drag that let's drag the

plate complete visual okay great so now

let's open up this script over here on

let's first have the reference to our

Plate Kitchen object

film private for the Plate Kitchen

object for the Plate Kitchen object

back in the editor let's drag the

reference okay great so now here

basically we need to update this visual

whenever the plate gets any ingredient

added to it

so let's go over here into the point

script and basically just need to fire

off an event when that happens

so let's make a public event event

handler and let's call it on ingredient

added

okay and for this one let's also make an

event RX to contain the data of what

object we added so let's make a public

class on ingredient added event args

let's extend event args and inside let's

make just a kitchen object a cell

kitchen object as well

okay great and let's make the event of

this time

all right so now let's just fire off

this event so down here when we try to

add an ingredient if we do add the

ingredient let's fire off this event so

let's invoke with this and let's create

a brand new one passing the kitchen

object as so as this kitchen I'll take

this off okay so we have our event

correctly being sent now we're here on

the play complete visual let's listen to

it again as always let's make sure to do

it only on start so the play kitchen

object on ingredient added let's listen

to this event and over here we just need

to either enable or disable the visuals

that relate to the kitchen object inside

over here the event arcs however of

course the question is how exactly do we

find them the point complete visual has

all these game objects how do we know

which one belongs to that kitchen object

now technically one way would be to do a

simple transform find and find the

channel objects by name technically that

would work but like I mentioned in the

beginning of the course strings are a

horrible way to identify things they are

very air prone so let's not do that

instead let's use a proper approach

where we can Define some kind of link

between a kitchen object a so and a game

object and we can do this very easily by

justifying a struct so here in our

script let's do exactly that let's

define a public

make it a struct

and name it kitchen object so underscore

game object

then inside it's very simple we just

have a kitchen object so field

and then also a game object field

that's it super simple by the way if you

don't know what is a struct basically

it's very similar to a class except it's

stored in different places in memory and

behaves somewhat differently

I have a very very important video on

that subject what is the difference

between value types and reference types

classes are reference types so when you

pass in a class into a parameter you are

passing in a reference to that object

whereas struts are value types so when

you pass in a struct onto a parameter

you are passing in a copy it's a bit of

a tricky thing so definitely make sure

you go watch that video for more details

so you don't get confused in the future

here I Define that as a struct simply as

kind of a teaching moment but also

because it just makes sense that if I

just want to store some data without any

logic then it should probably be a

struct and not a class although in this

case the class would work just as well

anyway so here we have a struct inside

the struct we have a field of type

kitchen object so another one of type

game object so now let's just make a

list of this type that we can expose in

the editor so here a serialized film

private let's make it a list of kitchen

objects so game object and call it

kitchen object so game object list

okay that's it super simple so let's

save and make sure this compounds so

actually let's just comment this out

just make sure our code compounds okay

and over here in the editor we see the

tricky thing when it comes to using

fields of custom types if we look in the

inspector no we don't see anything so we

cannot see our custom type in the

inspector if you make a custom time like

this front and you want to show it in

the inspector then you need to add the

attribute serializable which exists

inside system so let's go up here using

system

and let's say the attribute serializable

just like this okay so do this save and

let's look and if there you go now we do

see our custom struct so we've got a

list then we can click on the pause icon

and there you go we've got an element

and it does have a film for a kitchen

object so and one for a game object so

that's great with this now we have a

really nice place where we can link one

object to another so let's just do

exactly that so for example let's put

the bread over there and let's assign

the kitchen object as so for the one

with bread let's do the same thing for

all of the others so let's add a whole

bunch more Okay so we've got the bread

then we're going to have the meat Patty

cooked then the tomato slices then we

have the cheese slices the Cabbage

sliced and finally the meat Patty burned

so I've got number zero through five so

you have six elements and over here yep

we do got six so we have all of them we

can get rid of these last two okay great

and now let's assign the proper objects

so this one for the meat Patty cooked

then we've got the tomato slices then we

have the cheese slices then the Cabbage

slices and finally the meat Patty burned

okay great so all of the references

match now back in the code here so we

have this List fully filmed out and when

we have this really very simple we just

cycle through the list to find the right

game object it's similar to a 40 inch of

type kitchen object so game object

in our kitchen object so game object

list and we check if this kitchen object

is so dot kitchen object matches the one

that we received in the event

if they do match then go into this one

grab the game object and set active into

true

okay so that's it some very simple logic

and also we can start with them disable

them by default in the editor or just

over here just use something very simple

just do a for each second through every

single one of them and set every single

one of them to false so that they are

hidden okay so with this on the

ingredients on the plate should be

visible so here in the editor let's just

make sure all the references have been

set let's go back save the prefab and

let's set on play okay so here we are

and by default like that an empty plate

and yep it is empty and now let's slice

some cheese now let's Place some cheese

on there and there you go we've got some

cheese now let's pick up some bread drop

some bread and there you go got some

cheese and some bread

then let's cook some meat so let's cook

it and let's pick it up with a plate and

as soon as I go boom there you go I've

got a nice cheese butter

all right awesome so wait a second I'll

do a complete Burger so let's finish it

let's just add some more tomatoes so

slice them and add the tomatoes and

finally some sliced cabbages slice them

put them there and there you go here we

have a fully complete Burger okay so

that's great all of our vision logic is

indeed working however this visual is a

bit hard to see it's not very clear to

the player so just looking at it from

this distance does that have a tomato or

not

there's a tiny sliver of red in there

but you can't really see it

so we should probably add some nice

clear icons on top to clearly indicate

what exactly is on this plate so that's

exactly what we're going to do in the

next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add some

really nice icons on top of our plate so

we can easily see what is on there okay

so for the icons let's do the exact same

thing that we did for the progress bar

meaning let's use a warm space canvas so

let's go inside our play kitchen after

prefab and over here on let's right

click let's create a brand new canvas

let's name this the plate icons UI then

for the settings let's make it World

space put it on zero zero everything

width and height also on zero then let's

lift it up a little bit so put it on a y

of one okay like that now inside let's

define an icon

so let's start by making an empty game

object call this just the icon template

let's put it with a size of 0.3.3 it's

okay something like that then inside

let's add a new UI image name this the

background

and make it stretch to film The

appearance so put 0 on everything okay

there's our background

for the background image instead of a

square and let's actually go with a

circle for that Unity actually has a

bunch of built-in Sprites that are

tatted in the last versions however it's

not actually over here by default

in order to see those default Sprites we

need to install the 2D Sprite package so

let's quickly just go into window

package manager let's make sure we are

in the UNT registry make sure we aren't

looking at all and over here let's find

the 2D Sprite package okay so let's

install this

okay there's the package so now if we go

into the background and we search for a

Sprite and over here make sure you click

to actually show the assets from the

packages and now we see a bunch of

default hexagons a bunch of isometric

tiles the square so on and if we search

for Circle yep here we've got a bunch of

circle so let's use this one over here

on this path so let's use it there you

go we have a nice circle now let's

duplicate this image and for the second

one let's name it icon

then for this one let's assign just a

random Sprite so let's say the bread

and again remember how the Sorting order

on the UI this one is based on the

ordering the hierarchy

so make sure that the icon is underneath

the background the hierarchy that way it

shows up on top okay so we have our icon

template that's great of course we're

going to dynamically generate all of

this through code we're going to have

multiple icons and for positioning them

Unity actually has some really useful

components let's select the plate icons

UI and over here now let's add a

component now for example a built-in

component is the grid layout group this

basically helps you position all the

charm objects so let's put the size of

the canvas over here on 0.9.9 okay so

there you go a nice Square window then

over here on the settings for this for

the cell size let's put it at 0.3.3 and

if there you go already shows up over

there on the corner

and we can see what it will look like if

we just duplicate this object so let's

make a bunch more templates and if there

you go that's what it looks like so as

you can see this component is super

useful for automatically positioning all

of the challenge objects now if we want

we can play around all of these we can

add a little bit of spacing on the XR on

the Y but let's actually leave both

those with zero let's leave everything

on defaults just over here on the

channel alignment let's put it on middle

Center okay so there you go that looks

pretty nice so you can see how this

built-in component is super useful

there's actually two more so this one

for the grid layout this is great when

you want to put things horizontally and

vertically

but if you just want horizontally then

there is the horizontal layout group and

if you just want vertically there's the

vertical layout group so all of these

components are really awesome really

useful okay so with this our objects are

placed and note how I named this an icon

template basically a template is just

what I call something that is kind of

like a prefab but not really a prefab

through code we're going to duplicate

this template and dynamically modify the

icon so we're going to use it very much

like a prefab

we could actually make this into a

proper prefab so I could just drag it

over here onto the project files and

make a regular prefab that could work

and the only reason why I prefer this

method of not using a prefab

he's just because this object this

template stays here on the object as

opposed to cluttering over here your

project files if you have tons of

single-use UI elements with tons of

objects you need to spawn you can end up

with tons and tons of prefabs and you

might not even know where each of those

is used whereas with this method the

template says exactly where it's used

and does not take an asset slot over

here on the project files so personally

this is just approach that I prefer for

spawning UI elements but like I said

prefabs work as well so if you prefer

using prefabs go ahead and make it okay

so let's make our script to run the

plate icons UI so let's go into our

scripts and on the scripts folder let's

create a brand new c-sharp script for

the plate icons UI over here let's

attach a script and open it okay so now

the first thing we need is a reference

to our plate

so let's begin by making a serialized

film private for the played kitchen

object for our play kitchen object

okay let's save it and drag the

reference so over here there's the point

icons let's just drag the plate

reference okay great now on the plate we

already made this event when an

ingredient is added so basically we just

need to listen to this in order to add

the new icon so over here on the UI

let's do as usual private void start and

on start let's go into the Plate Kitchen

object and listen to that event

and when that happens let's spawn an

icon although here let's actually use a

different method from the one we used on

the plaint visual over here on the plate

visual whenever we had the event we

really just modified the object that was

added so over here the equivalent would

be to spawn a new icon whenever that one

was added but instead of doing that

right now let's listen to this event and

when this happens let's update all the

icons in this display basically this

other method is useful when the contents

can be added as well as removed now in

this case they are never going to be

removed so in this case both methods

were fine but still I want to show you

the second method just so you can use it

when you need it so for that method we

just need to know exactly what is on the

plate so over here on the Plate Kitchen

object we just need to expose the

kitchen object as some list so let's do

example that so fun week we're going to

return a list of kitchen object SL

let's go and look get the kitchen object

the sewn list and we just return the

kitchen object that's always okay very

soon then over here on the planet icons

UI let's just make a function to update

the visuals so private Droid let's call

it update visual

and when we have the event let's call

our update visual okay

so now here let's basically just cycle

through all the ingredients so let's do

a 40 inch kitchen object so in the plate

and get the kitchen object the sewn list

okay so we're cycling through all the

ingredients on the plate and then we

want to duplicate our template so that

means we need a reference up here so

let's add a serialized film private type

transform complete the icon template

okay and let's save the code

and over here in the editor let's drag

the reference so let's drag the icon

template by the way I'll have the others

over here that's not a problem since

these are going to be destroyed those

we're going to see in a little bit the

only one that matters is the first one

okay so here we have the icon template

so to spawn it we do it just like we do

with any preform so we just call

instantiate pass in the icon template

and then transform parents so let's put

it as a child of this object this part

is important we need to make sure the

object is spawned as a child of this

object if over here you put something

like no then the template won't be

spawned as a mobile object so it won't

be somewhere in the world so in order to

make it positioned properly let's make

sure to use transform to become a child

of this object okay and then since we're

using the other script the green layout

group this is already going to be

automatically positioned so just like

this it should be spawning the icon and

with the icon spawned all that's left is

really just setting the image and now

again the quick and dirty approach would

be over here when we spawn let's say we

pick up the item transform

and over here we could go inside and do

a find in order to find the image in

order to get the component of Type image

and so on so that is one approach that

would be the quick and dairy approach

but again we want to do things properly

so let's do it the proper way instead so

instead of this

let's make a proper script that we're

going to run on the icon template so

let's create a new script so a new

c-sharp script come with the plate icon

single UI so this one represents just a

single icon let's go ahead and attach it

to the template so over here let's drag

it and now when using this template

method really the only one we need to

worry about is this one the other

duplicates we can just leave them they

don't really matter but don't just

avoiding confusion I'm actually going to

delete them it's okay we just have one

icon template okay and it has our script

okay let's open now over here let's

basically just make a function to set a

kitchen object or so so public void

let's go on set kitchen object so

we receive parameter of type kitchen

object that so okay great so then we

need to set the image so let's just go

into a serialized film private of Type

image which is inside the unity

engine.ui

so for this one for the image we have a

reference and then we set the

image.sprite go into the kitchen object

and grab the Sprites

okay so we need to do is drag this

reference so over here in our template

let's drag the icon image okay great so

now back here on the plate icon Ty so we

spawn it that's great then let's we get

component in order to get our script

so the plate icon signal UI okay and

then we just call set kitchen object so

and pass in this okay that's great this

is much better now again you might be

thinking that this method is a lot more

verbose than just setting the image

Sprite here we had to create another

completely new script we had to write

this logic and over here get it and use

it the quick and dirty approach would

indeed be quicker but remember that

while the equationary approach might be

faster at first it will mess you up over

time so just take a few extra seconds to

do things properly this approach is much

more scalable let's say for example on

this function you want to change not

just Sprite but also trigger some kind

of Spawn effect or animation with this

it's very simple we've got this function

right here we receive the kitchen object

of so and we can do whatever we want

with it so like this we have this grip

that is responsible for anything related

to the single template and if you've got

the general one which just spawns him

and just gives them the kitchen object

so so all of our logic is nicely

separate okay so just like this it

should already work however like this

you might already be thinking want to

spawn way too many icons and yep it will

basically every time we add an

ingredient we're updating the visual

where we're cycling through every single

one and spawning all of them so with

this we're constantly going to spawn

more and more items this is not what we

want over here on the update visual we

do want to update and spawn all of the

icons but before we do that we actually

need to clean it up we need to clean up

the icons from the previous event

so before we do that let's just cycle

through all the children on this

transform so that's pretty simple you

can just do a for each transformed child

in the transform

so this way Cycles through all the

children and then just call destroy on

this channel that game object so that

won't work that won't destroy all of the

previous children however of course we

also have one issue the icon template

itself is also a child

so if we do this we're going to destroy

the icon template which then over here

we're going to have an error because

we're going to instantiate no so we want

to destroy all the children except for

the template so over here that's pretty

simple we just check if the child equals

the icon template if so then let's just

skip it so we can just call continue and

there you go it skips

okay great so just one more final thing

if we leave the template like this

meaning the game object is enabled like

this the template will always be visible

plus whatever ingredients we have we

don't really want the template to be

visible this is just meant to be a

template that we can instantiate so

that's pretty simple to fix let's make a

private void awake and on a week let's

grab the icon template grab the game

object set active into false okay so now

the icon template won't be disabled so

it won't be visible and then over here

when we are instantiating the

instantiated ones will also be disabled

so let's make sure we go in there and

enable these all right that should do it

so all of our logic should be working

there's only one more tiny thing we need

to take care of this one is a world

canvas so like we saw with the progress

bar we need extra logic to make it look

towards the camera and thankfully we

already wrote an excellent generic

script to do just that so let's go into

the point icons UI and let's add a

component and let's add our very nice

look at camera something like this and

let's set the mode the same that we use

so let's put it camera.org okay so

everything is great everything should be

perfect so let's finally test let's

leave the scene save the prefab and hit

on play all right so let's go pick up a

plate and there you go there are no

icons visible okay that's great now I'm

going to place a bread on top of the

plate and there you go I've got a nice

bright icon okay great now let's make

some meat cook it and as soon as it's

done going to pick it up and there you

go I've got a bread and some meat now

let's put some cheese slice it put it

there and there you go now I can easily

see that plate has some bread some meat

and some cheese now let's just add the

rest of the ingredients to make a foam

Mega Burger so let's add some tomatoes

and add some nice cabbage slices any of

there you go it works perfectly so here

we have a complete burger with

everything and we can easily see on the

icons everything this contains alright

awesome

okay so here you'll learn how to make

yet another Super useful element that

you can easily add to all of your games

personally I use this kind of logica ton

in all kinds of UI things for example in

my upcoming steam game total warm

Liberation the items in the inventory

they're all added using this method so

there's a template and I duplicate that

template same thing for all of the

action buttons all of those are based on

having a template and duplicating it

it's a really easy way to do this kind

of thing with all that here we have a

phone plate and we can easily see what

is on there so with this the next

obvious step is to actually deliver some

orders so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to build the

delivery counter this is where we're

going to drop some items that the

customers have requested in order to

complete the orders also just for fun

we're going to learn how to use Shader

graph to make a simple custom Shader

okay so let's begin by making our

counter so let's go into our base

counter let's create a new prefab

variant for the delivery counter let's

go inside and now let's find the visual

the visual for delivery counter let's

duplicate it to make the selecting let's

go inside modify the material then on

the selected make it one percent bigger

one zero one add the component the

selected counter visual let's drag the

kitchen counter like that okay that's

our basic setup and also start with the

kitchen count disable okay great now

let's make a script to run this so let's

go into our counters folder and let's

create a brand new c-sharp script for

the delivery counter let's attach it and

open okay so now here as usual let's

begin by extending our base counter

class all right now let's override the

interact function

and for now let's actually do it it's

not like the trash counter meaning let's

just destroy the object so we just check

if the player is holding something so if

the player has a catch an object let's

go into the player the kitchen object

then let's destroy it

however another room over here for an

Oliver counter is this is only going to

accept plates so let's see if the player

is carrying a plate object so player get

kitchen object and test try to get the

plate so out played kitchen object for

the Plate Kitchen object

we try to get this and if it is a point

then we destroy it

okay that's it here in the editor let's

just compound the script and drag the

references so the countertop point and

on the selected let's drag the counter

reference and let's exit this save the

prefab and let's drop it over here on

the corner so let's find over here the

delivery counter and let's put it over

there hang on it on this side put it

like this let's also just quickly

reposition all of our counters since we

already have all the types that we're

going to use so on the lever counter

let's put it over here on this corner so

x 7.5 0 and Z of two then next to it

let's put the plates counter so over

there okay

then next week let's put a clear counter

after that let's put the trash counter

and then let's also put another empty

one there so let's duplicate this one

move it up to about this and put it like

that now we just need to move all of

these down here so just select all of

these counters and let's move them down

by about this okay so on minus 5.5 like

this okay so everything is nicely

positioned just over there right now we

cannot access that container so let's

actually modify those as well which by

the way over here there's the canvas in

front so as I click I'm actually

selecting the canvas in the hierarchy so

here's a quick empty tab on the

hierarchy on the left side you've got

these two buttons so one of them hides

the object and the other one simply

makes it unselectable so if I click on

this and I click through any of the

click goes through the canvas so that

makes it much easier to select over here

on the items in our scene so let you

select all of these okay all of these

now just push them all to the side and

make another empty one and put it over

here okay that's a nice layout now let's

just finish the rest so over here let's

just duplicate our empty counters and

place a bunch more let's put one more to

the side

and now these ones over here so let's

put it over there and rotate it here

and duplicate another one and another

one

and another one and just one more and

get rid of this one okay great so here

we have pretty much our complete map

let's also just move the camera tiny

tiny bit just make sure that it is

nicely organized so put it over there

just so everything is nice and centered

okay so there's our map now let's get

back to working on our delivery counter

we already added this code so let's just

quickly test so here we are and if I

pick up something like for example some

cheese go into the delivery counter and

interact and nope nothing happens

because that one only accepts plates now

if I pick up a plate go there don't wait

for any of there you go it does work

okay great so this is the basic logic

that we want

for defining the actual recipe and logic

we're actually only going to do that in

the next lecture but for now let's add

one more nice thing let's add a simple

custom visual over here using Shader

graph this is a great way for you to

learn the pottery of Shader graph and

just how easy it is to use this is a

visual tool for making shaders it's

really very easy personally I don't know

how to write shaders with code but I can

build some pretty nice things using

Shadow graph as usual I have a dedicated

video on it I also have an entire

playlist showcasing how to make all

kinds of interesting effects and even

one special video covering some changes

in recent shareware versions so over

here let's learn the basics how to use

it so first here in our project window

let's create a brand new folder let's

name it just shaders and now inside

let's create one so let's create then go

up here into sheet graph then we're

using urp so let's go inside there and

here we've got a bunch of options now

don't worry about picking the quote

unquote wrong option all this does is

just create a template so for example if

you accidentally create an unlit Shader

you can then easily swap it out from it

so right right now let's go with the

English hitter and for the name let's

name it moving visual

okay there's our shade Rafael now now

let's just double click to open it and

up here we have the nice shade graph

window by the way you can make this

phone screen so you can either right

click over there on the tab and maximize

or alternatively you can just click on

this window and then use the hotkey

shift space and if there you go it does

maximize okay great now by default we

have this down the center this is called

the master stack these are the actual

properties that we're going to need to

use then on the left side we have the

properties Blackboard on the right side

we've got the graph inspector and

finally down here we've got the main

preview all of these windows can be

scaled and also if you don't see these

windows or if you accidentally hide them

they're all appear on these three

buttons so the Blackboard that's on the

left the graph inspector and the main

preview okay so now here we've got a

nice empty board so we can add whatever

nodes we want so we can right click and

go into create node and then we can

write something or just click anywhere

and press on space and there you go now

we can cycle through and browse all of

these menus to see all of the nodes that

exist there's tons and tons of them or

alternatively just go up here and use

the search bar so for example let's find

the sample texture 2D node so here it is

this one okay we've got this node what

this one does is it takes a texture and

grabs the color from it so on the left

side of the node are the inputs and on

the right side are the outputs within

the parentheses you can actually see the

types so for the input texture this one

is of type T2 so that means it's a

textured 2D then on the output you can

see there's a 4 meaning it contains four

floats which in this case refers to the

four colors so that's red green blue and

Alpha so for an input we want a texture

so let's set it over here as a property

let's click on the plus icon and we've

got a whole bunch of types for texture

we want a textured 2D so let's go with

that and then for the name now usually

there are two standard names there's one

called main text or base map main tags

used to be the more common name but when

working with urp for some reason they

decided to name the main texture as base

map so we're here let's stick within the

urp standard and just call this basement

okay there's our property and if we

click the select it and on the right

side we can see the graph inspector and

we can see all the properties for this

Actron property so we see a name

reference and a bunch more things now

the really important one is over here

the reference this is the actual name

that you're going to use if you want to

interact with this Shader through code

the name on the property this one is

just a text ring so this can be whatever

you want you can even have spaces and so

on whereas the reference name this is

the really important one and by default

when you set up a name it should already

accept the correct reference usually the

standard is to name it just like the

name both without any spaces and with an

underscore in the beginning so just like

this okay then we can give it a default

texture so let's go ahead and select

something for example over here the

bread texture remember this is just the

default this will not be hard-coded

directly into the Shader we can then

modify this okay so we we have our nice

base map property definition now we can

just drag it over here on the board and

yep there it is and now we can just

click on the server icon in order to

drag a connection and let's connect it

over here onto the sample textures to

the input and yep right away we do see

it does work so we are correctly

sampling the texture however if you look

on the main preview over here there's

still nothing that's because we don't

have this node connect to anything we

need to connect it to the final Master

sack in order to render something so

again on the output over here we can see

a four so these are all of our colors

and actually one very useful node is the

preview since so many things in Shader

graph can be hard to visualize so we can

move these nodes around and let's add

the preview node

and this does examine that so you can

fit it an input and you can see down

here what that input contains so for

example let's drag just the red Channel

and if they go over there we can see the

red channel for this texture we can drag

the green channel the blue Channel or

look at the alpha Channel yep there you

go it does work so this preview node is

super useful for being able to see what

your Shader is actually doing over here

we have the colors so let's get rid of

the preview right now in order to make

it work we really just need to connect

the rgba and go up here into the base

color and right away it should work but

you might not be able to see anything

over here on the main preview

I believe this is a rendering bug in the

current Tech version so right now

nothing is shown

so if you still don't see anything it's

actually pretty simple just go up here

on the top left side and make sure to

save the ascent okay save it great then

let's exit from our maximize View and

now let's close this tab let's click on

play just to play the game now let's

stop playing and now if we open the

Shader again if there go now we do see

the Shader compiling over there that

color that is the Shader compilation and

after a little bit it should work let's

just maximize this

see if there you go there we do see our

texture okay great

so again it's just a simple rendering

plug on the current Tech version if

you're watching this video in the future

chances are you don't even have this box

so there's no need to worry okay so

right now we do see it working we can

see our bread texture and it's currently

being applied on a sphere for a use case

we're working with 2D textures so this

would be best to be seen on the Quan so

we can right click over here on the

preview in order to select the preview

mesh so let's go with a simple quad and

if there it is we have our Knight Squad

okay great

so over here we have our basic Shader

all it does is just shows the texture

that's it now it's actually use this and

first let's always make sure to save the

asset on the top left side on the moving

visual if you see an asterisk here that

means you have unsafe changes so always

make sure to save them in my case I

don't but still never hurts to save now

over here in scene view let's go inside

art only three counters and let's open

it and now for the display for our Arrow

let's make it a flat one so let's right

click in the hierarchy and let's create

a new 3D object and let's make it a quad

let's call this the delivery Arrow

let's place this on top of the counter

so let's rotate it to face upwards by

the way on the rotation make sure the

collar is facing upwards most shaders by

default they only render one face and

not the other one so make sure you put

the face with the collar upwards and not

the other one okay so let's rotate this

one upwards so there we go 90 over there

and let's just put it just exactly on

top of the counter so just enough so

that it's visible okay great so now

let's make a material for our Arrow so

let's go inside the materials folder and

over here let's create a brand new

material

let's call this the delivery Arrow let's

make sure to use this material on the

quad so let's just drag it over there on

the mesh render okay so it's using our

custom material and over here on this

Shader graph drop down menu over here we

can select what Shader we want to use so

in our case let's go inside the founder

Shader graphs and inside yep here we

have our moving visual Shader so let's

go ahead and use this and here right

away we do see that it does work here we

have our texture being drawn exactly on

top of our material okay so far so good

now again here remember one very very

important thing that I said the texture

that you define the Shader over here the

default for the property this one is

only the default the important one is

the one that we have on the material I'm

emphasizing this point because I've seen

a bunch of people make this mistake if

you modify default texture whilst inside

the Shader like for example if I change

here from bread let's say into the

Cabbage slices

if I modify that note how it does not

modify any materials that were created

we are only changing defaults so if you

want to change the texture that is

actually used make sure you change the

one on the material that you created and

not the defaults I changed the default

but did not change this Shader however

if I now were to make another material

which by the way here's a quick tip you

can recollect directly on the Shader

file and going to create and create new

material and it will automatically

create the material using that Shader

naturally here then update default just

because I didn't save the Shader so I

modified this one for the camera slices

and now if I save the asset and now if I

right click there and I create a brand

new material and yep now that one does

have the new default but again remember

what you said over here is just the

default what really matters is what is

on the material after the material has

been created modifying default here does

nothing so always keep that in mind in

most cases you want to be changing the

property on the material itself not the

default on the Shader okay let's just

clean up both of these all right so

let's continue now here we have our

Sprite working okay except we don't want

to show some bread so let's actually use

the proper Arrow Sprite so let's select

this one

and yep it does work it is printing the

Sprite however one obvious thing is that

the arrow is not transparent like it

should be so let's solve that back in

our Shader graph in order to make this a

transparent Shader we need to actually

go into the graph settings so on the

graph inspector go into graph settings

and over here you see a bunch of

settings that relate to the graph itself

and not any selected property so let's

go into graph settings for example like

I mentioned a while ago you can modify

between lit and lit and so on so this is

where you would change that you can also

appear at multiple targets so you can

create a Shader in Shader graph and make

it work with the Universe on random

pipeline or the high definition render

pipeline or the built-in render pipeline

all of those are supported through

Shader graph now for a goal in order to

make this a transparent Shader let's

just go over here onto service type

instead of opaque and let's change to

transparent and as soon as we do look

what happens there and if there go it

adds a brand new Alpha Channel if we

just save the asset right now and open

look at that it still doesn't work it's

still not transparent basically we made

this Shader transparent but now we need

to fit in the transparent Channel over

here onto the alpha this is the one

thing that is different from a previous

version of shadowgraph previously you

could just feed the alpha Channel over

here onto the base color and Shader

graph would automatically apply it but

in recent versions you need to add it

over here separately so if you have any

issues with transparency when following

some older share graph tutorials always

remember this change I covered that

along with some other changes in a very

useful video so if you're following

along some other shade graph tutorials

make sure you watch that video to learn

what you need to do to update them to

the latest version okay so here on the

similar texture we already have the

alpha channel so we just connect this

onto the master Alpha and right there we

already see it working let's just go

ahead save our asset and here in scene

view if there go now we do see our Arrow

now one more small thing you might

notice that from some angles it's not

exactly transparent basically it

actually is transparent but since we

made this in literature sometimes the

light might make the transparent Parts

visible one option to solve that is over

here on the graph settings instead of

making it lit let's make it unlit that

would work say up with the unload Shader

the transparency is perfect but if you

really want to keep it lit then the

other thing you can do is just over here

play around with these settings you've

got smoothness AO and so on and over

here you can even modify the workflow

mode so for transparency instead of

making it metallic let's go with a

specular workflow and then over here set

the smoothness to 1 and the ambient

occlusion down to zero and now if we

save this Shader look at that and yep

now the transparent parts are indeed

fully transparent finally over here on

the right side on the mesh render if you

want you might want to play around over

here with the cast Shadows so maybe you

don't want this one to cast Shadows

maybe you don't want it to impact light

probes and so on okay so with this we

have our nice transparent Arrow

let's make sure to save our delivery

counter so let's go outside back into

scenes

and let's head on playing and if there

you go we have our transparent counter

with our nice Arrow now we want the

arrow to actually move and doing that is

actually super simple going back here in

our shadow graph let's just modify

default just so we can see the arrow

that we want to see so let's select the

arrow Sprite okay there's our Arrow now

for moving over here on the simple

texture we've got an input for the UV

the UV is what defines what portion of

the texture we're going to grab which by

default just gets the whole texture so

since this field represents where we're

going to grab from texture by playing

around with this we can grab different

parts so to do that let's just add a

standard UV node so here it is this is

the standard UV channel so if we connect

this then nothing changes everything

still renders exactly the same but now

we can modify this and to do that we're

really just going to use some basic math

remember that when working with shaders

even though you do see colors everything

is really just numbers so uv2 is just

number the converges the number the

alpha is just a number so visually

everything might look like images might

look like colors but really in the end

it's all just numbers so for example how

do we move this texture well it's

actually pretty simple we just add a

number onto it so we're here on the UVM

let's just add an add node so this just

adds two numbers together very basic so

let's take the regular UV and let's add

something on top of it for example we

can make a vector two

and let's put it on say 0.10

and let's add this one onto this one and

now if we drag this one onto the input

and look over there on the preview what

happens and if they're going like that

it moves slightly to the left so if I

modify this one put it on zero there you

go and that point one on that point two

on that and so on so you can see that by

modifying here I'm essentially

offsetting the texture I'm offsetting on

the X and over here I can also offset it

on the y basically I'm offsetting the

texture by ten percent the UV is a

normalized value this is not pixels so

that is why point one is ten percent

regardless of how big the texture is and

if we go way past one then texture

essentially Loops back so this is really

all we need

for our moving Arrow we're going to have

zero on the Y and on the X we're going

to constantly either increase or

decrease that's how we're going to have

our moving Arrow so again the only issue

here is that I'm modifying this manually

we don't want a fixed amount on the

Shader instead we want a nice animation

so for that we have the very useful the

time node

this one has various time-based outputs

the one that we want for this case is a

time which is just the total time this

one is constantly increasing since the

start of the game by the number of

seconds so if you use this over here

directly on the end and they're gonna

look that texture is constantly

scrolling okay so that's great except

obviously we have one issue we don't

want it to scroll diagonally we only

want to scroll in One Direction so for

that we can essentially create a simple

property to act as our spin so let's

over here on the Blackboard let's create

a new Vector two column Tower speed

property and for the phone let's see if

I want to say 0.1 on the x0 on the Y and

now if I drag the speed over here onto

our Blackboard okay great this is

basically a multiplier so we just need

to multiply the time by this so let's

add a multiply node also by the way

quick tip over here on each node you've

got a nice little arrow so if you want

to make it a bit more compact so if you

don't actually need to see the preview

so make that and in this case let's take

our time multiply it by our speed and

then for the output pass it into the end

okay so like that now it is indeed

moving in this direction and over here

on the speed we can play around the

values so if we put that 0.5 now it's

moving faster and if I put it on the Y

now it's moving diagonally put zero on

the X and now it's only moving

vertically okay so this is really what

we want let's just go ahead save our

Shader and now let's just select our

delivery Arrow material and over here

yep we've got the spin if you don't see

it make sure they're on the speed

property over here you have it exposed

so we have the speed instead of moving

on the Y let's move on the X and

actually like this it's reverse going

backwards so over here we can just put a

negative value so let's put it on minus

one and if there go now the arrow is

moving perfectly also here let me make

one important note just in case you're

using this Shader with a custom texture

instead of the one included in the

course if you do that make sure that the

texture that you use over here I'm using

the arrow texture

over here on the Arrow import settings

down here under wrap mode make sure it

is set to repeat if you set it as clamp

you might get some weird visuals or

nothing at all in order for the texture

to constantly Loop and constantly repeat

itself that one needs to be set to

repeat okay so here it is in game and we

have a really nice moving texture for

that we created the simple but really

nice useful custom Shader definitely go

ahead and watch the various effects that

I made in the shadow graph playlist this

tool is super useful definitely make

sure you know how to use it I've used it

for making a building effect I've made

some nice outlines a really nice wind

Shader also a really interesting the

sound of effect and even a cool

transition Shader just like in the game

Hades so this really is a super powerful

tool make sure you watch that playlist

to really learn how to use it alright so

here we'll learn about share graph and

created a really nice custom Shader

however the delivery counter still only

has a visual so let's create some proper

Logic for generating and delivering the

correct recipes in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to build a

proper delivery manager that will

generate recipes that customers are

ordering and validate to see if the

player made the right dishes alright so

right now we have the player capable of

making dishes so for example I can put

some cheese cook some meat cut the

cheese and then pick up both of them

then let's say pick up some bread there

you go got a nice cheeseburger and

deliver it okay so that works but right

now they just vanish on delivery counter

so there's no recipe we need to follow

no validation none of that so let's add

both those things okay first of all

let's make our script so let's create a

brand new sharp script for the delivery

manager let's make a new game object to

run it so we need delivery manager

attached to script let's make sure to

keep things lean so reset the transform

and also by the way since we're here

let's go ahead and put the plates and

delivery counter inside the counter so

everything is nice and organized okay

great so let's open up this script now

here basically we need to Define some

sort of list to store all the recipes

that the customers are waiting for which

of course begs the question what type is

that going to be now technically one

thing we could do since a recipe is

around just a list of kitchen objects

over here we could have a list of list

of kitchen objects this would be our

recipe list technically that would work

but that really looks quite dirty

instead of having a list of lists we

should probably have a proper type for

this so let's write some good clean code

and Define a proper recipe Script Mod

object back in unity let's go inside

script knowledge's folder and create a

brand new one let's call this the recipe

so and over here let's make this a

script Mall object so extend script on

object make the create asset menu

and over here for the films for that

that we need well like I said a recipe

is just a list of ingredients so just

taking a list of kitchen object that

sell for the kitchen object SM list

okay that's it that's really all the

data that we need to define a recipe

just to be able to identify them for the

player let's also add a public string

for the recipe name

so just a nice name String okay great

now back in the editor let's define so

let's go inside the certain objects and

make a brand new one for our recipe so

and now inside let's create a brand new

recipe SL for this one let's call it

just burger and over here first of all

for the name just name it burger and

then for the kitchen object list well to

make a burger let's well first let's add

some meat and we want some cooked meat

we don't want to serve uncooked or burnt

meat so only the cooked meat then for a

simple Burger obviously we need some

bread and that's about it so some bread

some meat that's our very basic Burger

now let's also make another one so let's

duplicate this one and name this one the

cheeseburger over here let's name it

cheeseburger

and lightning place has bread meat and

obviously some nice cheese slices

so there you go okay we have a

cheeseburger now let's also make a mega

Burger so something with everything

so let's call this one the mega burger

and over here for the string name for

the Mega burger and for that we have

meat bread cheese let's also have some

nice cabbage slices and also some tomato

slices alright that's our Mega burger

with everything and finally let's also

make just a nice simple salad so let's

duplicate this for a salad

let's name it salad

and for the salad we don't have any meat

we don't have any bread and also no

cheese so just cabbage slice and tomato

slice that's a simple salad okay so here

we have all of our recipes so back here

on the delivery manager script instead

of making a list of lists of game

objects let's just make a list of recipe

recipe so and name it the recipe so list

this is where we're going to probably

see recipes that the customers are

waiting for so it's actually rename this

let's put it waiting recipe on list okay

so the customers are waiting for

whatever is inside this list and now we

could make this a serialized field then

set it in the editor but we don't want

to have a fixed list we want to

periodically spawn new recipes in order

to spawn new recipes we also need to

know which ones we can spawn so for that

we could add a list of all of the

recipes then we could pick a random one

from the list and add it over here to

the waiting list that would work that's

one good approach but since we already

did something similar to that various

times in this course here don't let me

teach you a different approach that

sometimes might make more sense for that

second approach we just need one thing

we need a script more object to hold all

of our recipes so let's do that let's do

a brand new c-sharp script this is the

recipe list scriptable object and then

inside this one is going to be a

scriptable object let's add the create

asset menu

and inside we're just going to have a

list of recipe so

for the recipe SLS so that's it super

simple now let's just create one object

of this type we can put it inside the

recipe as soon as since we're only going

to have one so let's make a recipe on

Lister so namely the recipient list SL

and then over here let's just drag our

recipe so we've got a burger a

cheeseburger we have a mega burger and

finally a salad okay so basically we

have a script ball object with all of

our recipes and now just for safety

since we only want to ever have a single

one of these objects a recipe on SSO for

this one we can go back here in the

script and simply comment out the create

asset menu so now back in the game over

here we can no longer create another

type of recipient list so so just say

nice safety thing since we probably only

need just one and let's also add an

underscore just so it shows up at the

top-down list okay great so we have this

and over here on the recipe manager we

can basically expose that in a

serialization so let's make a serialized

field

make it private of type recipe so list

recipe enlisted so for the recipient

list so and now here in the editor we

just drag that reference alright that's

it so basically the difference that we

did with this method is over here on

delivery manager instead of having a

list of all of our recipes we just have

a reference to one object and then that

object holds a list of all the recipes

in this specific use case like I said

this approach doesn't really have many

benefits compared to just starting the

last year but let's say we had another

script that also needs a list of all of

our recipes if we did that we would

basically have duplicate references so

this script would have a list of all the

recipes then some other script would

also have a list of all the recipes and

then if you wanted to add a brand new

recipe you'd need to add it to all the

lists on all the scripts whereas like

this any script that needs to know about

all of the recipes just needs a

reference to the recipe on SSO and

whenever we want to add or remove a

recipe we just need to update this one

object and everything works perfectly

that's one of the benefits of this

approach where you have a script mode

object to hold a list of all the objects

of some type personally I find this

pattern to be quite useful okay so on

delivery manager we have a list of all

of our recipes now let's just make a

simple timer to spawn them like I

mentioned previously in the spawn point

logic you could just use Echo routine if

you like that

core routines can be useful for running

timers but personally like I mentioned I

do not like Co routines I don't like the

pattern they force it to use so over

here I'm just going to make a simple

flow timer

so a private fluid for the spawn recipe

timer another one for the recipe timer

Max and let's say 4 seconds

then we just do a simple and private

weight update

on update let's count down the timer so

time dot down for time

and if the spawn timer is under 0f let's

reset the timer

and now let's basically spawn a recipe

so for that let's grab a random one from

the list so we go into the recipe list

so and grab the recipe as a list then

we're going to grab a random one so

let's get a random index so random.range

between 0 and the recipient list so dot

recipes dot count so you get a random

one this is going to be a recipe so for

the waiting recipe so

and then we simply go into the waiting

rest PSL list and we add a brand new

recipe okay that's it super simple let's

just make sure to initialize the list so

let's do here a simple awake for the

waiting recipes and just initialize it

okay so like this it should be working

however we're also going to generate

recipes non-stop we don't want that so

let's define some kind of maximum

so let's Define a simple end for the

waiting recipes Max

let's say we kind of have a maximum of

four recipes waiting

and then down here when camera lapses so

if the waiting recipes only stock count

if it is under the maximum then we

generate and add it okay that's it

pretty simple

now for testing let's just set allow

here to print the name so debug.log on

the waiting recipe so that we generate

so let's print out the recipe name okay

so let's test so here we are in yep one

will spawn right away so we have a solid

and after four seconds Yep they're going

out of salad and if we wait for four

seconds we should have another one there

you go a mega butter recipe and finally

after four seconds we have yep we have

another burger and now no matter how

much time passes there should be no more

since we're at the limit any uptime pass

then no more okay all right awesome so

we are correctly generating recipes that

the customers are waiting for now it's a

logic to try to fulfill these orders so

over here on delivery manager let's make

a function to deliver a recipe

so let's make a public Point make it

public since we're going to access this

from the delivery counter currently

deliver recipe

and the recipes are going to be

delivered whilst on a point so let's

receive a parameter of type Plate

Kitchen object

and over here the logic is actually

going to be pretty simple we just need

to cycle through all of the recipes that

the customers are waiting for and see if

the ingredients on this plate matches

the ones on any waiting recipe

so over here let's cycle through all of

our recipes so let's do before

entire zero going through the entire

recipe only star count I plus plus okay

let's grab the recipe so for the waiting

recipe so

and we grab from The Waiting recipes on

list on this index okay so we have that

then first let's do a quick test just to

check if the waiting recipe has the same

number of ingredients as they are on the

plate if not then we already know that

it's not valid so over here let's do a

quick test SO waiting recipe so let's

check the kitchen object that's only

it's not count if this one matches the

play kitchen object let's get the

kitchen object that's on the list and

also check the count so over here we

know that has the same number of

ingredients

so this is the first check then we need

to cycle through all the ingredients on

this recipe and all of the ingredients

on the plate and basically see if both

of them match so let's first cycle

through the ingredients on the recipe so

for each

kitchen object as so let's call it the

recipe kitchen object so in the waiting

recipe so let's go into the waiting

recipe and get the kitchen object list

okay so here we are cycling through all

ingredients in the recipe

then we need to cycle through all the

ingredients on the plate so let's do

another cycle for the Plate Kitchen

object SL and we're going to go inside

the Plate Kitchen object get the kitchen

object that's on the list like this

so here we are cycling through all the

ingredients on the plate

okay so now here basically we need to

see if this ingredient that we're

cycling through if this one matches the

ingredient on the recipe so here we

check if the Plate Kitchen object does

so if this one matches the recipe

kitchen outlet

if so then the ingredient does match

so in order to keep track if it does

match

over here before we cycle through all

the ones on the plane let's define a

bone for found or ingredient found

let's default it too false and over here

if we have match then this one becomes

true and by the way over here we can

also break out of the cycle

now if you're not familiar with break

basically this is going to break out at

the for each so let's say the plate has

10 ingredients and the second one

matches when this cycle gets to the

second one it triggers a break so it no

longer goes through the remaining eight

so basically it breaks out of the cycle

so keeps writing some code right down

here okay so we cycle through all of the

ones on the aggressively then recycle

through the plate and if we do find that

ingredient on that plate then we have an

ingredient found so over here

if we have a not ingredient found

then over here that means this recipe

ingredient was not found on the plate

so if that happens then essentially over

here we have a phenocate so the

ingredient that this recipe requires is

not on the plate so let's go up here

when we have the same number of

ingredients let's define a Boolean

called the plate contents matches recipe

let's see found it to true and over here

if we don't find at least one of them

then the plate contents do not match the

recipe and afterwards we can check this

bowl again

so if this one is true that means they

all match if just one of them does not

matches then this one won't be false

so over here we know player delivered

the correct recipe

so over here on let's do a quick debug

down log and print out a message

and after we do let's also do a return

so we stop the rest of the execution so

basically if we find a waiting recipe

that matches we don't want to keep going

and also here if we do find it let's

also remove it from the list

so let's go into waiting queue remove at

and remove at this index okay so we're

going to remove this recipe but if this

doesn't happen then it's going to be

keep cycling and it's going to cycle

through all the recipes so basically if

it reaches the end this far

then basically no match is found

so the player did not

deliver a correct recipe

so let's do another debug in here

okay so this is done for logic it looks

a bit complex but I hope this was easy

to follow when we see it in action It

all becomes a bit more clear so all

that's left is just calling this

function from the delivery counter so

let's do that over here on the delivery

counter it accepts plates and destroys

plates but before we destroy

let's go into the delivery manager which

means we need to access a reference so

again we could add a serialized field or

in this case it makes perfect sense to

make this a Singleton so let's make it

here public static of type delivering

manager call it instance with a public

get and a private set

okay then over here on awake let's set

instance equals this

all right so now over here on the

delivery counter we can go into the

delivery manager access the instance and

deliver our recipe and pass in the Plate

Kitchen object

okay that should do it let's test all

right so let's look in the log to see

what they are waiting for so there are

two cheeseburgers waiting another Mega

burger and a cheeseburger so let's make

a cheeseburger to deliver so first of

all let's cook some meat let's slice

some cheese let's pick up the meat

before it burns pick up the cheese and

we just need the bread okay this is a

valley cheeseburger so let's deliver it

and if there go the players delivered

the correct recipe okay great

now let's deliver something that nobody

asked for let's say just some meat

actually let's burn it just for fun all

right so there we have a bunch of

charred meat so nobody really wants this

but if we deliver if their yield player

did not deliver a correct recipe alright

awesome so over here everything worked

we have a bunch of recipes being

generated and then we have the logic so

that when the player delivers something

it checks if the players delivered

something correct or incorrect so

everything is great all that's missing

is obviously some nice UI so let's do

that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to create a

nice UI visual to display our waiting

recipes okay so our delivery manager is

already working we are randomly spawning

some random recipes every once in a

while now instead of looking at the

console let's add a proper UI so for

that over here in the editor let's go

inside the canvas and by the way let's

click on the button to unlock the canvas

and this is actually the first time

we're using the Ragnar canvas quite a

while ago we just created it we didn't

really set it up so let's quickly do

that for the render mode this one is

meant to be a regular UI so let's leave

it on the screen space overlay then over

here on the canvas scaler instead of

constant pixel size let's go with scale

with screen size then for the reference

resolution I like to use 1920x1080

and finally unlike to fully match with

the height basically this means that

objects in the canvas will be scaled if

the height changes for example let's add

inside just a quick UI image just a test

let's look in the game View

so there you go there's the image let's

just put on a different color okay so

there's the image and note how if I

modify the aspect ratio here so let's

say I put it on 5x4 there go the

horizontal side of the window change but

note how the element was not scaled so I

can put it even on free aspects so

really wide and does not change the size

whereas if I modify this if I modify the

vertical size the image does indeed get

Scaled up or down personally I like the

setup because means that I only have to

worry about positioning things

horizontally if the vericon part gets

changed everything gets automatically

scaled okay so great so over here let's

go back into 4G all right and let's get

rid of the image all right back in the

scene view let's quickly look at the

canvas so we can select the canvas press

the F in order to zoom out and also we

can press the 2D button up here to go

into 3D mode okay so here's our nice UI

now inside the canvas let's create them

to game object call it the delivery

manager UI then in the inspector let's

make it stretch to occupy the whole

thing so let's put zero on everything

okay so this window now occupies the

entire screen

now inside let's do just like we did a

while ago for the plate icons meaning

let's make a template that we can then

clone but let's also put those templates

inside of a container so first of all

let's make the containers so a new empty

game object

of currently just the container the

reason why I'm going with this approach

is because I also want to have other

objects outside of here if you remember

how we did with the templates we can

actually go there and see so let's go

inside the prefabs inside the counters

actually it's on the kitchen objects

let's go inside the plate over here for

the template basically we use the play

tokens UI this main canvas as the

container but if you remember how we did

that in order to make sure we didn't end

up with duplicate icons we always

destroyed the previous one when we

spawned a brand new one so every time we

were cycling through the children of

this object in order to destroy all of

them except the template so over here

we're going to use a container so that

we can apply the logic only to the

children of the container and that way

we can have other objects outside of the

container for example outside of here

let's say we want some nice text just

saying recipes and waiting so on

delivery mansion let's make it a

challenge down let's go into UI and

let's make a text text mesh Pro and this

is the first time that we're using text

mesh Pro so this window pops out it's

actually import mesh Pro Essentials okay

just let it import okay that's it we

don't need the examples are extras so

let's just close this window and over

here on this window let's name this the

title text let's set the text to

something like recipes waiting

let's put it up there on the corner so

let's anchor it on the top left corner

also for the text I like to put it on a

width and height of zero but of course

that makes the text really vertical so

then down here on the wrapping let's

just disable it so there you go looks

like that and let's put it over there on

that corner now in scene view we are

seeing things different so if you want

to see what this looks like just go into

the game View and over there yep we do

see the recipes and let's just make it

in bond so there you go just some nice

text okay so that's our text and then

for the container let's make inside the

delivery template so let's create an

empty game object let's go with the

recipe template and for this one we're

going to want to Anchor it to the top

left corner so with the template

selected over here in the inspector

let's click and we want to click up here

however we also want to set the pivot so

let's make sure to hold down shift in

order to set the pivot over there okay

great that's exactly what we want so we

want the template right on the corner

then let's give it a size of say 250 by

100 okay now inside template we just

need two things we want to name the

recipe as well as the list of all the

ingredients although before that let's

actually make a nice visual for the

background so a new UI image for the

background

let's make this one stretch to occupy

the whole thing let's put everything on

zero okay that's the background let's

put it on a black we're just a little

bit lower Alpha okay that's good then

for name let's make a text field so

inside the template let's create another

text call it the recipe name text then

over here let's put it a bit small so on

the font size of maybe just 20 let's put

it in bold

and let's also again put the width and

height of 0 and over here make sure to

disable wrapping okay so that's the text

so we've got it up there let's just

anchor it to the top left corner okay

great

over here we can change the name to

recipe and then what we need is the

icons on here and for that we're going

to do pretty much the exact same thing

that we done on plate but before we do

that logic let's just get this basic

setup working so let's just position

everything so first of all the container

for all the templates let's anchor it on

the top left corner and let's push it

all the way over there and for

positioning them let's use this time the

vertical layout group so inside let's

duplicate the template just to be able

to see them okay so that's pretty much

we want we can actually set the width

and height both to zero and let's set

the spacing to something like 30. okay

so that's our basic UI now let's make

the script to run this

so over here in our scripts let's create

a brand new C sharp script for the

delivery manager UI let's go into the

parent game object and let's attach your

script let's open okay so now here first

we need a field for the container

another one for the template

so let's do a serialized film private

transform for the container

and another one for the transform and

this is going to be the recipe template

then let's do pretty much same thing we

did previously so first of all let's

actually go on a way in order to hide

the template so game objects set active

into false okay so first we hide the

template then let's make an update

visual function so private void update

visual

and for updating we're going to do the

exact same thing that we did so first

let's cycle through the container and

destroy everything except for the

template so do a 40 inch transform child

in the container

and if the child is the template

if so then we're going to continue and

if not we're going to destroy the child

game object okay so we have the cleanup

now we need is the second through all of

the waiting recipes so that means that

over here on delivery manager we need to

expose our waiting recipes on list so

let's go down here make a function to do

that probably going to return a list of

recipes so get waiting recipe so list

and we just return the waiting recipes

on list

okay great

so now here on the UI we can now go into

the delivery manager xsc static instance

in order to get the waiting recipes on

list so let's cycle through this so do a

40 inch for each recipe so recipe so in

the waiting rest vsl list

for each of them let's instantiate

and let's spawn our recipe template

spawn it inside the container and then

we just need to set this to enabled so

let's read the transform for the recipe

transform we grab this one grab the game

object and set active into true okay so

like this the only thing missing is the

text but that's okay for now

let you see where we're going to call

this function to update the visuals and

as usual we want to be smart and write

some good clean code so let's not do the

dirty approach of just updating this on

every single update instead let's only

call this function when something

actually changes so over here on the

delivery manager let's just make some

simple events

so if I'm like event event handler

let's go on recipes fund and another one

call it on recipe completed

and actually as soon as I add the event

handler which also add the using system

now here we have an interesting thing

we've got a nice namespace Collision

it's telling us that random is an

ambiguous reference between Unity engine

now random and system.r random that is

because both these namespaces Unity

engine and system both of them have a

class named exactly random so the code

here does not know which class we're

trying to use to solve this component we

really just need to be more specific in

this case here we want to use the UNT

engine version so let's just write the

full name Unity engine.renom and yep

that works okay so now let's fire off

the events so first of all the own

recipe spawns over here when we spawn a

recipe let's invoke this event so this

is ventar is not empty and let's also

get rid of the log we know we need that

okay now we could also add the wedding

recipe on the event artist but in this

case we don't need it just firing the

event is enough and then down here when

the players delivers something if the

player delivers the correct recipe we

remove it from the list and then let's

fire off the event so on recipe

completing let's invoke with this and

event rx.mt okay so we have the event

and down here we also don't need analog

okay so that works and finally over here

on the delivery man GUI let's just make

a private void start on start going to

the delivery manager access the static

instance and listen to both these events

so they spawned and let's also listen to

the other ones the library manager

instance on recipe completed

when either of these work let's just go

and update the visual so just like this

let's also rename this because again

instance doesn't sound like a very good

name let's actually rename this to only

remanager and same thing up here by the

way I'm using the visual studio shortcut

control RR in order to rename this to

delivering manager

and finally we also need to update the

visual OnStar just make sure the

previous ones do not show up okay that's

it so like this it should be working we

should be able to see no Visual and then

as more our spawned we should be able to

see each one being spawned until the

maximum so let's see just over here in

the UI let's make sure to drag the

references so the container and the

template and let's hit on play and okay

right away actually it spawned one

recipe it spawned instantly then after

four seconds there you go a second one

and after four seconds we should be able

to see yep another one now four more

seconds and we should see the final one

and now no matter how long we wait it

should no longer spawn anymore and yep

that works alright awesome so the basic

logic is working now let's handle the

proper Logic on the template for that

like I mentioned previously one approach

would be over here you could go and do a

transform.find

the actual recipe name text then get the

text mesh component and set it that

would work but like I mentioned

previously that would be very dirty not

good at all we should avoid using find

at any time and we should also avoid the

individual logic from the total logic so

let's do it properly and make a proper

script to handle each spawn template so

let's create a brand new c-sharp script

call this delivery manager single UI

single just because it refers to a

single recipe and also right now we

already have quite a few UI scripts so

let's organize our project again so

let's organize new folder for the UI and

inside let's put all of our UI scripts

so if we manage is single this one

deployed icons white icons and the

progress bar so let's put all of these

nicely organized in the UI folder okay

so with the script let's go into the

recipe template and attach the script

now let's open and over here let's begin

by adding a film for our text so a

serialized field

and over here it's also very important

for the text we are not using the text

inside DNT engine.ui this is the in

Legacy text it is not text mesh Pro so

this is not what we were using instead

we want to use text mesh Pro U going

which is inside TM Pro

so we need to go up here and add using

TM Pro and now we can use this type and

also make sure you're using text mesh

Pro ugui and not text mesh Pro this one

also exists but don't mix these two

these are two very different types if we

go over here in the editor and if

outside the canvas if I just create and

create new 3D object a new text object

if I do that then if we look over here

in the inspector we see this one as a

type text mesh Pro whereas for the ones

that we're using inside the canvas if we

unlock this is text mesh Pro it's a UI

text so these are the two different

classes within text mesh Pro you have

text mesh Pro and text mesh Pro ugly

we're working on the UI so we want this

one okay so we named this the recipe

name text

okay that's it over here in the editor

let's drag our reference all right so

now this group let's make a function to

set the recipe so a public void and

let's call it set recipe SL

they're going to receive a recipe so

recipe so

then we just go into the recipe name

text and we set the text to recipe so

dot recipe name

okay so that's pretty much it now over

here on the Y script when we instantiate

our recipe transform let's get component

of type of our

delivery manager single UI and call set

recipe so and pass in the recipe so okay

so let's see if the name shows up any

operator wait does show up so we can see

that we generate a cheeseburger recipe

and right now a mega burger recipe okay

great so all that's left are the icons

on here so like I said that is going to

be yet another usage of our template

pattern

so inside the recipe template let's

create an empty game object currently

the icon container and then inside that

let's make the template and template is

just going to be an image so we can just

create an image to our way

called the ingredient image let's scale

it with a size of 40 and 40. let's put a

image by default just like that and on

the icon container let's put the width

of zero height of zero and let's put a

horizontal layout group put it over

there on the left side and we can create

a bunch more just to see how it looks

okay so that's pretty much it now over

here on the single script let's add a

serialized field private transform for

the icon container another one for the

icon template

then we do the same thing as usual so

when we set the recipe so let's first of

all clean up the container so let's do a

40 inch transform child in the icon

container

and if the channel is the template

then we want to continue and ignore it

if not we want to destroy the child.game

object okay so that's the cleanup

and then let's do a four inch kitchen

object as so

in the recipe so dot kitchen object.zone

list

second through all of this let's

instantiate our icon template

instantiate it inside the icon container

so this is going to be the transform for

the icon transform

then as usual we need to go into the

game object set active in order to

enable it

and also let's go up here make a private

way to wake and on awake the icon

template game object let's disable it

okay we don't want the template to be

visible

okay so we instantiate the template we

set it as active then since this one

just has an image we can just do a get

component of Type image

that's image not image conversion

so image so it's this one the one inside

Unity engine.ui so let's get this image

and let's modify the Sprites and set it

to this kitchen object so that's right

okay so that's it that should do it

let's test over here in the editor let's

just go into the template let's drag the

container reference and the template

reference and let's also rename this

instead of ingredient image put icon

template just to be a bit more clear and

we can get rid of the other ones or

leave them doesn't really matter okay

great so let's hit on play and see and

yep right away does work so we can see a

burger is composed of a burger and a bun

a satellite yep there you go some sliced

cabbage and sliced tomatoes then

cheeseburger same thing as the burger

with some cheese and then another Burger

let's just deliver until we see the mega

Burger so let's deliver a cheeseburger

let's cut it

get this get some bread place it in

there pick it up before it burns that's

a cheeseburger so that one should vanish

and if they're good does vanish let's

see something else not cheeseburgers so

let's keep doing until we get a Mega

burger just see that everything works

so let's deliver a regular burger okay

now let's deliver a regular salad

okay just pick up like that like that

and drop it

okay let's see

any up there it is the Mega butter all

right great so the visual logic is fully

working and the delivery logic all of it

is working

so I can deliver the right recipes and

get rid of them from the recipe waiting

list and more are spawned every time

here we can see the name of the recipe

as well as all of the nice icons okay so

with all this our game is really taking

shape everything is very close to being

done

one massive thing we're still missing is

an obvious one which is sound so let's

do that in the next lecture

hey again quick intermission you're

almost at the end so once again congrats

for making it this far this is the

second secret call out go ahead Post in

the comments a timestamp and a nice monk

Emoji it won't be fun to see how many

people make it to this point by now you

already know about the website I hope

it's been very useful to you and you

already know to ask any questions in the

comments if you need help with anything

so that's life for me to say right now

is thanks for watching the course so far

and I really hope you've already learned

a ton there's only a bunch more lectures

until we get to the final polish game so

let's continue on the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add some

audio to our game starting with a really

nice music track okay so our game is

already looking pretty good but

everything is still way too silent so

let's begin by adding some music adding

this is actually extremely new in the

included assets over here inside the

sounds we've got a really nice music

track I hired a musician to make this it

sounds really good it's a seamless Loop

so to add to our game it's going to be

super simple we just want a constant

never-ending Loop so let's begin by

creating an empty game object call it

the Music Manager

let's reset transform keep things

organized and let's add a component and

we want the component an audio Source

here it is this one like name implies

this one acts like a source of audio

you will note how by default on the main

camera down here it already has an audio

listener so the source plays some sound

and The Listener listens to it now for

here we just need to set these fields so

for example on the autoclave let's make

sure to drag the music audio okay great

next over here and let's enable and play

on a wink we wanted to start playing

right wing and for this track we do want

to enable looping okay great then for

priority basically UNT has limited to

how many sounds can be played at once if

you play too many then some sounds won't

play and which ones do you play is all

based on priority we always want the

music to play so let's put this one on

Max priority

then for the volume later on we're going

to make a proper option screen to handle

this

but for now let's put it on something

like 0.4 or 0.5 just make a nice

background track then we have here the

spatial blend for this music track we

wanted to play the same regardless of

where the camera is so let's make this

all the way if only a 2d sound okay

that's it we don't need to play around

with any of the other settings and just

like this if we are on play any up

there's the music now if you're not

hearing anything make sure that on the

game view first of all that the game is

actually selected make sure the scene is

in Focus so over here I can move around

so the game's in Focus then on game view

we are on the top right corner make sure

this sound icon is toggled if not then

everything is muted and also again make

sure like I mentioned on the main camera

that it has the audio and listener

component with all that yep you should

be able to hear the music

now this song is playing and it won't

Loop forever just like we wanted

personally I really like how it sounds

I'm really happy with what the composer

made it perfectly matches the E5 of the

game so it really is this simple to add

some music to the game let me just point

out one thing also related to sound one

of the things you can make is an audio

mixer so for example on the project

files let's create a brand new and let's

find over here the audio mixer so there

you go here is an audio mixer then you

can double click to open up the audio

mixer window and then over here you have

the masternode

and then you can create multiple groups

so let's create a brand new groove for

something else

and then you can play around over here

with the effects with the volume all

kinds of things all kinds of effects

everything then for each sound where you

have the audio Source over here note how

you have an output and for this output

you can set it to play on the message so

it plays on everything or set it on just

one individual group so with this you

could assign a group to one individual

type of sound effect or the music or so

on maybe you could even have your music

split into multiple stems so there's a

lot you can do but for me I'm not an

audio engineer audio is probably the

part of game development that I know

least about I just stick with the

absolute Basics but if you want to learn

more definitely look into the audio

mixer this is an extremely powerful tool

but like I said for me I don't know how

to work with it so I'm just going to

stick with the basics so on the output

let's revert back into none close the

audio mixer and get rid of this and

there it is music is playing and the

wrong sounds really nice alright so here

we very easily added some music to our

game this lecture is actually super

short because it is generally that

simple now the next thing that we need

is not going to be a little bit more

complex and that is adding sound effects

so let's do that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add some

sound effects for our game okay so

previously we already added some really

nice music now let's add a whole bunch

of sound effects in the project files if

we go inside the assets over here we've

got all kinds of sound effects recently

I heard the really nice sound designer

to make all of these and I think they

all sound really great so let's add them

to our game now when it comes to sound

effects there are two main ways to play

a sound one is just like we did for the

music so we can create a game object at

the audio Source component and play it

that's one approach but that basically

requires pre-preparing the sound objects

so there is another simpler way that

just requires one line of code so let's

begin by making a Sound Manager game

object so a new empty game object for

The Sound Manager let's reset the

transform now let's make our script so

let's go in the scripts folder create a

brand new c-sharp script for The Sound

Manager let's attach the script and open

okay so now here let's make a function

to play Simple sound so let's do a

private void just call it play sound and

over here the way we play sound through

code is actually super simple we just go

inside the audio Source class

and in here there's a static function

play clip at point this as you can see

it takes an audio clip a vector 3 for

the position and finally a volume so

basically it won't play that sound on

that position by default TNT already has

3D sound so if you play the sound on the

left or the right side of the camera it

won't play in the correct place also for

the volume the further away it is from

the camera the lower it will be and if

we don't want the 3D sound we can just

play it directly on top of the camera

position okay so in this function let's

receive our arguments so for the audio

clip

it's going to be our audio clip

then let's receive the vector 340

position and let's also receive an

optional one for the volume

let's just default this to 1f okay so

here we just pass this in into our

function so the position and the volume

okay great so now let's call this nice

function and for example let's start

with a simple one so let's start with

the delivery sounds so over here on the

delivery manager script down here we

have the logic for delivering a recipe

and over here we know when we completed

a successful recipe or when we failed

and the player delivered a wrong recipe

so this is where we want to play some

sounds and again here we have yet

another very important clean code

question

we could definitely call the play sound

function directly from here that would

work but of course that would make this

class tightly coupled with The Sound

Manager for a simple game on this scale

that approach can work just play sounds

directly from the logic code however

again to make things properly we should

really separate the logic from the sound

just like we separated in logic from the

visuals so instead let's not call the

sound directly from here instead let's

make two more events

so let's make one on recipe success

another one on recipe failed

okay so now let's fire off these events

so over here we have the success so on

recipe success and if we get down here

then we have a fail so on recipe fail

okay great we have two events now back

here on The Sound Manager we can just

listen to those so let's do a start go

into the delivering manager access the

instance and listen to the on success

and on failed events let's listen to

that one delivery manager instance on

recipe film listen to both of these

again let's write some good clean codes

so let's rename this one instead of

instance let's put it delivery manager

and same thing on this one also name it

correctly delivery menu

okay great so now when you have this we

want to call and play sound

and now I want to pass in a reference to

the recipe film sound so technically one

approach would be appear to add a

serialized film for an audio clip that

would work but since we've already done

that so many times in this course here

let's use a different approach that I

also like to use

let's create a scriptable object to home

the reference to all of our sounds so

similar to how we Define the script

object on all of our recipes let's just

comment this out just make sure the code

compounds okay great so back here in the

editor let's make a new script more

object type so let's create a brand new

c-sharp script

for the audio clip refs script long

object now here let's make this a simple

scriptable object with a create asset

menu

okay so now for the fields if we

unlocking the S over here the audio

design that I hired actually made

several variations for each sound so

we've got multiple chops multiple

delivery fails and so on

so back in the code here instead of

storing a reference for a single audio

clip let's store an array for all of

them so we have the chop then we have on

the other Solutions and all of the

references

so there's a job there's the delivery

fail

then we have delivery success then we

have footsteps

then the object drop then the object

pickup

then we have the stove Sizzle although

this one is just one then we have the

trash and finally we have the warning

alright so these are all of the sound

references we're going to use back in

the editor let's just create the object

so on the script mode objects let's

create a brand new one let's make it of

audio clip per episode

just name it audio clip refs so

and over here let's just write the

references so let's use that quick ENT

tip in order to unlock the inspector now

I can select all the chops and drag them

all the delivery fails drag them it's

only re-success drag it then for all of

the footsteps after that are all of the

object drops then the pickups then we

have the sizzle which is just one

finally we have the trash and the

warning okay those are all the

references so our script on object now

has all of the data we need let's unlock

the inspector okay and back in the code

here on The Sound Manager let's make

another version of this function so

let's make one play sound except instead

of receiving an audio clip it receives

an array of audio clips

then basically we just call the other

function so we call the other place on

function and pass in an audio clip from

this array so let's actually rename this

so audio clip array

and let's pass in an audio clip from

here so do a simple random.range

between 0 and the array down length

pressing the position and the volume

okay so just like this now we need is a

reference to our suitable object so it's

generalized film private of the audio

clip refs SL

okay we have this then here in the

editor and let's just assign the

reference so the audio clip refs okay

great and over here when we have the

recipe failed let's go into the audio

clip refs

and let's pick up this one instant

delivery fail

and then the other one is going to be

delivery success

for the position let's just default to

the camera dot main transform that

position

so like this it sounds like exactly on

top of the camera okay so let's test and

see if it all works okay so here we are

and let's do a wrong delivery now quick

warning if you're following along or if

you're just watching the video this

sound will probably be way too loud but

let's test

so if I just pick up the plate and I

just deliver an empty plate yep there

you go there's the sound

and now if I deliver a correct one so

someone wants a salad so let's cut a

nice salad

chop that chop this pick up the plate

pick up that one and that one don't be

the correct salad

any of that I go with those were all

right great so the sound effects work

they played perfectly but they're a bit

too loud basically that's because these

sounds were designed to be played in the

world rather than on top of the camera

so when we play the sound let's actually

play it on the position of the delivery

counter

here is the delivery counter script and

based on our design we're only going to

have a single military counter so we can

just make this a Singleton

so as usual public static of type on

Livery counter call it instance where

they probably get and a private set

then on privatoid awake

let's just set the instance equals this

okay so over here on The Sound Manager

we can just grab delivery counter

delivery counter and we just go into

Library counter and grab the static

instance

and then for the sound position we can

just go into delivery counter access the

transform that position

okay so just like this on that one and

on this one

okay so it says now it shouldn't be as

loud

okay so here we are and let's do a wrong

delivery any hope it does work

now let's be successful delivery so

let's make a nice cheeseburger so grab

some cheese slice it grab plate just

need some bread

and delivered any of there you go it

worked all right awesome

okay so this is really it this is how

we're going to play our simple sounds

now there are some that are going to

require more logic like the footstep

sounds and the stove Sizzle but first

let's begin by adding the simple ones

so let's begin with the chop sounds this

is super simple we just need to go over

here onto the cutting counter and

actually we already have the uncut event

that we made previously this was used to

spawn the visual so we can also use it

to spawn these sounds

however there's actually one difference

we're going to have multiple cutting

counters and this one as you can see

this one is not a static event meaning

each different counter is going to have

each list of listeners and we really

don't want to have to subscribe to every

single one of the counters individually

so what we can do is instead of making

it a regular event that belongs to each

instance of a cut encounter we can make

a static event which won't belong to the

entire class but we still want to leave

this one just for the visual so let's do

another one a public static event event

handler

and let's call it on any cut basically

for any static events that belong to any

object type I like to add the keyword

any we're going to fire this event when

any cutting counter is going to trigger

a cut action so where we fire this event

is exactly the same thing so over here

we've got the uncut and let's do the

exact same thing so on any cut with this

an event R is not empty okay so we have

our nice static event and over here on

The Sound Manager let's listen to it so

let's go into the cutting counter again

we're going to access through the class

name and let's listen to the on any cut

event and over here let's just play the

sound so let's play the sound let's go

inside the audio play prefsl and let's

grab the chop sound then for the

position

we want to know who fired this event and

by following the c-sharp standard over

here we already have the object sender

so we know this was the object that

fired this event and we know this is

going to be of type cutting counter so

we can just get cutting counter cutting

counter and we just grab the sender as a

cutting counter

okay so we have this and then over here

very simple access transform that

position

okay that's it great

that won't play The Cutting sound on

that position on that cutting counter

okay great now let's handle the player

picking up something and for that let's

go over here onto the player class and

the way we set up the kitchen object

parent system is actually already

perfect for this

down here we have a function so if we

scroll down Yep this function set

kitchen object this one is called

whenever the player receives a kitchen

object which means really when the

player picks up something so if this

kitchen object is not known then that

means the player picked up something so

let's do that

so up here and let's make the event

so a public event event handler

call it on pick something

and then down here just to be test so if

the kitchen object is not known so if

the player did pick up something then

let's just fire off this event so just

view our usual invoke with this an event

RX rmt

okay so that's great

then on the sound management let's just

listen to it so let's go into the player

Quest let's access these static instance

and let's listen to the on picked up

something event and again let's rename

this to a proper name so player on pick

something

and over here let's just play the sound

and for the sound go into the refs and

grab in this case the object pickup

and for the position let's just go

player

dot instance and gravity transform that

position

okay that's it next for item dropping

now we can only drop items on a counter

so over here we have the base counter

class and again we have the same thing

so we have the set kitchen object and

again the same thing as with the cutting

counter we don't want to be required to

listen to every single counter we just

want to listen to one event so let's

make it up here so if I'm like static

event of type event handler

and let's name it on any object placed

here

and then down here when we have the set

kitchen object we do the usual if

kitchen object is not known if so then

let's fire off this event

okay great

and on the song Imagine let's listen so

go into the base counter on any object

placed here when that happens play the

sound then let's go into the other top

prefs and this one is the object drop so

that one and for the position let's do

the same thing we did so we cast the

base counter equals the sender as a base

counter and then we go into the base

counter and let's grab the transformed

up position okay so we just need one

more special counter type

here we have the trash counter and this

one it never really changes the parent

it just destroys the object it's over

here on the trash counter itself let's

fire off an event but again let's make

it static even though we're only going

to have one trash but make it Saturday

just to be able to support multiple so

public static event

Handler

on any object trashed

and then over here just fire off this

event

so invoke with this and eventar is not

empty okay

so now if we go into The Sound Manager

and over here once again the trash

counter on any not the on any object

place but on any object trashed

and on this one let's do pretty much

exactly the same thing so let's copy

this the sound is going to be the trash

sound instead of a bass counter

we could just cast it to a base counter

but let's make it proper so let's make a

trash counter as a trash counter and

this is a trash counter okay great

that's it so these are all of our basic

simple sounds as you can see all the

logic is super simple so let's test and

see if it all works

okay so first of all let's pick up an

object so if I go into a container and I

pick it up and if there you go there's

the sound now if I drop it somewhere and

if there's a sound now for the trash

pick it up drop it on the trash anyhow

there's the trash down okay great

then also let's check out the cutting so

if I pick up some cheese drop it there

and cut and if there go got a really

nice cutting sound okay so far so good

now let's handle the more complex ones

starting off with the stove for this one

the sound is meant to be on looping but

only when the sub is on so we don't want

to just play once but play and stop

playing depending on the state of the

stove

so for this one instead of spawning the

sound through code let's actually spawn

it on the object itself so let's go

inside the stove object let's go on the

stove counter and open up the prefab and

inside this prefab let's create a brand

new empty game object name it sound

let's reset transform make sure it's on

zero zero zero okay great now let's add

an audio Source component

and for the auto clip let's use the pan

sizzle let's make sure to not talk on

play on awake but we do want it to Loop

and let's also make it a 3D sound

okay so that's the basic setup Now to

control this let's make a script so

let's go into our scripts folder and

let's create a brand new c-sharp script

come with the stove counter sound

let's attach the script over here and

let's open it

so now here first let's grab the audio

Source component so we've got a private

audio source for the audio source and

just go on awake and audio Source

sequence get component of type audio

Source okay

then we're also going to need a

reference to the stove counter so let's

uh appear a centralized film private

of type stove counter for the stove

counter

then back in the editor let's drag that

reference all right

now on the stove counter over here we

already have the states and we have the

on-site change event again the same one

that we use to modify the visual so on

the sound lets you pretty much examine

the same thing

over here let's do a private void start

and on certain let's go into the stove

counter and listen to the on stay

changed event

and basically when this changes we want

to check if it's frying or fried if so

then we want to play the sound if no

then we don't want to play it so let's

define a ball call it play sound and

we're going to play if the state equals

we are frying or the state equals that

it is currently fried and about to burn

Okay then if we have a play sound

then let's go into the audio source and

comp play

and if not then let's go into audio

source and call pause

all right so that's it pretty simple

let's just make sure to save our prefab

go back outside and let's start on play

and okay four stars there's no sound

playing now if I pick up some meat and I

drop it on there

and if there go there's a sizzling sound

and continues going and now it is still

sizzling but if it burns it should stop

so if I go

and if there go the sizzling soundstomp

all right awesome so let's take this one

out let's actually trash it now let's

pick up another one let it cook

and once let's go pick it up and there

you go the sound of the Stomp all right

awesome

so we just have one more final sound

remaining that's the footsteps

by the way the warning sound is going to

be added during the Polish lecture

for the footsteps we want very much the

same thing that we did on the stove so

we're going to want a script to handle

that logic

but this time we don't need an audio

Source on the player we're going to use

the same play Method as the other ones

let's just make a script to run the

sounds so let's make a new c-sharp

script for the player sounds

let's go into the player game object and

attach the sound okay so here let's

first grab the player reference

so private player player and on private

way the way let's get the component of

type player and assign it to the player

okay

then for the footsteps basically we want

to play them every certain amount of

time so let's do appear a private Cloud

for the footstep timer another one for

the footstep tower Max and let's say you

want to play say 10 times per second

then we do a basic update and on update

footstep timer countdown by time.com

time and if the footstep timer is under

zero

then let's reset it so set it to the

maximum

and it's in here that we're going to

play the sound so now here we have two

options we can fire an event here and we

can listen to it on The Sound Manager so

exactly the same thing that we've been

doing previously or we can just trigger

the sound directly from here doing that

will mean that this class is tightly

coupled with The Sound Manager usually

we want to avoid tight couplings however

in this case the player sounds class

this one is really only meant to exist

alongside the sound manager so in this

case it's perfectly fine to totally

coupon them so let's play the sound

directly from here which means we need a

reference to The Sound Manager we can

make a serialized field or just make

this a Singleton so let's do that

so a public static type Sound Manager

name it instance where they probably get

any private set

then on private void awake

we just set the instance equals this

okay

so then over here we can just access it

so just go into the sound manager access

the instance and we call play sound

which we actually need to make public

however this function also takes a

reference to the audio clip array

so that means we need a reference to the

audio clips so again we have multiple

options we could add over here on the

player sounds at a serialized film for

the footstep sounds or we can just make

a specialized function over here on The

Sound Manager both options can work just

fine let's go with the second one just

to be different so just make here a

public void play

footstep sound

we're just going to receive a vector 3

for the position

and then we just call play sound let's

go into the audio clip refs ASL and

let's pick up the footsteps and play it

on this position

and let's also receive the volume

just appear a fault for the volume

okay so that's right now we just need to

call this function

it's over here on the player instead of

calling play sound let's go on the other

one play the footstep sound

then for the position that's the player

transformed that position and for the

volume I just exposed the volume just in

case you want to make the footsteps a

bit more sound or not

but for now let's begin with one F and

then see if that's waiting around as

usual instead of using magic numbers

let's define a fluid for the volume put

it at 1f and over here use the volume

okay great however you might be noticing

an obvious issue here right now this is

going to play non-stop obviously we

don't want to do that we only want to

play footstep sounds if the player is

actually moving so this pre-semble we

just need to ask the player if it is

moving

and we already did that so player is

walking so if the player is walking then

you play The Sounds if not we don't okay

that's it so let's test so here we are

and if I'm standing still there's no

footsteps okay that's great and as soon

as I move yep there you go we got some

nice WhatsApp sounds

all right great so with all that we

added all of our sounds

now here note how we mostly use this

method of going into the audio source

and using the play clip at Point

function this one is great because it is

so simple but it does have limitations

specifically with regards to all of the

options if we look on the audio Source

component here we have all these options

so you can use an output use an audio

mixer like we saw in the previous

lecture we can play around priority play

around the pitch make it 2D or 3D play

around over here with how the sound

falls off so tons and tons of options

that you can't really access if you use

that simple function so one approach if

you need these options you could make

each sound a prefab so make a prefab for

each different audio clip and then

instead of calling that function you

would simply instantiate that prefab to

spawn that audio so if you have lots of

options depending on how complex you

want your sound to be

but for a simple game and for simple

sounds this one line of code is super

simple

alright so here we have added sound

effects to our game that component with

the music that we had previously already

makes everything sound so much more

alive it's really starting to look like

a proper game

the one thing we still don't have is

some kind of game start and game and

scenario so let's have that in the next

lecture

hello and welcome I'm your code Maki in

this lecture let's add a simple and

beginning state to our game so right now

we can play the game of the mechanics

everything works perfectly and it's all

been implemented however in the

beginning of the game it just starts

right away as it loads there's no start

no countdown no time for the player to

get ready

someone sort that out with a simple

countdown let's begin by making a

general game manager script to handle

all of our general game States so let's

create a brand new c-sharp script

and now here you could use the name game

manager so you could use this name

however for some reason yantian likes uh

this custom icon when a script is named

exactly game manager personally I don't

like this I don't want it to be a

different icon I want this script to

look and behave just like any other one

of my scripts so personally I don't like

this but if it doesn't bother you then

go ahead use it doesn't really change

anything just a visual but in my case I

prefer to give it a different name so

sometimes I call it game Handler or

other times just something related to

this game like for example the kitchen

game manager and just like that it won't

have that custom icon just need to go

inside and rename this to Kitchen game

manager okay save the script and all

right now let's make a game object to

run it so a new game object with the

same name let's attach the kitchen game

manager and reset transform okay let's

go now here we're going to Define all of

the various game states that our game

can be in so for that let's define an

enum so a simple enum call it state

and for the various States let's say we

are first of all waiting to start then

we are on countdown to start then the

game is playing and then we have a game

over okay so these are our states let's

do a private void awake and on the

waiting list of the state so we need to

store a state for our state

and on a week we set the state equals

and let's begin on waiting to start by

the way the point with this waiting to

start say it will also be very important

in the next video covering multiplayer

basically we're going to wait until

everyone is connected before we start

the actual countdown but over here for

now we're just going to wait a little

bit on the waiting to start then we're

going to trigger the countdown and then

after some time trigger the game playing

state so pretty much all of these states

are going to be time based so let's make

a simple timer so a private float for

the waiting to start timer let's begin

on something like 1f so we just wait for

one second then let's make a private

void update and let's make a state

machine just like we've done previously

so do a switch on our state

in case we are on state DOT waiting to

start

if so then let's go into the waiting to

start timer count it down by time dot

Delta time

then if the waiting to start timer if it

is under zero if so then let's move into

the state equal state DOT let's go into

the countdown to start okay so that's it

and the other states are going to be

pretty much exactly the same so let's

just copy this so we have the winning

start and the countdown to start then we

have the game playing and finally we

have the game over and that one doesn't

have anything so just like this like I

said we could reuse the same timer but

let's write our code nice and proper so

let's make different timers for each so

let's make three timers so we're going

to have the countdown to start timer

so countdown

for this one let's see Fallen two three

so we're going to wait three seconds

before we start and then the game

playing timer

and for this one let's put it something

short just for testing so let's put it

just test and then down here let's just

use them so on the countdown let's count

down this timer on the game playing

count down this timer when the countdown

ends we go into game playing and when

the game playing ends we go into game

over alright so that's our super basic

state machine just a bunch of timers

super simple

let's do a quick look just to see so

over here just say debug.log and let's

just print out the current state

okay so just like this let's test and

yep right away we are waiting to start

after one second going to countdown then

after three seconds go into game playing

and now if we wait for 10 seconds

after 10 seconds we should be able to

see just a little bit and yep there you

go we've got our game over okay great

all the logic is working although we

actually didn't change anything

technically the game right now is on a

game over but everything still works the

same experience only so I can still play

I can still do everything

so let's sort them when we are in any

state other than the game playing State

we don't want the player to be able to

interact with anything we want to leave

it movement because that's usually nice

and fun but we don't want it to be able

to interact pickup objects or do

anything so let's do that basically over

here on the game manager let's just

expose the function so public pool let's

call this is game playing

then over here pretty simple just return

if the state equals state DOT gameplay

that's it

so now we can go into the player script

so over here on the player script let's

go down into the interaction function so

over here we've got the interact

alternate and the interact and on both

of these basically let's just ask if the

game is in the game playing state if so

we want to interact but if not then we

don't want to do anything so to access

the game manager we could add a pure

serialized field or as usual let's just

make a nice Singleton so pure public

static of type kitchen game manager the

instance make a public get and a private

set

then down here on awake let's set the

instance equals this okay so now over

here on the player let's just go into

the kitchen game manager access the

instance and test is game playing

and we're going to do an if if the game

is not playing so if we are not playing

we want to stop this so let's just

return so if the game is not playing the

code is going to stop executing here and

same thing on the interaction so just

like that we won't be able to interact

with anything once we are not in the

game playing State okay so here we are

waiting to start nope I cannot pick up

anything count down to start nope I

can't and as soon as we go into game

playing yep now I can't interact so I

can cut a bunch of things

and as soon as it goes into game

overstate

there you go currently in game over

state so now if I try and interact nope

can't do it okay awesome everything

works perfectly

so in terms of logic this is really it

there's nothing else we need to do

but of course right now the player would

have no clue as to why sometimes they

can grab and sometimes they can't so

let's add a proper visual

first let's add a visual to the starting

countdown

so let's do that as a canvas element so

let's go inside our canvas create an

empty game object name this the game

start countdown UI let's press F to

focus on the object press 2 to turn this

into 2D okay so let's see and over here

we really just need a text object so

let's leave this one anchored on the

center let's put the width and height

both on zero we don't need that and then

let's go inside create a new text object

call this the countdown text and then

inside let's just put a number so just a

three

let's put the width and height both on

zero then down here let's put it in bond

on a really big font size so let's say

something like 250 okay really nice big

number then let's also put it centered

and down the middle okay that's right

we've got our nice big countdown number

also by the way when using text mesh Pro

we can easily add a whole bunch of

effects if we'll look down here we have

the default text mesh Pro material and

over here we can add an outline another

line and so on so that's really great

however there's one very very crucial

thing when you want to add some effects

always remember that the effects are

being applied to the material meaning

any text objects that are sharing this

material all of them won't modify so for

the most part usually you don't want to

modify the default material if you do

then everything using this default

material will change like for example I

want to add a nice thick outline to this

one but over here I've got some regular

text that is also using the default

material so if I now add an upline and I

increase the thickness and if there you

go those also got an upline as well as

this and if I wanted download make it

quite a lot bigger there you go all of

them modify because all of them are

sharing the same material so usually you

don't want to modify the default

material if you want to add some kind of

special effects always make sure to

create a brand new material beforehand

so over here let's remove the outline

put it back on the dilation and let's go

up here to create the brand new material

first we need to find our phones over

here on the font asset we can just click

on it and we can see it over here

highlighted on the project window so

it's inside the text mesh profiler the

resources phones and so on so here is

the default font and inside this one is

the font that we're using now in this

font there's a nice little error icon

and inside we can see the default

material so let's duplicate this

material although it's important make

sure you duplicate the material and not

the font so with this material selected

I'm going to press Ctrl D and there you

go it duplicates the material and over

here let's give it some name so let's

say this is material that I want to use

for the start countdown

so there you go just like this also one

very very important thing the name of

the material needs to include the font

name otherwise it won't show up for

example if I get rid of this the only

version Sans SDF if I name the material

just like this and now I'll look over

here on the countdown text look on text

mesh Pro here is the drop down menu for

selecting material and over here note

how that one does not show up so it is

extremely important in order for it to

show up in here it needs to have the

same starting name so over here if I

rename this material put Liberation

sends SDF and then the name and now back

in here now look and yep now I do see my

material okay so that's great and over

here we can add what kind of effects we

want and it will only affect this one

and not any others okay so for this one

let's add a nice outline and let's make

some nice thick numbers so over here on

donation let's handle it by quite a

little bit

then for the outline color let's put it

maybe on a blue something a bit like

this okay let's push it back just a

little bit okay I think that looks

pretty good now if you want you could

add even more effect to this I made

another video covering how to use custom

Textures in your font doing that you can

just import the font directly into

Photoshop and edit it with all kinds of

effects for example in that method is

example what I used in my game hypernite

make the head counter look really nice I

also have a tutorial specifically on

that so if you want even more custom

text definitely go ahead and watch those

videos but anyways here we have our

countdown text looking pretty nice now

the number itself will be written

through code so let's do that let's go

into our scripts into our UI folder

create a brand new c-sharp script for

the game start countdown UI okay and

let's select the parent object and

attach the script now here first thing

we need is a reference to that text

object so let's add a serialized film

private and again remember what I

mentioned a couple of night years ago

with regards to the types so we want

xmesh Pro U GUI we want this one so it's

going to be our countdown text and now

for updating this text basically we just

need to know the game state so we need

to know when the countdown should show

up and as usual let's use some nice

events so over here on the kitchen game

manager let's fire an event whenever the

state changes

so a public event event handler

let's call it on stay changed

okay just like this no need for the

arguments so let's go down here whenever

the state changes and let's just invoke

this event so invoke this eventar is

that empty

so we change in there change in there

and change down there okay that's it so

now over here on the game start

countdown let's see we've probably start

and on start let's go into the kitchen

game manager access the instance listen

to the on say changed event as usual

write some nice clean codes so let's

rename this the kitchen game manager

so when they say changes we basically

want to show this if we are on the

countdown to start so let's go here to

the kitchen game manager and let's make

another function so public boom is

countdown to start active

and we just return if the state

equals the state DOT countdown to start

okay so that's a nice simple function

and on the UI script if the kitchen game

manager

if this one dot is countdown to start

active

if so then let's show if not then let's

hide so else

let's do a hide

so let's make these functions so proud

void show

and a private void hide and on this

let's just do the usual thing so game

objects and active into true or over

here set it into false and on start

right after we subscribe to the event

let's also hide it by default okay so

that's the basic logic for showing or

hiding it and now for the timer text

technically over here once inside the

countdown to start we could fire an

event on every single update that would

work but it would have some unnecessary

overhead

so instead another option is just make a

function to expose it so let's go here

make a public returning float get the

countdown to start timer

and we just return the countdown to

start timer very simple so then over

here on the UI script we can just make a

regular proud void update and on update

go into the countdown text in order to

set the text

and let's go into the kitchen game

manager and let's get the countdown to

start timer and just do A2 string okay

so that's it super simple so on update

we're going to constantly update the

timer so let's see if this works

back here in the editor let's just make

sure to drag the countdown text

reference and let's hit on play and okay

waiting to start and after a bit yep

there you go there's the number it's

currently on countdown and now the game

is playing so the show and high did work

on the number seem quite a bit odd

that's because over here on the settings

we have wrapping enamel so now I just

quickly disable this and let's test

again

sir we are waiting to start and there

you go there's our countdown three two

one zero and there you go gameplay

okay so it did work now of course as it

comes to the visuals it depends on what

you want

for example if you want to limit the

decimals you can use over here the two

string this one can include all kinds of

string formats for example for

displaying just two decimal places you

can add the string format F2

let's see what this looks like waiting

for the countdown and there you go now

it does Show with two decimals okay so

this is one approach alternatively

another format you can use is

number sign Point number number and

let's see this one

and yep there you go now it looks like

this

so as you can see there's lots of things

you can play around with when it comes

to the two string formats but in our

case I don't really want any decimals I

really just want to see whole numbers so

for that let's just seal out this number

so in mathf.cl

let's see on this one out and then just

do a two string okay let's see

so wait a bit and we got three two and

one and there you go the game is winning

alright awesome so here we have our

waiting to start and the countdown to

start all of that logic is working

perfectly now the next thing we need is

to handle the game end so let's do that

in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to handle

the game over State now for the game

over State this is obviously a game

design question for example you can make

it so that each recipe had a timer

attached to it and the player had to

create that recipe within time limit

then if they failed enough recipes you

could trigger some kind of game over or

for something more simple let's just do

exactly what we did for the game start

let's just do a basic countdown timer

after the game is over let's pop up a

game over window and show how many

recipes the players delivered so let's

do that let's go into our canvas and

inside make an empty game object call it

the game over UI then over here let's

stretch it to occupy the entire parent

like this now inside let's begin by

making a UI image this is going to be

the background let's put it in black

with just a little bit of transparency

and let's also stretches to occupy the

entire thing

so just like this then let's make some

text so let's make a new UI text click

the game over text

and let's say just game over

let's set the width and height both at

zero then down here disable wrapping put

it centered let's put it pretty big so

maybe 135 put it a little bit higher

then for some more text let's duplicate

this let's call this the enlay bone

recipes delivered text and over here we

just say recipes

delivered

let's put this one a bit lower and quite

a bit smaller

say on 50 okay and also on this one

let's put it in bold then change the

color a little bit okay next let's make

yet another text this one is going to be

for the final number so let's call this

recipes don't deliver text

and this one is just going to have

whatever number of recipes we've

delivered and let's put it over here and

quite a bit bigger okay so this is the

game over window that we want also a

quick note like I mentioned previously

the Sorting order over here on the UI is

based on the ordering the hierarchy so

for the game over we want this one to

show up on top of everything else so

make sure the game over it is the last

one over here on the UI make sure it is

the bottom most child on the canvas okay

now let's make a game object to run this

so let's create a brand new script game

over UI let's go into the object wait

for the compilation and let's drag the

script okay now here the only reference

that we need is just for the text so

let's just make a serialized film of

type text mesh Pro ugly for the recipes

delivered text here in the editor let's

just drag the reference okay now let's

make some show and height functions and

also show it just on the game over so

really we're going to do the exact same

thing that we did over here on the game

start countdown so let's actually copy

exactly this let's go into game over UI

pass the exact same thing Okay so we've

got the show and hide functions we test

and then over here on the state change

instead of showing this one on the

countdown we want to show it on the game

over

so let's go over here and just make

another function so public goal is game

over and we just return if the state

equals the state that game over okay

that's a function

so over here if we are is State game

over

if so then we show if not we hide okay

the last thing we need is just for the

text so this is going to be the recipes

only vertex so we're going to set this

to something

which really means that we just need to

keep track of all of the recipes that

have been delivered so until here onto

the delivery manager script and let's

just keep track so just a simple end so

a private end for the successful recipes

amount

and then whenever we have a recipe

success so let's go here into our

delivery recipe function whenever we

have a success let's just increase this

by one okay so that's it now we just

need a function to expose this so we

probably can't for the get the

successful recipes amount and just

return the successful recipes amount

okay so finally back here on the game

over UI let's just print it so go into

the delivery manager xsc static instance

and get the successful recipes amount

and of course we need the string so to

string except for this one this is never

going to change after the game is

already over so let's not do this on

update that would be quite wasteful so

let's just do it up here so as soon as

we have the game over we show we print

the recipes and that's it okay so let's

test so here we are waiting for the

timer and let's wait and just wait five

seconds for it to finish and we should

see a zero so let's just make sure that

works so after a little bit of time yep

there you go we've got recipes all over

zero okay

now back here again let's try and

deliver some recipes now so let's try

and make a cheeseburger try it only for

that

cut this one pick up this one

pick it up put it in there

and okay quickly all right good and

there you go we've got a one all right

Awesome everything worked perfectly

let's just add one more final element

right now we cannot see what is the time

left in the game so let's add a nice

lock element

so over here on the canvas let's make

another empty game object

let's name this the game playing clock

UI

and let's also put it behind the game

over UI so let's put it above on the

hierarchy so that it shows up behind in

order to be able to see what we're doing

let's also just hide the game over UI

but only here on scene view so let's

click on the I icon okay so here we have

our window let's just anchor it on the

upper right corner so let's put it

somewhere in there then inside let's

create a new UI image come with the

background for the Sprite

let's go with these circles right so

let's click on the eye icon to show all

the default Sprites and let's use the

one included with the circle

so you have this one let's also add a

nice little outline so let's put it on 2

2 with phone Alpha and let's also add a

nice shadow just nice visual so on five

minus five like that and for the color

let's also put it some kind of dark gray

okay so this is our background now let's

duplicate this so Ctrl d

and let's rename this one the timer

image and for this one let's give it a

different color so maybe something like

a blue so something like this okay and

now over here on the image type instead

of simple let's go with filmed let's

choose Radeon 360. okay great and now

over here we can play around the film

Mount and this will be our timer then

you can set it up however you want for

me I'm going to choose to start from the

top so as it starts the time we're going

to countdown Until the End okay so

that's great now let's make the script

to run this so let's create the brand

new c-sharp script same thing the game

playing clock UI and over here let's

just attach a script so now all we need

is reference to our image

so let's make a serialized field

private image let's make sure to use

this one the image inside Unity

engine.ui this is going to be our timer

image okay like this back here in the

editor let's drag the reference all

right now that we have this we need to

ask the game manager to get the timer

normalized so let's go over here onto

the kitchen game manager and let's make

a function to return just that so a

public float let's call it get plane

timer normalized or game point timer

actually just to match the state

so get this one and up here we have the

playing timer we just need to define a

maximum in order to be able to calculate

the normalized value so let's duplicate

this call it the game timer Max and set

this one to 10 and this one leave it

like this

and down here when we change the timer

when we go into game pointing let's set

this one equals this.mex that way we

only Define the timer just up here okay

so with that now down here we can do the

compilation so we can return the game

playing timer divided by the game

playing timer Max

except just like this going to be

inverted because for the game playing

timer we're counting down instead of

counting up so all we need to do is our

simple just reverses so just one minus

just like this okay great so we have

this function and then over here on the

clock just go private void update and on

update let's go into the kitchen game

manager the instance let's get that and

we're going to use that on the timer

image.fillment okay that's it super

simple let's see okay here we are on the

waiting to start all right waiting and

as soon as we start if there you go

there's the timer going and we can see

it constantly increasing

so it's at the halfway point

and just a little bit more

and there you go yep we've got the time

over and we have our game over

all right awesome so over here we

implemented a really nice game over

Saint we have a playing timer with an

icui element and when it ends we get a

game over window showing you a bunch of

stats now with this working the next

task is to have some kind of main menu

so we can play again after the game is

done so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to make a

super simple main menu and downloading

system okay so every game needs a main

menu so let's build one let's begin by

making the scene so let's go into our

scenes and create a brand new scene call

this the main menu scene

and okay here's our default scene now

over here for the most part you really

just want some basic buttons so nothing

too special so let's create a brand new

UI canvas and let's set up as usual so

screen space overlay yep then let's go

with scale with screen size 1920 by 1080

and let's match with the height okay so

there's our canvas now inside let's make

an empty game object name this the main

menu UI let's stretch it to occupy the

entire thing so zero zero on everything

okay

now inside let's create a brand new UI

button let's name this the play button

then inside for the text let's say play

Let's size the button to be quite a bit

bigger so let's say 450 by 150 and on

the text itself let's put it in bold

only font size quite a bit bigger let's

say 70 then let's also change the color

let's put the text in White and the play

button over here the normal color for

the image let's put it on a dark gray

then also over here on the button

background let's add a nice outline

let's put it on foam black say something

like three three then let's make a

Shadow and for this one five minus five

okay so that's our basic button let's

just anchor the button so choose the

play button let's anchor it on the lower

left corner and let's push it just a bit

like this okay pre-symbal now let's

duplicate this one push it a bit lower

let's also make it just a tiny bit

smaller so just 120 this is going to be

our quit button so let's rename this to

the quit button and inside for the text

just say quit and put a bit more on the

font size okay like this okay so we have

the two basic buttons that we need now

let's make this crypto random so let's

make script with the same name so main

menu UI so let's go into our script UI

folder create new script for the main

menu UI let's attach the script and open

okay so now here let's begin by making

serialized films for our buttons so it's

always film private of type button

inside Unity engine.ei this is the play

button and then we have another one for

the quit button okay back in the editor

let's drag the references so that's the

only button and the quit button okay now

here in the code let's add some

listeners to these buttons and let's do

a private way to wake and on the way

let's go into the play button and going

to the on click event so the event when

the player clicks on the button and

let's add in listener and now we pass in

The Listener now for here to do this we

can add a function so we can make a

private void Play Click we can define a

function kind of like this and over here

add it as The Listener so that's one

approach or another alternative that

personally I like to use is to use what

is called a Lambda expression so instead

of defining an external function down

here we just go up here and directly

with the finding Lambda so we open

parameters to display the parameters for

the function which in this case we have

none so just open and close then we do a

nice little arrow and then we have

whatever we want to be our clear code so

both the code that I have here and one

that I have here both of these are

exactly the same thing this one is

called the unlimited expression which is

also a type of delegate definitely go

ahead and watch my video on C sharp

delicates in detail it's yet another

extremely powerful c-sharp feature I

find them especially useful especially

over here to setting the click listeners

there's no need to make another function

just use a Lambda expression that's it

so over here I'm going to use that

instead of an external function Okay so

we've got the play and then let's also

listen to the equip so on the quit

button the exact same thing okay now

first on the equip button it's actually

very simple we just go into application

and we call the quit function this will

quit the game that's it very similar

although one note if we actually test it

like this so here is the game playing

and if I click on quit and nope nothing

happens now the logic is actually

working we can see visually that the

button is changing state so we are

indeed capturing clicks however when the

game is running inside the editor

calling that function the

application.quit doesn't do anything but

if this were a phone bill then clicking

on that would indeed close their game

okay so now for the play button for this

one it's also very simple we just need

to go inside the scene manager which is

inside the unity engine.scene management

we just need to go inside of this one

and we call load scene

this function will load with a certain

scene and for loading we can either use

the scene film index or we can use the

scene name like I've mentioned several

times string names are horrible although

in this case the alternative using an

INT is also not very good just a number

is very hard to read the code and being

able to know what scene this is loading

so there's one better approach that I

prefer to use but first over here let's

just use the index just for testing so

we're going to load the scene on index

one so just like this and then here in

the editor and let's go into file and

build settings

and over here we see the scenes in our

build right now we just have the game

scene so let's just add our scene so

let's drag the main medicine and drag it

on there and also let's make sure it's

on the top of the list basically the

first scene is the one that won't be

unloaded as soon as the game starts so

let's try it right up top just like that

then over here on the right we see the

index so by loading the scene on the

next one we're going to be unloading the

game scene okay so with the slits test

so here we are and if I click on playing

and if there you go it doesn't load the

main scene okay great everything is

working so this is the seamless way to

do scene loading however this method

does have one issue it's not super

noticeable when a game of this scale

because it loads pretty quickly

but like this note how when we click on

play there you go everything freezes for

a little bit while the game is loading

like I mentioned in this case the freeze

is so small so not necessarily an issue

but if the game was much more complex

then the player would be staring at a

frozen main menu for perhaps 30 seconds

that would not be good one way to avoid

that is actually very simple basically

it's what I already covered in detail in

the scene loading video that video was

made quite a while ago but it's still

very much up to date here we're going to

do pretty much the same thing so we

first create the scene just empty just

saying loading and then from that scene

we load the final scene that way the

game stays Frozen on a scene that says

loading which is much more clear to the

player so let's do that first let's make

our scene so inside our scenes folder

let's create a brand new scene call this

the unloading scene okay let's go inside

and on this one we want this one to be

fully black so let's go into the main

camera and scroll down over here under

environment and instead of rendering the

Skybox for the background let's go with

a solid color and let's go with phone

black okay there's our black main camera

now let's make a canvas so a new UI

canvas let's set up as usual so scale

with screen size 1920 by 1080 and match

with the height okay then inside let's

just make a simple text object so just

say text then over here on let's say

just loading

let's put the text width and height on

zero put it on Bold let's make sure to

disable wrapping

and push it over there on the side and

maybe increase the font size down a

little bit okay there you go we have our

very basic loading screen now we're

going to unload this scene and then once

on this scene we're going to load the

final scene although also one very

important thing related to loading

scenes is you need to remember the

lifetime of the objects regular game

objects only for example the ones that

we see here in the hierarchy these get

destroyed when you do a scene change

so for the goal that we're trying to

achieve we need to unload this loading

scene but then also somehow transfer

data so that the loading scene here

knows which one is the final scene now

you might think that over here on the

main menu we could create a game object

attach a script that would hone the

reference to the final scene but like I

said game objects get destroyed as soon

as we unload the unloading scene so for

transferring data between scenes we

can't really use a regular script on a

regular game object now one approach is

to use the don't destroy on loan this is

a Unity function that helps you stop a

particular script or a game object from

being destroyed that way the object

won't process through scene changes so

that's one option but another option

that I prefer is very simple let's just

make it another class so let's create a

new c-sharp script call this loader and

over here let's go ahead and make this

class a static class and we are not

going to extend Model Behavior so just

like this

basically by making it static it means

that this one is not attached to any

specific instance of an object this

class cannot be attached to any object

and cannot have any instances

constructed then inside we can add

static functions in fields like for

example a static and for the Target

scene index

so now this field we could set this

field from over here on the main menu UI

and when we would load we would not be

resetting this field also here I should

point out one quick thing you can make

field static without making the entire

class itself static making the class

static is just a good approach if the

entire thing if everything in this class

is also meant to be static if you don't

make it static then you can have regular

films here

you can have both static and non-sanic

whereas if you make this static

then you're going to have an error

because you cannot have non-static

feelings so this is another clean code

thing if it's only meant to contain

static logic then make the class itself

static okay so we have a static field

for our Target scene but as usual we

don't want this to be a public field we

don't want the main menu to directly

write to this field so let's make this

class the only one responsible for

anything related with scene loading

since then let's make a function so a

public static void call it load

and for a printer let's receive a string

for the Target scene name then over here

we will load the actual scene so let's

go into the scene manager and load the

scene

analyst best in the Target scene name

okay that's it

and then over here on the main menu UI

instead of directly unloading a scene

let's go into the loader and con load

and pass in the scene name so that's the

game scene

okay so this is what we're going to do

that's good except it's obviously not

good over here we're using string names

that's horrible we should never use this

so let's avoid using strings as much as

possible in one simple way is to just

Define an enum for all of our scenes so

let's go here on the other and let's

define that so a public enum let's call

it scene

and for all of our scenes so we have the

main menu scene then we have the game

scene and the unloading scene

okay so then down here on this function

inside receiving a string we just

receive a scene for the Target scene and

we use the target scene although of

course the NT API does not support

unloading our custom enum it has to be

an index or string so the simple

approach is just to convert this one

into a string that's it so the only

thing you need to make sure is that the

enum values over here match the actual

name on the actual scenes perfectly so

don't make any mistakes keep it case

sensitive so don't do this make sure

everything matches perfectly okay so

just like this everything should already

be working the same as previously so the

main menu calls that let's actually just

use that so let's use scene Dot Game

scene

so on the main menu we do this and

unloader we load the scene okay let's

test here is the main menu and if we

click and wait a bit and after you go it

didn't load the game scene okay great so

everything still works the same as

presently except now all of the

unloading logic is inside of this class

and over here let's open a loading scene

in the middle basically when we have

this function to load a final scene

let's first off set this field so this

one instead of being type in let's make

it a type scene and this is going to be

the target scene and let's make it

private okay

so when we have this function let's set

that field although here remember how

this is a static class so in order to

access this field we need to exit

through the class name because over here

we also have a local variable with the

exact same name so what sex is the

unloader.target scene and set it to the

Target scene

so again don't be confused here you can

even use visual studio and put the

cursor on top to see what object

represents what so you can see the

unloader.target scene is referencing

this field whereas this one over here is

referencing the local field so we want

to assign the member field to the one

that we received as a parameter okay so

we store that and then let's immediately

unload the unloading scene so scene

manager let's load the scene and we're

going to load

the scene dot loading scene dot to

string okay so we're going to download

that and now here comes the tricky part

if we do this so if we load the

unloading scene and then immediately

unload the target scene if we didn't

like this it won't actually show the

loading scene

we're calling these functions one right

after the other so to unload the one and

immediately the other basically we need

to wait at least one frame to render so

that the unloading scene is visible and

then we can alert the final scene so

let's make a script to do a very simple

jump let's create a brand new c-sharp

script for the unloader comeback and now

let's go inside the unloading scene so

this is important let's make this on the

loading scene not the main menu or the

game scene so over here let's create an

empty game object for the unloader

comeback let's reset transform just keep

things nice and clean and let's attach a

script so the only other comeback okay

and on this script we want to basically

just wait for the very first update

so let's see private ball is first

update and we started off as true

actually

so is the first update is true then we

do a product void update so if it is the

first update if so then let's set is

first update to false

we have the first update although

technology I should point out that we

don't really need this we're going to

load right away so either way it will

only run One update but still I like to

add this just to make the logic

perfectly clear basically if it is the

first update then let's call a function

on the unloader so on the loader over

here let's make a function public static

void call it below their comeback

okay we have this function it's over

here on the other convex let's just go

into the unloader and call the unloader

convex function all right so basically

now here we have this function that is

going to be triggered on the first

update so we know for certain the

unloading scene has been rendered so

it's over here that we want to load the

actual final scene okay that's it here

we have a super simple loading system

just make perfectly sure that the

unloader come back with the script this

one only exists on the loading scene it

should not be on any of the other ones

so let's test and for that let's go

inside the main menu scene okay and now

let's hit on play okay so here we are on

main menu now if I click on play and

actually here's the thing that I forgot

so make sure you don't forget this we

need to add the unloading scene to the

builds in order to be able to load

so let's go up here into the build

settings let's go into the project drag

the unloading scene like that okay so

now let's test so here we are on the

main menu let's hit on play and there's

the loading scene after a bit yep here

we have our game scene all right awesome

so with that everything is working

perfectly all of the logic is working

great now the wrong words great let's

just make a nice proper visual for our

main menu so for that let's go inside

the game scene and over here let's copy

a few things so let's pick up the four

object and let's also pick up the global

volume with the post pressing so let's

copy both of these let's go into the

main menu scene and over here on let's

paste both objects okay now let's also

drag some player visuals so let's put

this in 3D go back down into the floor

and let's pick up some visuals so let's

go inside our assets on the prefabs

visuals let's find over here the player

visual again make sure you drag the

visual only we don't want any logic

components and by the way this is yet

another great benefit of separating the

logic from the visuals right now it's

super simple for us to play some players

here because we have just the visuals

commonly separated from the logic okay

so on the visual let's just make it look

at the camera let's position a bunch

more players so let's duplicate this

and put one to the side we're going to

move the camera in a bit but now let's

just place them and included assets

there are a bunch of materials so over

here we see the employer body then we've

got a blue a green and a red like I said

this first course is on making this game

in single player but the goal is to then

make a second course after this one on

converting this game into multiplier so

that's why I included multiple colors so

let's just drag these let's go into this

player Visual and on this one make it

blue so on the head and on the body then

on this one on the side here let's make

this one green so green there and green

on the head and for the one behind let's

make this one the red one so put it in

red and in red Okay so we've got our

nice four players now let's also add a

camera so we're going to have the camera

kind of like this kind of from below and

looking upwards I think that looks

pretty good for that let's use cine

machines and let's go into game object

go into cinemachine and let's create a

brand new version on camera okay unlike

this let's just push it up a little bit

okay so this is our nice composition

now on the virtual camera let's just go

ahead and add some noise so let's add

basic multi-channel purlin so let's do

it just like we did when we first had

the thin machine so let's use the

handheld normal mild and now let's just

play around these films which by the way

you can do that while the game is

playing so let's hit on play and over

here you can play around down the fields

although actually defaults already look

pretty good but let's put the frequency

maybe a little bit less and the

amplitude maybe a little bit bigger so

just some nice little Sway and by the

way if you make any changes to the send

machine virtual camera and now you stop

playing it will actually lose those

changes but over here on the virtual

camera there's this nice toggle save

during play so if you tick this and now

you exit play mode and there you go

those changes were saved okay great now

let's just make sure to untick this so

we don't accidentally modify okay so

here we have the basic Vision that we

want finally there's also a game logo in

the included assets

so let's just go into our canvas into

our main menu let's create a brand new

UI image let's assign the logo Sprite

then let's just position it on that

corner so let's move it all the way up

there we can anchor it to the top left

corner and let's make it a bit bigger

and by the way I want something like

this if you play around this it might

get a bit scratched so if so over here

on the options on the image you can

download this one to preserve the aspect

ratio so that way even if you stretch it

won't actually be stretch it will always

be perfect okay just like this okay so

here we have our basic main menu it's a

basic setup but it looks pretty good and

with that we have built a nice main menu

alongside with the unloading system so I

can click on play it goes into the

loading scene and then into the game

scene so that's great

the next thing that we need is some kind

of pause button so let's do that in the

next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add a

pause button with a pulse window that

also has the ability to quit back to the

main menu and in doing so we're also

going to solve some sneaky issues with

loading okay so here in the main menu we

can click the play button in order to

unload the game and yep everything works

now I'm in the game but now let's say I

want to pause the game for a bit or quit

back to the main menu right now there's

no way so let's do that let's go here

onto the game scene and first let's send

on the pause and for that we're actually

going to need some input so let's first

go inside our player input actions let's

open this and then over here let's make

a brand new action let's name it the

pause

for the action type let's go with button

okay and for the bindings over here

let's go with escape and actually if we

use the same method that we've been

using if we listen and press on Escape

nope doesn't work because Escape just

cancels it so instead we need to use a

search bar here Search for escape

keyboard just like this okay great now

again as always let's make sure to save

the asset and wait for the compilation

to happen there it is so now here on the

game input list let's listen to it and

fire the event as usual so go into the

player input actions the player action

map let's go into the pause action and

listen to the performed event

and when this happens let's fire off an

event so a public event event handler

let's go on pause action

and then down here we're simply going to

invoke this event

okay just like this now from listening

to it here's the question where does

that make more sense should we do it

over here on the player script or

perhaps over here on the kitchen game

manager I think over here on the game

manager makes more sense since a pause

is more related to the game itself

rather than a specific action by the

player so let's add it over here let's

first of all listen to the event so

let's see what private void start and on

start let's listen to it so let's go

into the game input and we didn't

actually make it a Singleton yet so

let's do that over here let's make a

public static game input

for the instance with a public yet and a

private set

then down here on the Wake let's set

instance equals this okay there's our

Singleton so now back in the kitchen

game manager what's going to be instance

and listen to the on pause action event

and again let's rename this to give it a

proper name

so the C game input on pause action okay

so here we have it when we have this

let's call some kind of pause game

function so let's define this let's go

to the end of the file here and over

here let's make that function

so a private void pause game and over

here we're going to pause the game now

for pausing doing this is actually

surprisingly easy

basically all of our logic is using time

dot on time for example over here on the

player script we have our movement speed

yep then we get the inputs and over here

on the handle movement function yep for

the movement distance we have move speed

multiplied by time.10 is done or another

use case over here on the stove counter

we've got a frying timer and how we

count it down again is the same thing

time dot double time well it turns out

that behind the scenes time to time the

time actually already has a multiplier

when you access this it is after that

multiplier calculation so over here on

the pause game function we can just go

into time and we can modify the time

scale this one is the multiplier so if

we just put this at 0f then that's it

this is going to pause all of the other

Delta times so let's test so here we are

pay attention to that in the countdown

timer and I press on escape and there

you go everything pauses the countdown

timer pauses over here the script pauses

and I can no longer move nothing works

everything is perfectly paused alright

Awesome everything works except one

problem obviously right now we cannot

unpause if I press Escape it's not in

pausing so let's do that over here on

the kitchen game manager let's add a

simple bone so a private bone let's come

with is game paused and let's see found

it to phones okay so is game paused and

then down here on the pause game

function let's simply flip this one so

we set this one equals not this one so

that is going to flip that Boolean and

then we check if the game is paused if

so set it to zero f and if not then

we're going to set the time.time scale

back into one F okay so now this should

pause and unpause so essentially rename

this function since this is no longer

just going to pause let's rename this to

toggle and pause game this is going to

pause and unpause

okay so let's test

okay so here we are everything is

running now I pause and there you go

everything freeze I cannot move the

arrow will stop the countdown to stop

when I press again and there you go nice

and redeemed all right great so all of

the logic is working perfectly the only

thing we need is we don't just see

visual and as usual let's separate the

logic from the visuals so let's go

inside the canvas let's go into the

scene View and inside the canvas let's

create an empty game object call it the

game pause UI then let's stretch to

occupy the entire screen so zero on

everything okay great now inside let's

first of all add a background so a new

image name this the background let's

once again stretch to occupy everything

and on the color let's put it in black

with just a little bit of alpha okay

just like that then let's add some text

so let's create a brand new UI text

let's name it pause text

and in here let's just say paused let's

just make it big so the width and height

both on zero let's disable wrapping Put

It Center down the middle and let's

increase the font size by quite a bit

and put it in bold and let's also change

the color maybe a nice yellow something

like this okay that looks pretty good

let's just lift it up by a little bit

now let's make a script to show this so

on the UI folder let's create a brand

new c-sharp script call this the game

pause UI let's attach it then open now

here let's do the usual thing so let's

make two show and hide functions so

private void show and then a private

void hide

so on the show game object set active

into true and on the hides set it into

false

okay that's it pretty simple now we need

to know when to show our hide these

functions so we're here on the kitchen

game manager let's make two events to do

that so let's go up here make a public

event event handler

and let's name this on game pause

another one for on game unpaused okay we

have both events then down here on the

toggle pause game if we have this one

time scale 0 that means we have pause so

let's invoke the on game pause this

eventar is not empty okay and on this

one let's trigger the other one so on

game unpause

okay we've got the two basic events now

back here on the game pause UI let's

listen to it and as usual let's do it on

start so private start let's go into the

kitchen game manager access the static

instance and let's listen to the on game

pause

and I'm going to listen to the other one

so the instance on game unpaused so

listen to both of them and as usual

let's write the clean codes and let's

rename this so kitchen game manager and

on this one the same thing

so also the kitchen game manager

okay we have both and when the game is

unpaused then we want to hide the pause

window and when the game is paused then

we want to show the pause window and

finally of course we want to hide it by

defaults over here on sart after we add

listeners let's just hide it okay so

that's it that should work so let's test

so here we are everything is running now

press the pause and there you go got a

nice pause window press again and there

you go everything resumes okay great so

the last thing that we want is just a

button over here to go back to the main

menu and let's also add a button to

resume without having to press the

hotkey so over here let's create a new

UI let's make it a button this is going

to be the main menu button now let's

make it quite a bit bigger okay width

and height of 30 and 80. let's put this

one quite a bit down there and inside

for the text this one is the main menu

let's put the color in White and the

background for the button let's put this

one in a dark gray and let's also just

for fun add a nice upline and let's also

add a shadow

for the outline let's put it on for

Alpha and let's put it on about 3 3 and

for the effect on the shadow 5 minus

five okay so that's a nice outline and

nice shadow

and then for the text itself let's put

it in bold and raise it by just a little

bit okay just like that looks pretty

good so this is the main menu button and

then let's also make so duplicate this

let's make this one rename it this is

the resume button

and inside on the text let's say resume

okay we have our two basic buttons so

let's handle them in the script so over

here let's add as usual a serialized

field private of type button so that's

inside Unity engine.ui so it's for the

resume button and then we're going to

have the main menu button

okay let's save the script and back in

the editor let's drag those references

so that's the main menu button and the

resume button okay so now for these

let's add the click action so let's do a

private awake and on the way go into the

resume button the on click and let's add

a listener so this is going to be our

listener

and same thing for a main menu button so

main menu now for the main menu this one

is super simple let's just go into the

loader and call the unload function and

we're going to download the main menu

scene

okay that's the main menu very simple

and for the resume this one is only

going to be clickable when the game is

paused so we can just trigger the same

function on the kitchen game manager to

toggle the pause so kitchen can manager

the instance and toggle the pause game

this one is actually private so let's go

to it and let's make this public so we

can count from there okay that's it

super simple Let's test okay so here we

are and let's pause the game and now if

I click on resume if there go it does

work everything resumes and now pause

again and now let's go back to the main

menu loading any up there you go back in

the main menu alright awesome so

everything works perfectly

however there's one sneaky issue here

you can already see the issue by seeing

that all of these animations are still

but let's click on play and notebook

that issue everything is still frozen I

cannot move the character and over there

the Shader that one is completely Frozen

so the times can only still set to zero

basically we need to manually reset it

and the simplest way to do this is

really just in the main menu

so we can go here on the main menu UI

and we can just use this as our reset

function so let's just go into time.time

scale and let's set this one back into

one F that's it that's the only change

Let's test so here we are let's pause

let's go back into the main menu

and we can see the animations are indeed

playing and if we go back into play and

if there you go everything works

perfectly we can pause and yep here we

do see one of the other two sneaky

issues left basically it has to do with

scene loading and cleanup so the first

one is on input

over here on the game input class we are

constructing our player input actions

and we are listening to these events and

technically this object the one where

the game input is attached this object

is going to be destroyed when the scene

changes

however this object that we're creating

this instance of player input actions

this one does not get destroyed

automatically so that is why when I went

into the pause menu again for the second

time over here we've got a missing

reference exception basically the player

input actions of the previous game is

trying to show the pause window also of

the previous game which has since been

destroyed so obviously we have a missing

reference exception because that object

no longer exists so in this case we have

two options to solve this one option is

we can just unsubscribe to these events

Unity mono behaviors have a really nice

combat called on destroying so over here

private void on Destroy so this is the

default one this one is called when the

mono behavior is destroyed

so we can go into this one and we can

manually unsubscribe and the way that

you unsubscribe is you just do minus

equals

so this would solve that problem because

when this object is destroyed it's going

to unsubscribe from those events so the

next time it will no longer trigger so

that would fix it however on the game

input class we are still creating a new

object of this type I'm not 100 sure how

the input system works in the background

so perhaps this object might say in

memory which is not good so another

approach we can do or perhaps in

combination with this is we can

unsubscribe and then we can properly

dispose of this object how we do that is

very simple let's just go into the

player input actions and we just call

the dispose function that's it

this should clean up that object and

free up any memory so let's test so here

in the game view let's pause let's go

back into the main menu now let's go

back into the main game and now if I hit

pause and if there you go we no longer

have any errors okay so that's good

however now we still have one more

potential issue and this one has to do

with Statics like I mentioned before

Statics belong to the class and not any

instance of that class so that means

that static films will not be destroyed

or reset when the scene changes in the

case of our unloader here where we have

a private static field this one the fact

that this one doesn't reset

automatically that was a good thing

that's what allowed this to make the

unloading system but in the case of

maybe static events that might not be as

good it might mean that we might be

keeping some state from the previous

game which might cause everything to

break so basically we have a similar

problem to what we had in the input

where some logic from the previous game

might be affecting the next game in all

the code that we wrote the main place

where we use Statics were in The

Singletons and these are going to be

cleared automatically when the

underlying instance object when that one

is destroying so these do not cause any

problems however for example over here

on the cutting counter we've got a

static event when the scene changes this

will not be cleared so this will still

have the same number of listeners we can

actually see how many listeners there

are by printing it so let's go down here

before we're invoking the event let's do

a debug download let's go inside the on

any cut event and over here we can get

the invocation list this one is a list

of all of the functions that are

listening to this event

and we can just print out the link to

see how many listeners are listening to

this event so let's see what this

returns okay so over here let's pick up

some cheese and slice it and if I'm

working the log yep there you go one

there's only one listener okay that's

correct

however now if I go back into the main

menu and now I go back and I play again

okay so let's play let's just wait for

the countdown and once the countdown

ends pick up some cheese go there slice

it and there you go there's the problem

now we have two listeners in this case

doesn't really cause an error because

the tune listeners they're just over

here on The Sound Manager so we are

subscribing to this event and we're

doing the cut and playing the cut object

however if here we do something with

this transform like for example let's

just do a debug download on this

transform that position if we do this

here let's go ahead on the first one

let's slice and okay that works let's go

back into the main menu now play again

now wait for the timer

pick up some cheese go there slice any

of that I go there we have our air that

is because we are now accessing The

Sound Manager transform and that one has

since been destroyed so if you do use

static events like this one here if you

do that always remember you need to

manually reset that state it won't

happen automatically on the scene load

and one way that I normally do it is

just make a class responsible for doing

that so let's go ahead and let's create

a brand new c-sharp class let's call

this the reset static data manager and

for this one we want this one to run

only on the main menu That's only where

we're going to reset things so let's go

inside the main menu scene let's go

there let's create a brand new empty

game object for the reset static data

manager let's reset transform just keep

things clean and let's attach that

script again it's very important that

this object only exists on the main menu

then over here we're basically just

going to go into any script and reset

any data so for that on all those

scripts let's make a function

so over here on the cutting counter

let's make a public static function

let's call this reset static data in

order to reset any listeners let's just

go into the on any cut and set it to

null that will clear all the listeners

so we just do this and then on this

script Let's see we practically awake

and on awake let's go into the cutting

counter under the class so not any

instance so we're going to access the

static and we're going to reset the

static data that will clear all the

listeners on The Cutting counter all we

need to do is make sure to do this on

every single static event that we have

so on The Sound Manager and by the way

here we can get rid of the testing code

here we can see all the static events

that we're using so we've got the

cutting counter then we've got the base

counter and trash counter so let's go

here on the base counter and paste the

exact same thing and reset this event

okay and now let's go into the trash

counter

so here on trash counter same thing

reset this event set them all into null

and by the way here we have a warning

that's because trash counter extends

base counter so basically this is

telling us that we are hiding another

function with the exact same name in

this case we do want to hide it so

what's actually make this new to make

sure that this one is a different one

just to avoid that warning and same

thing over here on the cutting counter

we also need to make a new okay so

that's it and now we just need to go

over here onto the reset static data

manager let's go into the base counter

and reset the static data go into the

trash counter and reset the static data

okay that should do it let's see so here

we are in the game let's pick it up and

slice it and yep we've got just one

listener that's good let's go back

outside back into the main menu let's

play once more and over here let's pick

it up again go there drop it and there

you go still just one listener because

we are now correctly eliminating all of

the previous listeners

so this is the one sneaky issue that you

must be careful with when it comes to

object Lifetime and Statics for static

Fields you need to remember that they

don't manually get cleaned up that's up

to you so that's something you have to

keep in mind but you can also see how

easy it is to solve now that this is

solved let's just go into the cutting

counter and just get rid of our testing

log alright so with all of that all of

our scenes are working so we can start

from here from the main menu and go

straight into the game then here we are

in the game playing normally we can

pause the game at any point from the

pause screen we cannot resume or we can

go back into the main menu and from back

into the main menu we can once again

play the game from scratch and if there

you go everything works alright awesome

now the next thing that every game

requires is some options so let's do

that in the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to create a

simple options menu where we can modify

the audio levels okay so here let's make

the options menu so on our game scene

let's go into the canvas and create a

new empty game object let's make this

the options UI let's stretch out this

one to occupy the entire screen

then inside let's make a UI image once

again let's stretch out everything

let's put this one in black in just

almost full Alpha okay now let's make

some texts so let's create a brand new

UI text call it the options text

then for text let's say just options

let's put the width and height at zero

let's disable wrapping Put It Center

down the middle and put it quite a lot

bigger

okay that's the options now just move it

slightly upwards all right now let's

make some simple buttons to handle our

audio controls we're going to make it

super simple literally just a button we

can click so inside the options UI let's

create a brand new button

call this the sound effects button then

let's make the button a bit bigger

something like this okay

and inside for the text let's say sound

effects and then we're going to have a

number for the sound effects let's just

quickly change the color so put the text

in White and the button over here the

button image let's put it in a dark ring

okay let's also make it just a tiny bit

thinner it's just like that okay so this

is the sound effects button now let's

duplicate this one this one is going to

be the music button so let's name this

the music button

then inside for the text music and then

a number

and that's pretty much it so by clicking

on either of these buttons we're going

to increase and then Loop the volume so

let's make a simple script to handle our

options window so in our scripts inside

the UI let's create a brand new c-sharp

script for the options UI let's go ahead

and attach a script and open

so here as usual let's get some films

for our buttons so a serialized film

private of type button for the sound

effects button and then there's another

one for the music button

okay both buttons now let's add the

click event so on private awake let's go

into the sound effects button and on the

on click let's add a listener

and we're going to do the same thing on

the music button

okay so now when we click we want to

change the volume so let's go here onto

The Sound Manager and make a function to

modify the volume

let's make a private void change volume

and here we're going to increase the

volume by 0.1 percent so constantly

increase in 10 increments so that means

we need to keep track of the volume so

up here in order to find a SIM phone

private float for the volume

well it's default it to one F okay so

now down here we take the volume and we

increase it by 0.1 F and now let's Loop

it back to zero

now for looping usually you do it using

the modular operator so here you could

do volume equals volume module of 1.1 f

that way when it gets to 1.1 f it would

reset back to zero but here since we're

working with floats which can have a bit

of odd Precision with this let's just do

a simple lift to make sure that always

works

so if the volume is above one f

if so then let's just reset it to zero

okay

so here we modified volume and let's

just make sure to use it over here when

we actually call the audio

source.playclip Point here we've got a

volume but this is the one that we

received as a parameter so let's

actually receive this one rename this to

volume multiplier

and we're going to basically multiply

the one that we receive in the parameter

by the one that we actually store

so this way on these functions when we

play a certain sound we can still give

an optional volume if we want to make it

louder or quieter then the regular sound

effects okay so we have our change

volume function now we just need to call

this from the options UI so that means

this one actually needs to be public

okay so now here on the options UI we go

into the sound manager access the

instance and call change volume okay so

that is going to change the volume then

we just need to update the values on the

options UI so let's make a proud void

update visual

and this one we need to update the text

so up here on let's add once again some

more serialized Fields so text mesh Pro

ugly one for the sound effects text and

another one for the music text

okay we have both these then here the

sound effects text not text

equals and we go into The Sound Manager

the instance

and then we need to get the volume

so over here on the sound management

let's make a function together so a

public float return get volume and we

just return the volume okay so then here

let's get volume except volume is going

to be a normalized value so rather than

showing 0.1.2.3 on the UI let's just

multiply the volume by 10f that way we

show between 1 and 10 okay then let's

just round out this number

and then add the text

so here's sound effects and then we have

the bone okay so that's pretty much it

and up here when we change the volume

let's just update the visual

and let's also make a private void start

and on start let's also update the video

okay that's it pretty simple now let's

do the exact same thing on the music

except on the Music Manager we named it

music manager but over here we just have

an audio Source there's no actual

manager so let's actually make one let's

create new c-sharp script for the Music

Manager let's go into the Music Manager

object let's attach a script and let's

open so here we really just need pretty

much exactly the same thing that we had

so let's just go here into The Sound

Manager and just copy these

so on the Music Manager let's paste them

we need a volume so a private mode for

the volume just like this okay so that

changes the volume except again the

Music Manager this one the music is

constantly going to be unlooping so

after we modify the volume we need to

update the actual audio source so let's

begin by grabbing the audio source audio

source and we just do a pro void awake

and on a week let's grab the audio

source

get the component of time Body Source

okay so we have this and when we change

the volume let's go here and update this

phone okay that's it and let's also

default it to some like 0.3f okay good

then in order to be able to call this

from the option Cy we just need to make

it a single turn so as usual public

static Music Manager for the instance

and we have a public get and a private

set

and then an awake just set instance

equals this okay

so then here on the options UI we can go

into the Music Manager the instance and

change the volume and afterwards let's

update the visual and down here on the

update visual lets you pretty much the

same thing so on the music text modify

the text to say music then we go into

the music manager and get the volume all

right that's it all this should be

working let's just drag our references

so back in the afternoon let's drag

firstly button so the sound effects

button that's this one then the music

button that's this one then we have the

music text that's this one and the sound

effects that's like that okay let's test

okay so here we are the music is playing

and as I click the music is currently

getting louder and louder

and their game I'm using is at max

volume and if I click again no the music

is completely muted alright awesome any

sound effects also work so like this

they should be less leather than usual

okay great so everything works perfectly

except obviously we have one big issue

the options window is on top of

everything

the goal is for the options window to be

kind of a sub menu of the pause window

we want to have an options button on the

pause window that won't bring up the

options window so let's do that let's

first hide the options window let's go

into the game pause UI and over here we

have these buttons let's just make one

more let's put it down the middle this

is going to be the options button

and inside let's modify the text to

options okay

now let's edit this script so we're

going to have another button so this is

the options button and down here we're

going to have another click so the

options button okay

and when this happens we want to just

show the options window so in order to

access it let's make this a Singleton so

public static for the options UI

a static instance

with a getting a private set

and on weak as usual instance equals

this

so over here on the game POS UI we go

into the options UI access the instance

and then call a show function so we need

to make this

so here on the options UI let's make

those so a public void show

and this one as usual just game objects

that active into true

and then we have a private hide

and this set active in two phones

okay we have both these on the other

side we show it and over here on start

let's also hide it okay

then let's also hide it manually so

let's add a button to close the options

UI so over here let's show the options

UI and let's make another button let's

put it on the bottom this one is the

close button

and over here let's just say close

so then here on the options UI just make

another button the close button and down

here for the click event

we go into the close button and we just

call height

okay so that won't hide the window

however remember that the pause window

can also be closed by just pressing

escape if we resume with the hotkey it

won't hide the pause window so let's

also make sure this one hides on the

same thing so we can do pretty much

going to the kitchen game manager the

instance and let's listen when the game

is unpaused so when that happens let's

hide this window

so once again let's do things nice and

clean let's rename this so the kitchen

game manager

and when this happens let's just hide

okay this should work let's just drag on

the references so first here on the

options UI let's drag the close button

and then on the game pause UI let's drag

the options button okay so let's test

and if right away the options window is

not showing the trade and if I press in

this game there you go there's the pause

window and if I can click on options if

there's the options window now if I can

go and close back here back into resume

okay works now if I pause options and

now press on the Escape key and you

better go closes everything all right

great so everything is working fine

however we have one slight issue

the option does work so I can modify

this to change the sound effects and

Music volume so for example let's mute

the music and put the sound effects on

five so I put it like this but now if I

stop playing and I hit play again

and working the options and oh there's

the issue basically that is back to the

default obviously that is resetting

since we didn't actually save anything

so let's save it now in unity the

easiest way to save some data is using

player prefs so let's go over here on

The Sound Manager and when we modify the

volume over here when we do that let's

access the Unity Player prefs and over

here we've got a bunch of set functions

so we can save a float an INT or a

string this one as you can see it takes

a string and a value so this is pretty

much essentially just a dictionary now

for the key as you can see it's a type

string but again we should not be using

strings directly

so let's go up here in order to make a

proper constant so a private con string

let's go with Pro layer

prefs sound effects volume

and let's go sound effects volume

okay we have our nice Center in content

and down here when we set the float

let's use this string and say the volume

okay so that is going to set the float

and now technically Unity is going to

automatically save the player perhaps

basically there are only problems if

Unity somehow crashes in between when

you can't set float and when it actually

saves but if you want to prevent that

from happening you can just go and tell

it to save manually just like that that

won't definitely save it and now we just

need to handle loading so here on awake

when we have this let's go into the play

prefs and let's use get float let's pass

in the same key so this one takes the

key and default value so let's default

it to one F basically the default value

is used if there's no save data on

display prefs on this key so the first

time we run it's actually going to use

this default and this one's going to

return these saved value so let's just

set it on the volume

okay so that's it that's only takes to

save some basic data now let's do the

exact same thing on music so over here

on the Music Manager let's first Define

our private con string for the player

pref's music volume

and this is going to be the music volume

okay we have our string and then down

here when you change the volume layer

press

and let's set the float on this key and

let's pass in the Music Volume okay and

then what's going to player prefs and

actually save it and now appear on the

wake

let's grab the volume

and it's going to be going to the player

prefs in order to get the float on this

key

and default value is 0.3f however over

here on the music again we are not

spawning the sound afterwards the sound

starts playing right away

so let's make sure to set the audio

Source volume to the one we grab from

there okay that's it so like this it

should be working so let's test so here

we are and the music is playing let's

pause go into the options let's bring

the music completely down so let's mute

the music okay the music is gone and

sound effects let's put a note 5. now

let's stop playing and now play again

and going to the menu options and if

there you go the data was indeed saved

and the music is indeed muted alright

awesome so here we have some basic data

being saved and also just quick note

related to saving for this simple game

decisions are pretty quick so I didn't

include any kind of save system for the

actual game data but if you want to know

how to do that I also have video

covering that topic okay so with that we

have our options window working the

volume sliders work perfectly the next

thing we need to add to our options is

some key rebinding so let's do that in

the next lecture

hello and welcome I'm your code monkey

in this lecture we're going to add key

rebinding to our options menu so here we

already have this nice options menu we

can modify the volume of the sound

effects or the music next let's handle

key rebinding okay so first let's build

the elements over here on the UI so

let's create a bunch more buttons but

before that let's actually make some

text on the side and buttons in the

middle so let's create a brand new UI

text

call this move of text

let's put it on the same size as the

other one so these got a font of 24 so

let's put it same thing font of 24 width

and height let's put both of these on

zero and down here anchor it to the left

okay down the middle and with no

wrapping okay so then over here this is

going to be the move up action

so we have move up then we have the move

down move left move right then we have

the interact the interact alternate and

finally the pause so these are all of

our actions so let's just make all of

these

so rename this so this one is the move

down

then this one over here is the move left

this one is the move right this one is

the interact text then the interact

alternate text and finally the pause

text now let's just modify the text on

these so that's the pause

that one is the indirect Alt

then this one is the interact then we've

got the move right

then over here the move left and finally

we have the move down

okay so those are our labels for our

controls now let's just make buttons

over here on the right side so let's

duplicate one of these buttons let's put

it over here and put it on something

like 50 by 50. so this is going to be

the move up button and inside on the

text this is going to be pretty much

just a w okay so we have the move up

then we're going to have the move down

move left move right the interact the

interact alternate and the pause

so we just need a bit more space so

let's move all of these up by quite a

bit let's also move the music and the

sound effects so move all of these like

that okay let's just name all these

buttons so this one

is the second one so this may move down

then over here the move left

then the move right then the interact

button the interact alternate button

and finally the pause button okay those

are on the buttons let's just position

all of the labels exactly where they

should be

okay so here we have all of the options

all of our bindings now in code let's

grab references to all the buttons and

all the text inside the buttons so here

inside the options URL let's add all of

those so first of all for the attacks

we're going to have the move of text

then the down left right and so on so

let you see all of these so down

then over here the left then the right

then the interact text the interact

alternate text and finally we have the

pause text

and for the buttons let's go up here

make all the buttons so they move up

button then they move down button

then we have the move left button then

the move right button then we have the

interact button the interact alternate

button

and finally the pause button

okay so we have all of these references

over here in the editor let's just drag

them so let's make sure we drag them on

correctly so let's do it one by one so

the move up this is the text and

actually it's not that one so that's

already a mistake right there we want

the text from inside buttons

so let's pick up all of these text

objects so let's go into the options so

text inside the move up let's grab that

one then inside the move down let's grab

that one and then left and so on so

definitely make sure you grab the right

ones okay that's on text now for the

button so let's move up button then you

move down

then they move left

the move right the interact interact

alternate and finally the pause button

okay great and just to verify that

everything is working let's give proper

names to these objects

so the move up button text

okay so I've renamed all the buttons so

now over here it's much easier to verify

that we have the correct references so

the sound sound music music and so on so

definitely make sure all of these are

correct otherwise you might go crazy

when things start to go a bit weird so

make sure these are all correct all

right now let's begin by updating the

text inside over here so let's go into

our update visual so we go into this set

the text and now we need to get the

binding text for this binding so for

that let's make that function on the

game input over here let's just comment

this out

then over here on the game input script

let's make a function to get the

bindings certainly we could make

something just to grab this player input

actions but again we don't want the

options UI to know what input system

we're using it should work regardless of

what input system

so we don't want the game input to

return anything of this type instead we

want to make a nice layer of abstraction

so for that let's make an enum to Define

all of our bindings so let's make a

public since we're going to access it

enum call it binding

and over here let's add all the bindings

so we've got the move up then we have

the move down the move left the move

right then we have the interact the

interact alternate

and finally the pause so these are all

of the bindings now let's make a

function to return the binding text

so over here let's make a public we're

going to return a string

let's just name it get binding text and

as a parameter let's receive a binding

okay so now here let's just do a switch

switch on this binding and basically

just match up the enum to whatever

action we have

so for example let's begin with the

interact since these are the simplest

ones

so for this one to get the bindings we

first go inside the player input actions

then let's go inside the player action

map then for the action so in this case

the interact and anything inside we've

got the bindings this is an array of all

of the bindings in our input map we

defined all of the keyboard bindings on

index 0. later on we're going to add

Gamepad bindings but for now we're going

to have the keyboard always on index 0.

so over here going to bindings axis on

zero and let's just do a two string

okay so let's just return this and let's

do a default to return always this one

just like this okay so let's do a quick

unlock to see what this returns so let's

do it over here on the game input just a

debug.log go into there get the binding

tags for the interact

okay so let's test and right away yep we

do see it working so the interact and

The Binding is on keyboard slash e but

we don't want all of this text we really

just want to see the E thankfully the

input system has a really great function

for just that so instead of calling the

general to string let's call to display

string let's see any of this one does

return just easy okay great so this is

the one that we want let's do the same

thing for all of the other simple

actions

so we've got the interact then we have

the interact alternate and we have the

pause so these are all the super simple

ones so just going to interact alternate

grab the binding on zero and for the

pause binding on zero okay so these are

all super simple now the more complex

one is the move it's more complex

because you can see all the others just

have one binding except for the move

over here we have a composite binding so

that's basically a binding which inside

has four separate bindings basically the

way that this works is that when you use

a composed binding all of these are

added to the array so this to the vector

is going to be on binding 0 then the up

is going to be on binding one two three

four and so on then the arrow keys this

one is going to be on five then we have

six seven eight nine and ten let's do a

log just to verify

so here if we do one for the move up

action for this one let's go into the

move and let's print out just the

binding zero let's do a regular two

string let's see what this returns so up

here let's just modify our log to say

the move up okay so let's see any up

index 0 does have the move to the vector

and now if we print the one on binding

of one yep now this one does have the

move on the w

so like I said we can see that all of

these Composites these are technically

inside that one but in terms of that

array it's just a flat array so this one

index 0 1 2 3 and 4. so that makes it

super simple to add over here so they

move up down left right

and let's just do all these

so we have all the bindings and over

here just one two three and four

and set a two string let's call the

display string okay so the binding text

this is all set up so let's go up here

and get rid of our testing code we can

now call this from the options UI so

over here let's do exam with that so

when we update the visual

let's go into the game and put let's

access the static instance let's get the

binding text and this one is going to do

the move up

so that's it this one is going to return

a string

let's write all of them

okay here are all of them so let's see

and if there they are all perfect don't

we SCD EF Escape okay great so the

visual is working now let's end on the

rebinding so let's add a click event

let's go into the move up button

let's go into the on click let's add in

listener and for the enlistener over

here let's make a function on the game

input to rebind this binding

so over here on the game input let's see

public void rebind binding and we

receive a binding

now for rebinding I cover this in detail

in the dedicated input system video

first basically we need to disable the

action map so let's go into the player

input actions let's access the player

and disable it so we need to do this

first then we're going to need to find

the action so player input actions and

for now let's go into the player and

let's just modify the move up action so

we're going to call the function perform

Interactive rebinding

this one as you can see takes a binding

index and if you remember up here we saw

that in order to modify the move up it's

on bindings index one so let's modify

the one on index one

okay so this is the function this

returns an object of this type a

rebinding operation this is a pretty

complex object where you can modify all

kinds of things add a bunch of

limitations and so on like for example

make a key not be able to be bound to

the mouse or something so there's tons

and tons of options you can play with

over here for the simple thing let's

just add an on complete listener so this

one takes in a convex and this will be

called whenever the interactive

rebinding completes

so over here on let's define and Lambda

so we come back and inside we have this

by the way over here this is the same

line of the expression that we saw

previously so exactly the same thing as

this except when we have just one

parenthesis we don't need to add them

okay so like this so then on this convex

we can see all kinds of things like for

example we can see the action that we

just rebound this is going to contain

all the data on the rebind operation so

for example let's print out the path so

let's go into the action

let's go into the bindings

on index 1 and let's print out the path

similar to a debug.log

and there's actually another one so

let's log the path and also the override

path these are two different things

let's see why in a bit we do this and

after we log we also need to rename on

the player action map so let's go into

the player input actions deep layer and

back enable this okay so we're only

going to need these settings on the

rewind action then we can just call

start in order to start the rebinding

process okay so this should work let's

just call this from the options UI so

over here we have the click let's go

into game input instance and let's

rebind The Binding and for this one is

the move up

okay with this let's test okay so here

if I click on the button and I click on

the T key and if there go it did work so

you can see that it print out the

regular path that is w and the override

path which is C so now if I exit out of

the options go back into the game if I

press W nope it does not move but if I

press T yep it does move upwards okay

great so we have successfully rebound

this one key now here just one thing in

previous versions of the input system

when doing a rebind operation you need

to manually dispose of this comeback

otherwise it would throw a memory error

in the recent version that I'm using

here there's no error so it seems

perhaps it's no longer needed to dispose

of the compact manually but still

there's no harm doing it just in case

over here combat dot dispose

okay so with that the key rebinding is

working except we have two issues the

first one is that it's not very clear

that it's listening for an input and the

second one is that the text options also

does not update so it's on both those

first let's add a visual when waiting

for a key press so inside the game

options UI let's create an empty game

object call this the press to rebind

team

let's stretch it out so put it on zero

on everything okay then inside let's add

a UI image

let's put it in black and once again

let's stretch it out

okay now let's also add a simple text

and for text let's say press a key

to rebind as usual let's put the width

and height on zero put it in bold Center

down the middle with no wrapping and

increase the size by quite a bit okay so

that's our super basic window now in the

code we just want to show and hide this

so let's do that and let's actually

begin with this hidden by default so

let's disable this object so here on the

options UI let's add another serialized

film it's going to be a transform for

the press to rebind key transform

so you have this let's make two show and

hide functions

so we show press to rebind key

we just go into that one game objects

and active this one into true

and another one where we set it to

phones so just

hide and set it to false okay pretty

simple let's make sure to hide this over

here on our start okay just like that

and for showing let's show it when we

actually rebind an action so right in

here but since we're going to have tons

of listeners to these events let's

actually make a nice separate function

to handle all of the rebinding logic so

down here let's make a function rebind

binding

we receive a game input.binding

then first we show the press rewind key

and then let's go into game input access

the instance and time to rebind binding

and pass in the same binding

okay so we have this and now up here on

the button event let's just call in this

function okay very simple so this will

work for actually showing the window but

now we need to know when to hide it and

for that let's use something that we've

used a few times in this course but

never directly let's use a c-sharp

donate as usual I have a dedicated video

on them this is basically how you can

define a field or a parameter of a type

which can hold a function it's another

Super useful CCR feature definitely

watch that video to learn all about it

let's go here on the game input and down

here when we have our rewind binding

over here let's receive a second

parameter this one is going to be of

type action this is one of the built-in

dongates it takes no parameters and

returns void so this one is perfect for

a simple comeback just like this one

let's go with on action rebound and

we're going to trigger this right here

after we achieve the convex so we get

the comeback let's trigger this just

like that and let's also get rid of

these testing logs we no longer need

them so just like this

now back here on the options UI so we've

got that and for the second parameter

let's just pass in the function to hide

that window so hi the press the rewind

key that's it again remember we're

passing in the function itself we're not

calling it so there's no parentheses

we're just passing in the function

itself okay so with this let's test so

here on the options let's rebind the

move W and there you go it does show up

to window and now if I press the key you

better go down hides okay great so this

is working but over here the text is

still not updating so over here on the

second comeback instead of just calling

this function we need to call this and

then also call the update visual

function so as usual let's use a simple

Lambda expression to do exactly both

so let's open and close the parentheses

and we do exactly this

so we hide the price of rebind and then

we update the visual okay that's it

let's test so here we are let's rewind

the move down we press on the T key and

there you go we did rebind and it did

update all right great now let's just

apply this to all of the other bindings

so first up here on the buttons let's

set listeners to all the buttons so

let's see move left

actually be moved down

then the move left move right the

interact button

the interact alternate button and

finally the pause button and for the

bindings this one is the fast binding

the interact alternate then the interact

then the move this one is the right

again make sure you don't make mistakes

here you call them the exact same one so

they move down okay so all of it is

correct here

and over here on the player input let's

do a switch on our binding

so Keys move up we do something and now

we could write this code directly up

here and then make a move down and write

a bunch more code that would work but

that would be way too worthy so let's

write our code in a nice clean way

basically the only thing we need down

here is we need to know the actual

action we're going to rebind and we need

to know the action index so let's just

find up here exactly that so an input

action for the input action

and then an end for the binding index

okay and then over here when we have the

switch for all of our bindings we just

set those so the input action in this

case it's going to be the player input

actions player and it's the move action

and for The Binding index

this one is on index one

then we're going to have the other moves

so they move down is going to be on

index 2.

then left and right

these are on index 3 and 4. okay so we

have all these and now for the other

ones

so for the interact this is the interact

action on binding zero then we've got

the interact alternate and the pause

so interact alternate and the pause

and this one is the pause action and the

interact alternate action and all of

them are on finding index of zero okay

so that's good so over here we are

assigning the input action and defining

index and also one thing we need to make

sure to always assign these values

so let's make sure to add a default here

just make sure it always works okay

great so now down here instead of always

accessing the move let's access whatever

is stored in the input action

and for The Binding whatever it is on

The Binding index okay so now this will

work with all of our bindings so here we

are and let's try rebinding all of them

so let's put them over here on the side

so before it move up let's put on T down

on G A on F then D on H for the interact

on y interact jumped on J and for the

Escape let's put it on E okay so all

these Keys have been rebound let's just

make sure they work so here I am moving

with these keys and yep it does work go

up here to interact and do the alt

interact and now the pause and if there

you go everything works perfectly

alright awesome so everything worked

perfectly although again we have the

same issue as previously so all the keys

have been rebound so it's not correct

right however now if I stop playing and

now if I play again

and nope there's the issue the rebinding

was lost so just like with the sound we

also need to save the new state now

thankfully the new input system has a

function that makes that super easy

let's go down to where we are rebinding

things and when we finish rebinding

let's just go into the player input

actions and let's call this function the

save bindings overrides as Json

this one is going to return a Json

string now if you don't know what is

Json go watch my quick video on it

basically it's a super easy to

understand and widely used file format

it's very easy to read and modify it's a

format where it's stored as just text so

let's look at what this says once we

debug down log over here after rebinding

something let's see so here if I rebind

one of these and if there you go there

we have our Json so the override

Bindings that overload the move on this

ID on this new path so basically we just

need to sort this string somewhere and

just like we did with the sound let's

just store it in the player prefs so

first let's define our constant so

private constring for the player prefs

bindings

and let's call this the input bindings

okay just like this

so then down here after we rebind the

king

let's go into player prefs and let's set

a string on the player prefs

bindings

and we're going to save the overrides as

Json

and after we do let's just make sure the

player perhaps is correctly saved okay

so that saves it then let's go on a way

to unload it so over here on awake let's

load that

let's first do a quick test to see if

there's a save so if the player prefs if

it has a king and if it has this key

if so then let's get it so the player

prefs let's get the string on this key

that returns this ring and we're going

to use the string let's just go into the

player input actions

and let's call the function load binding

overrides from Json just like this and

also let's make sure we do this right

after we construct the object and before

we enable the action map okay so that's

really it let's test so here we are

let's rebind the move up to T okay hit

rebound now stop playing now playing

again and you appeared is still rebound

to T alright awesome okay so here we

created a really nice options menu where

we can modify the volume and rebind keys

the only issue that we still have is

that we can only navigate the menus with

the mouse so let's add support for many

navigation with a controller in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to set up

phone controller support for our game

including regular actions and menu

navigation okay so first let's just set

up the controller input I have an Xbox

impact controller connected so let's

open up our player input actions and

over here we have all of our actions and

we already made the move one a long time

ago so let's just add the bindings for

the other ones for example over here on

the interact let's add a brand new

binding let's go into the path and

listen and for interact I'm going to

press the A Button and again here you

can specify just the a button on Xbox

controller or you can use the generic

South button which will mean a on an

Xbox or cross on a PlayStation or B on a

switch or anything else so let's go with

the generic one for the internal

alternate let's add a binding and for

this one I'm going to put it on the X on

the Xbox so the button West

and for the pause let's add let's listen

and I'm going to press the menu which is

the start button okay so these are the

basic inputs let's make sure they work

and thanks to this new input system we

really don't need to modify any code

let's just save this asset

let's wait for the compilation and then

we can do a test so here we are and yep

I'm using my control to move now let's

just wait for the countdown

and go up there and pick up a cheese put

it and slice some cheese yep I can do

that pick up a plate and so on all right

so everything works let's also pause and

yep that also works okay great so

everything works except there are two

issues with the GamePad especially one

with the movement that I only noticed

just now the first issue that we have is

the dead zone right now we don't have

one so if I just lightly touch my

Gamepad joystick there you go it starts

moving automatically in Gamepad games

you should always have some kind of dead

zone to prevent any kind of joy-con

drift thankfully that is super easy to

Zone let's just go into the player input

action so let's go into the move find

the left stick binding

and over here for the processors let's

add one and let's add a stick dead zone

so that's it pretty simple this

basically considers that inputs under

this minimum to be zero and above this

maximum to be one so if you have

joystick drift where when the joystick

is Idle it's always moving by say 0.1

and direction this helps solve that

problem except in our case for a game

we're only using normalized inputs so

actually for our use case let's increase

the minimum by quite a bit I did some

testing in 0.5 Works quite great and the

max that default that is just fine okay

so that's it one problem solved let's

just go ahead save this Ascent now the

other bigger issue that we have is if I

approach a counter and I try and look at

it it's really difficult it tries moving

left and right instead of actually

facing the counter that's because the

logic that we added in a long time ago

that logic to help the character

controller feel better when moving on

diagonals against the counter

that works great for keyboard because

it's digital so it's either moving phone

and left probably right or on the

diagonals

but it messes up the control which is

analog on the player movement if we are

not moving perfectly up or perfectly

down then it's considered a diagonal and

on a Gamepad it's really difficult to

get a perfect just up or just down input

we're always going to have a tiny bit of

either left or right so that's the issue

that we have here and thankfully the

solution is actually pretty simple let's

go over here on to our player script and

let's scroll down into the handle

movement function okay

so we're doing a can move using the

regular move Direction and if it doesn't

work then it's over here that we are

attempting only the X movement or only

the Z movement and for doing that we

made it so we can move if there is

nothing only on the X and if we have any

movement at all on the X so if it is

different from zero basically the issue

here is if the move dear.x is let's say

0.001 that is still different from zero

so it is still going to trigger this

logic so basically let's just widen this

Gap instead of testing literally just

different from zero let's test if they

moved here.x if it is under say minus

0.5 F or if moved here dot X if it is

bigger than plus 0.5 f

so instead of being exactly just on zero

we're only going to consider diagonals

if we are at least moving 0.5 either

left or right so we just did this and

same thing over here except we just test

for this n so we moved here.z and they

move the other dot set okay so like this

it should feel much better on the

GamePad and still work exactly the same

on the keyboard so let's test

so here I am moving around and yep now

it is much easier to just stay around

and look straight at the counter okay so

that's great so I can pick up and this

is all much much easier and the

character is no longer just sliding left

and right Non-Stop okay that's great so

now that this is working let's set

support for rebinding our controller

bindings so over here on the game input

let's do it just like we did for the

keyboard so let's add a bunch more

bindings over here on the enum let's add

the GamePad interact then the GamePad

interact alternate and then the GamePad

pause

okay so we have our bindings then let's

go down and add them to both our

functions so of course the text and then

the bindings so we're here on the text

let's copy pretty much this we're going

to have the GamePad interact then we're

going to have the other two so the

GamePad tracked alternate and the

GamePad pause okay

now for these bindings we're going to

use the same actions so this one is the

interact alternate and over here we have

the interact and over here on the input

actions we saw that we added for all of

them on index 0 we have the keyboard and

on the next one we have all the gamepads

so over here that's literally don't

change for the GamePad let's go into

bindings and access the array on index

one

okay and then over here on the rebind

binding it's going to be pretty much the

exact same thing so let's copy all these

change this to the GamePad interact then

the GamePad interact alternate and then

the GamePad pause some of these all we

need to change is just by an index put

them all on one okay so with that all of

the code over here on the game input is

working perfectly now let's go over here

into our options UI so we've got all of

our buttons so let's duplicate our

buttons let's just go into the

interactive pause and so on let's

duplicate push them to the right side

okay

and just change the name so let's get

into all of them so this one's the game

pad interact button then the game pad

interact alternate and finally the

GamePad Parts okay

also inside let's also rename these

buttons just to make sure the text works

great

and let's also make sure that these show

up behind the press the rebound key so

let's drag them put them above okay so

that's our setup over here on the

options UI now let's go over here on the

options UI script and let's add

references to our buttons and to our

text objects

so let's copy all these the GamePad and

add all these this is the pause the

interact and the interact confident and

then down here the exact same thing

let's add all of these

okay like this now over here let's drag

all of our references so on the options

UI let's make sure to always write the

correct things so the GamePad interact

text the interact alternate text and the

pause button text and then the buttons

themselves so the pause button interact

alt and the interact button again make

sure you always drag the correct

references so check and double check

make sure everything is correct okay

then over here for our code let's first

handle the text over here

so the text for all these

so the GamePad interact text then the

GamePad interact alternate text and

finally the GamePad pause text and we

just go the game file pause the GamePad

interact alternate and the GamePad

interact finally over here on the

buttons let's do the exact same thing

so Gamepad interact interact alternate

and the pause

okay so we added everything let's do a

test and see if everything is working so

over here let's pause the game go into

the options and for the interact let's

modify this one instead of a and let's

put it on B and yeah there you go it did

go so let's close let's resume and now

let's see so if I approach and I press a

nothing happens Press B and there you go

it does interact okay awesome so the

rebinding is all working perfectly

except we have another obvious issue

I can pause with the GamePad however now

with this pause I cannot click on any of

those buttons and if I go back to the

main menu

over here I also cannot do anything with

a controller so at some of that the

first step is on the event system object

look at how it shows us this warning

basically if we're using the new input

system we should be using a different

input Handler here thankfully this is

super easy we just need to click on this

button and yep that's it it

automatically sets it up now the way

that this works is by pre-selecting

buttons in order to better see which

button is selected we should probably

add a more visible color let's go into

our pause window so for now let's hide

over here the options UI show the pause

window and we have these three buttons

let's select all of them

and over here on the right side on the

button we can see one option for the

selected color

so instead of being white which is going

to be really difficult to see let's put

something really visible so let's say

like a bright green okay like this

let's do the same thing for all of the

buttons on the options UI so let's show

this one and find all the buttons so

we've got all of these ones down here

and these three ones up here and let's

do the same thing so on the selected

let's put it all on my screen okay so

all the buttons have a nice selected

color and just like this if we test and

if I pause the game

and right now nothing is selected so

right now I cannot do anything with the

controller however if I press over here

with the mouse on this button and then

let go once outside the button yep look

at that now that button is selected so

now as long as that one is selected now

if I move with the mouse pad yep now I

can navigate through this menu and if I

press on a yep I can essentially click

that button so that's great basically

all we need is to make sure that we

select the button as soon as the pause

menu shows up so let's go over here on

the game pause UI script and then over

here let's go into the show function so

when we show this window when we do

let's go into the resume button and just

call the select function this will make

it selected so that's it and with this

if we test and now here with the game

playing if I pause whilst pressing the

button on the GamePad and if they go

down and selected and now I can select

any option okay that's great so now it

works fully with just the GamePad except

now if I go into options yep now you can

see that the button that is selected is

on the options one over there on the

background so let's also make sure to

select a button on the options as soon

as the options window shows up so over

here on the options UI let's go into our

show function

and let's just select the sound effects

button and just console it okay let's

test so here let's pause go into options

select any of the Lego that did work

okay great except we have another issue

as I move up or down over here on these

buttons you have a look at that some of

them are a bit strange like for example

over here on a I'm moving up and look at

that it actually selected the resume

button behind it so as we are moving up

or down we are actually selecting

buttons on both menus that's very

strange basically what is going on is

that since both windows are visible the

game is trying to guess which button we

want to select basically what is

happening is Unity is trying to use

automatic navigation if we select the

button so let's go for example let's

hide the options and show just the game

pause okay let's select one of these

buttons and over there on the button

component we can see navigation is set

to automatic and we have a button to

visualize and if we click on that yep

over here we can see all kinds of arrows

for example we we can see one over here

on the options that seems to be going to

some button in there that is going to be

the button that is showing over there so

if we move down from the options we're

going to end up over here on the

interact alt button now usually the

automatic navigation actually works very

well the only reason why we're having

problems is because we have both windows

active at once one solution to this is

to make the navigation explicit so let's

hide the options here and over here on

the resume on the navigation instead of

automatic let's put none and then let's

select explicit and if now we have our

own four Fields so we can decide which

object gets selected when we are here

and we move up down left or right so for

example here we would drag for the up

going up we could go into the main menu

so we will drag that button and going

down we could drag the options button so

that's one solution just add the

explicit navigation to every single

button or another simpler solution is

let's leave this one on automatic and it

said we're just going to hide the pause

window once we are in the options window

so over here on the game pause UI let's

see over here we are showing the options

you Ai and when we do let's just call

hide on this so we are going to hide

this window when we show the options and

then on the options we want to know when

the options closes so that we can show

this one again so over here on the show

function let's receive an action this is

what we're going to do when we close the

options let's call it on close button

action

and let's store it up here so let's

store

a simple and private action for this

okay so we have this and then down here

when we have our show function when we

have let's set this equals this we store

this and then we're just going to run

this action whenever we click on the

close button so let's go over here the

close button we've got that one let's

hide the options window and Trigger this

action so now we need is over here on

the game plus UI let's pass in and

basically when we close the options UI

we want to show the POS UI okay so let's

test so here we are let's pause the game

okay let's go into options and open it

and if there go it only shows the

options and over here moving up or down

works perfectly and moving left and

right also works perfectly

and now if I want to go back let's go

into close press it and there you go

back into the pause menu

all right awesome so everything is

working perfectly now the last thing we

need is over here on the main menu so

let's do the same thing first let's open

up the main menu scene

let's save the changes okay and over

here let's begin by doing the same thing

on the event system so let's replace it

okay great

then let's go inside our canvas inside

main menu y let's select our buttons and

once again let's modify the select color

put it on my screen all right and since

over here we only have one menu we could

set a test selected over here on the

main menu UI script

that's one option or we can just go into

the event system and over here on the

event system there's a film for the

first selected so you can just drag the

play button and that will automatically

make it the selected one so it says and

yep the play button starts off as

selected and I can move up or down

and if I press a button yep there you go

here I am playing the game I can pause I

can resume go back to the main menu and

so on all right awesome so here we have

the final thing we needed to make our

game fully playable with the GamePad

thanks to how the input system works and

the menu automatic navigation this was a

pretty simple task for this our game is

pretty much completely done however the

next lecture is also one of the most

important lectures it's all about

publish so let's do that in the next

lecture

hello and welcome I'm your code monkey

in this lecture we're going to add all

kinds of small things to polish our

power game if you are regular on this

channel then you've certainly heard me

say that polish is what separates good

games from great games so as you build

your own games make sure you don't

neglect polish here let's add a bunch of

small tiny things that will make a big

difference in the final game let's begin

with a very simple very visual one let's

just add some ones to our map and first

let's just hide our canvas so that it's

not blocking our view so again over here

we can use the buttons on the hierarchy

to hide it okay great

so let's add some walls and for that

let's create a brand new 3D cube let's

name this a wall let's put it quite a

bit thin so over here on the scale for

the X so let's put it 0.25 then on the

one let's put three so something like

this then we modified Z so let's put it

over here on the side right next to the

counters okay so that's the wall let's

just stretch it out One Direction and

the other one okay so that's our basic

one

now when you included project files

there's a nice one material so let's go

over here into assets under materials

and you appeared as you want material so

let's just drag it and use this one and

if there you go it's just a nice simple

gradient this is also an example of how

you can take something simple and make

it a bit more interesting if you look at

this material the base texture is really

just this it is literally just a simple

vertical gradient texture and then with

the color point to it and looks pretty

good okay so this dual let's put the

wall on on three sides so let's

supplicate this so just select and press

Ctrl D 2.8 let's put one on the other

side so right there right next to the

counters okay and finally the one there

so Ctrl D to duplicate it let's push it

over there on the side and rotate it 90

degrees

and let's put it just like that let's

just scale it to get to that end and to

get to that end okay so we have our nice

walls but over here if we're playing the

game we can still see the floor on the

outside that looks a bit ugly so let's

fix that

let's create another object and let's

create a 3D object another Cube and for

this Cube let's put it over here on the

side and this one let's use the black

material so again in the included assets

there's this nice black material there

you go it's completely black nothing to

it

so let's just use this as kind of a

Hider so let's just scale it quite a bit

and lift it up

okay so there it is a black material

right next to the wall and let's put

another one over here on the left side

and just like that

you can also put another one on the back

there even though I don't think the

camera can see that part but still let's

put it so just put it like that and

stretch it out okay that's good by the

way over here on the outside it doesn't

have to be perfect doesn't have to

perfectly match the camera is never

going to see that position so it doesn't

matter it only matters what the camera

can see and if we pull it like this and

if they're yellow now that looks quite

nice if we want over there we can get it

together just a little bit and we can

also move the camera forward a tiny bit

so over here on this one let's push it

just a little bit to the left okay and

now in the virtual camera

let's play the game

and now here if we want we can push it

up a little bit something like this so

let's put it on this set so let's copy

it stop playing the game and let's paste

it just like that

okay so here's our game and as you can

see with just this one tiny chain just

adding some walls and a nice black

outside just with that it already looks

so much better than having some counters

in wide open space now for another

simple one let's add some nice particles

while the player is moving

so in the included assets if we go

inside the prefab visuals over here is a

nice one for player moving particles

this one as you can see is a particle

system so let's drag it over here into

the world see what it looks like and as

you can see by default it's actually not

spawning anything so I can make sure

that this one is running and nope

nothing is spawning so this is actually

set up in a really interesting way is

that instead of spawning particles all

the time it only emits while moving so

if I click to move this object there you

go the particles start emitting and if I

stop they stop so this one is definitely

perfect for a player particle system the

way this setup is over here on the

emission on rate over time it is set to

zero so it doesn't spawn anything

automatically and it only has over here

the rate over distance so as it moves

it's going to spawn that number of

particles then the other settings

they're all pretty basic so there's some

gravity so they fall down just like the

stove counter particles simulation is

over here on space so that as I move the

particle stay behind this is important

if I were to put that in local and I

move it around look at that this is not

what we want we want the particles to

essentially stay behind instead of

following this transform so that is why

this change is super important if that

one is set to whirl and as I move yep

the particles stay behind okay great and

the other property is around pretty

basic for the shape it's a cone pointing

upwards then for the size of our

lifetime again just a basic curve

constantly becoming smaller and smaller

and down here on the renderer instead of

rendering your quads actually rendering

a mesh and it's rendering a sphere mesh

so that's just so that it looks a little

bit better I think than just having a

Sprite particle okay so that's it so in

order to make this work really all we

need is just attach it to the player

so let's find the player make this

object a child of the player game object

and again let's also make sure to set

all of this to zero so the position on

zero zero and zero

and there you go just with this that's

all we need if we test here we are

stopping there are no particles and as I

start moving if there you go some nice

particles around the player okay great

next let's add a pretty obvious one some

kind of mini tutorial we want a window

to show the controls and the goal of the

game and wait for the player input

before we start the countdown

so for that let's go into our canvas so

let's show our canvas and inside let's

create an empty game object called the

tutorial UI

let's drag this one above the game pause

window so that it shows up behind it

let's double click to center it and

let's press on the 2D button to go into

2D mode okay let's also hide those two

windows so you can actually see what

we're doing so outside all of these okay

great

now this one first of all let's stretch

it to occupy everything so put zero on

everything okay then inside let's make a

UI image for our background once again

let's stretch it put it like this

and for this one instead of black like

we've used for all of our Windows let's

actually leave it on white put it on an

alpha something like half so something

like this just to be a bit different

then on top of this let's make another

image so let's make another UI image and

for this one instead of stretching let's

give it a size so let's put it on 1280

by 800 and for the image I created a

nice image for the tutorial if we go

inside the assets and then inside

textures yup here is a really nice

tutorial image

so let's just go ahead and use it so on

the image let's drag it all right

there's our nice internal image so this

has a pre-based tutorial so the recipe

is coming from the customers then the

player has to prepare the correct

recipes and deliver them on a plate on

the delivery counter so just a very base

tutorial and also over here it's very

important for the player to know how to

actually play the game so there are some

labels for the controls and now we're

going to dynamically add some keys on

top so let's do that let's create an

empty game object call this the king

let's put it on a size of 40 by 40 okay

now let's go inside and inside let's

make an image let's name this the

background

and for the Sprite let's go with the

included Circle so default Circle

and for the size let's stretch it occupy

everything put it on zero zero zero okay

there's our nice key

so we have the background and for the

background let's actually make it just a

little bit darker

and let's also add just a nice shadow so

maybe three minus three and let's also

make a nice upline

let's put it on two by two

full Alpha so something like this just

to be a nice one maybe one by one okay

so that's just the visual and then on

top of it let's add a text

and this one's essentially going to be

the king so let's put a key for the

width and height let's stretch it to

match the parent size okay then for the

phone here let's go with maybe just say

20 let's put it Center down the middle

and also let's put it on bond okay so

that's our nice key indicator

so this is our key and we're going to

have the movement so the movement on the

keyboard is going to have four keys so

let's just implicate so one two three

and four Keys okay then on the GamePad

that one is actually not rebindable so

let's put this one as static

so let's just go inside inside the text

and just say left stick and let's lower

the font size so that it fits in there

okay great

then for some more keys

we're going to have the interact action

then the interact alternate

and finally the pause action

then let's just duplicate these to be on

the other side

okay so these are all of our keys now

instead of having key one two three this

is very difficult to understand so let's

give it some proper names so this is the

key move up then we have the key move

down

then the key moves left then the key

move right

then this one is going to be the key

Gamepad move

then we have the key interact

the key interact alternates

the key pause

this one is the key Gamepad interact

alternate

this one is the key Gamepad interact and

finally the key Gamepad pause

okay all of these and since we're going

to drag references to the text objects

let's also give those a name

so just copy drop it with text

just like this

okay so those are all the names so

everything is nice and organized okay

great now let's make the script to run

this so our tutorial UI let's go down

into our UI scripts create the brand new

c-sharp script for the tutorial UI and

let's attach the script okay

so first let's drag references to all of

our keys we only need the text so let's

do a serialize field of type text mesh

Pro U going again never make the mistake

always use the ugly one if we're working

the UI so the key move of text

so let's add all of these

okay these are all the references then

over here let's drag on and make sure to

drag the correct ones

okay let's double check to make sure all

the references are correct okay they

don't seem correct all right great and

then over here only to pretty much

exactly the same thing that we did over

here on the options so we need exactly

this so let's copy this and over here

and let's do just that

let's see a private void update visual

and on this one let's do pretty much

this so the key move up text

I know this one you get binding text to

move up yep let's just do all the others

okay so those are all the bindings

that's great now let's go over here on a

proud void start and on start let's

update our visual all right and also

let's make sure this updates just in

case the player rebinds something from

the pause menu once the tutorial is

still visible

so we just need to know when that

happens so let's go over here onto the

game input and make a nice event so

public event even Handler let's call it

on binding rebind

okay we have this event and down here

when we have our rebind binding function

we do this we rebind and over here let's

invoke this event

okay just like this

so then on TTR only y let's go into the

game input the instance on binding

rebind let's listen to this event and as

always let's rename this so let's put a

game input okay when this happens let's

simply update the visual

okay that's it pretty simple so let's

test and see if the inputs are correct

and if there it is we do see it correct

so we've got ones we've got e to

interact F and over there we've got the

GamePad okay great so all the buttons

are correct all that's left is the show

and hide so over here let's make the

usual two functions so product void show

and a proud boy in Hind and for these

game objects set active and this one is

going to be into false and this one's

going to be true okay

so for show up here on start let's

actually show it by default even though

it's actually already going to be shown

but still okay then for the hind this

one we want to hide when we press the

interaction

however when that happens we don't want

just this window to hide we want the

kitchen game manager to change the state

so we're here on the kitchen game

manager we currently have the waiting to

start and that one actually has a timer

so we count down the timer and then we

start whereas right now we want it to be

based on player input so let's modify

this to not be based on timer so let's

just get rid of this timer

and now let's see all these errors so

I'm waiting to start we are not going to

count down any timers instead let's

listen to the game input so game input

let's listen to the on interact action

event and rename this to the game input

okay so when we have this event when the

player presses the interact action let's

check if the state if this one is on

waiting to start

if so then let's modify the state so

let's go into State and we're going to

go into the countdown to start and let's

trigger the on state changed event

okay so that's it so we're only going to

change it on the player input and

nothing over here on the updates then

for hiding the tutorial over here one

approach would be to listen to the

interact action and hide it but I think

it makes more sense for this to only

listen to the kitchen game manager state

that way if we wanted we could also

modify how this one changes the waiting

to start

so let's listen to distinct over here on

tutorial we want let's go into the

kitchen game manager the incense and

let's listen when the state changes

so here we are going to check if the

kitchen game manager instance if it is

on the countdown to start active so if

the countdown is active then we're going

to hide this

okay so that should do it now let's just

do one more small thing the delivery

manager is currently spanning a recipe

whilst we're still reading the tutorial

that's not quite right

so let's go over here on the delivery

manager and right now this one starts

off at 0f and starts counting it down

right away

instead of only doing it like this let's

just make sure that we only spawn a

recipe if the game is playing so that's

super simple over here kitchen game

manager instance is game playing if so

then we are going to spawn a recipe and

let's do the same thing on the points

counter so let's go in the plates

counter

so here we are on the plates counter so

we count on time responsive lights but

let's also make sure we only spawn

plates if the game swing

okay so with all of this let's test and

right away here we are we can see our

nice tutorial teaching the player how to

play okay great here we've got the

controls everything and we're currently

waiting for an interaction we can see

over there plates are not being spawned

and recipes are also not being spawned

but as soon as I press the E key

and if there go the countdown starts

playing and we've got everything else

any up there you go the game starts and

after a while yep we've got plates and

we've got recipes alright awesome so

next let's publish the countdown visual

right now it's pretty basic it's just a

static number so let's add a nice

animation to it let's go inside the

canvas let's find the countdown UI so

the game start countdown okay

so here it is we just have some basic

text now let's go into the main game

object and let's add an animator

component

then let's create a brand new animated

controller so let's create a new down

here an animated controller for the

countdown UI over there let's assign

this controller okay now let's open up

the animation window so window animation

open up the animation window okay let's

create an animation clip and over here

on let's name this the countdown UI

number pop-up okay that's great now for

making the animation we want to

basically make it shake and also make it

fade away so one very useful component

is the canvas group so over here once on

the parent let's attach a canvas group

component this one is a really useful

component in this case the main benefit

is it let's just easily animate the

alpha so let's go ahead and turn on

recording let's go into the frame just

before one second so let's go into 60

frames because we are on 60 frames per

second over here let's record the normal

keyframe so let's modify the scale on

the tiny bit just to record it and let's

reset it back to one okay just to record

the keyframe then for rotation let's

rotate on Z then put it on zero again

just record the keyframe okay great so

now we can go back into the first frame

and over here let's first make it

smaller so for the size let's put it on

0.6 then let's rotate it to the left so

let's put 17 over here on the set

rotation okay like that now let's move

up by just three frames so on frame

three over here let's make it quite a

lot bigger so let's put it on 1.3 and

let's rotate it to the opposite position

so -17 okay that's great that's a nice

start now let's put it on frame 10 and

over here let's set the rotation to zero

and for the scale put it on 1.1 okay so

now finally over here on frame 50 let's

set the alpha onto one and then on one

second let's put the alpha zero okay so

let's preview and if they go a nice

simple animation okay so that was great

now we just need to play this when the

countdown happens so let's stop

recording let's go inside the animator

controller so here it is we've got our

number pop-up and we basically just want

to play this animation whenever we want

so let's put it and make a transition

from the any state onto the number

pop-up on this transition let's make

sure we have no exit time and for the

settings over here for the duration

let's put it on zero so that it's

instant okay great now obviously we need

a condition so on the parameters let's

create a brand new trigger call this the

number pop-up let's select that one and

Trigger it on this trigger okay great so

now for handling this logic here we have

the usual question

so do we put this visual Logic on the

same UI script or do we separate the

animations from the UI for me I find

that UI is usually part of the visual so

sometimes I like to mix the two and

sometimes I keep them separate it really

depends on a case-by-case basis this

visual is so simple and so connected to

the actual UI Logics over here let's put

them together so let's open up the game

start countdown script and over here

let's first grab the animator so private

animator for the animator and on private

void awake let's just get the animator

and just get the component of type

animator okay so we have the animator

now we basically just need to keep track

down here where we're modifying the text

we're doing this on every update but now

we need to know when this number changes

so let's basically just keep track of

the current number and the previous

number so first of all over here an end

for the countdown number

and we're going to get this so this is

our countdown number and over here we

set it to string

okay and we just need to use a different

function so instead of Cl lets you cl2n

just to convert the output into an

integer okay great

so we have the countdown number now we

just need to know if this one is

different from the previous one so let's

go up here let's define a private tint

for the previous countdown number

then when we go down here we've got the

current countdown number okay then just

check if it's different

if it is different from the current

countdown number if so then let's update

it so the previous one becomes this one

and now let's fire off the animation so

let's go into the animator and set the

trigger and again we don't want these

strings so let's go up to the top of the

file make a private cons string let's

call this the number pop-up

and number pop-up

okay so we have this end down here we

just set this trigger okay so that's it

pretty simple and just for fun let's

also add a nice sound effect so let's go

over here onto The Sound Manager and

let's make a function to play sound so

just like we did over here for the play

footstep sound let's make another one

for this one let's go and play countdown

sound and for this one let's not receive

a volume or position and we just play

let's say just the warning sound so just

down on Vector 3.0 and with the current

volume

okay so we have this function and then

down here just going to sound manager

instance and play the countdown sound

again we could refactor this code to

separate the Yuan logic from the

animation from the sound that is one

approach and sectionally one thing that

we're going to do in the next polish

stage but this one is also a possible

thing since the UI is only so directly

connected to visuals okay so with this

let's test so here in the options let's

just make sure that we have our sound

effects so let's make sure they are

playing okay great now let's go ahead

and play and there you go we have our

nice countdown number and there you go

it looks great so it looks great and

sounds great alright awesome as you can

see just by adding a simple animation

and some simple sounds that already

looks so much better now the next thing

we want to publish is on the stove so

let's go into our stove back into our

counters back into 3D and zoom in over

here okay let's also make sure that we

hide the canvas just so we can play

around this all right great so there's

our stove and for this we want to add

basically a warning icon on any nice

sound when the meat is about to burn so

let's go inside the stove counter prefab

okay so now inside of this we already

have a nice generic progress bar UI and

like I mentioned if you want to get some

more custom Behavior you can combine a

generic bar like this one with some

specific components so that's exactly

what we're going to do right now so over

here let's create a brand new canvas as

usual let's make it a world space canvas

for position let's put all of this on

zero

let's just lift it up by a bit so set it

on a y of three okay great then let's

add our super useful look at camera

component and make it camera phone okay

now inside let's go ahead create a new

image let's put it on a size of 0.5 by

0.5 okay just a nice square and for the

Sprite there's a nice warning image in

the asset so it's this one here we have

the warning okay great basically we want

to show this when the meter is about to

burn so let's make a screen to run this

and on the canvas let's give it a proper

name so let's call this the stove burn

warning UI

okay so let's make this crypto render so

when you c-sharp script with the exact

same name and over here let's attach a

script okay great so now the first thing

that we need is obviously a reference to

the stove so let's make a serialized

film private for the stove counter for

the stove counter

okay here in the editor let's drag the

reference of the sub counter okay great

so now we basically just need to know

when the food is about to burn and for

that we can actually listen to the on

progress event so let's do a private

void start and on start let's go into

the stove counter and let's listen into

the on progress change event okay so we

have this one

and recently we're going to want to show

this element so let's find a bone show

we're going to want to show this when

the progress normalized is above a

certain amount so let's define a float

for the burn show progress amount and

let's say 1.5

so on this one we show it except

obviously we don't want it to be shown

when the food is just cooking we only

want it to show when it's about to burn

so that means we also need to check the

state on the stove counter so let's make

a function to check if we are in the

state that we want so we're here on the

stove counter let's go down to the

bottom

and let's make a public bowl is fried

and over here we just return if the

state equals state DOT frame

okay that's great so now here we're

going to show if the progress is above

0.5 and the stove counter is on the

Fright state

all right so that's the logic that we

want then we just want to show our

height so let's make the original

functions private show and a private

void hide

and just do game objects and active into

either true or false

and over here if show then let's call

the show function and if not let's call

the Hide function and of course on start

let's start off as hidden okay that's it

let's test just over here in the editor

make sure the reference is right and

let's save the prefab go outside and hit

on point and yep right away there's no

element okay great now I place it and it

won't cooking there's no element and now

once it's on the halfway point for

burning and if there you go we've got a

nice warning okay awesome so now that

this is working let's just add a nice

animation so once again let's go inside

the stove counter and on the burn

warning UI let's add an animator

controller

then let's actually create the animated

controller so let's create a brand new

animated controller

for the stove burn warning UI

then let's assign it okay and over here

on the animation window let's create an

animation

let's put it on the same folder and call

it

for this one let's say flash we're going

to make it Flash and then again for

making it flash let's use the same

component that we used a while ago so

let's add a canvas group so here it is

now we can play around the alpha so

super useful although I should say that

at this point since we just have a

single image we could just record a

change over here on the alpha for the

image itself however one place where

this component is super useful is if you

have multiple images so if over here I

duplicate this one and I put it off to

the side if I change the alpha on one of

them then obviously it only affects that

one but if I go over here and I modify

the canvas group that changes the amp

for both of them so if you have a group

of images then using the canvas group

makes it super simple so anyway so here

we have just our image let's go ahead

and record and let's say we start off on

Alpha zero then after 10 frames going to

Alpha One and after 20 frames back into

an alpha of zero okay so that's it a

super simple very basic animation we

don't even need analogic since we just

want this animation to play Non-Stop so

that's great that should be working now

let's add some sound so for that we

could make another script but already on

the stove counter we already have a nice

sound component so let's open up this

grip the stove counter sound so this is

basically where we're playing or

stopping the sizzling sound so over here

we can just add the warning sound we're

going to play the sound just like we

have over here for the burning UI so

let's actually copy these same

components and over here let's face it

so for this one instead of show let's

give it a proper name so play warning

sound except it's not on say change so

let's actually listen to the other one

so still counter on progress change

let's listen down and it's on that one

that we use this

Okay so we've got that one and then for

playing the warning sound we're going to

want to basically play it every certain

amount of time

so let's make over here a private void

update and an update let's just Define a

private float for the warning sound

timer

and so down here we just count down as

usual time dot Delta time

and if this one is under zero

if so then let's reset it so Define a

certain maximum

let's say 10 times or maybe just five

times per second that should be good so

we have this but obviously we only want

this to run if we should be playing the

warning sound so let's actually save

this one up here so probably won't for

these play the warning sound and then we

set it on this one

and down here let's just go and we're

only going to run this if play the

warning sound then we're going to run

our timer logic all right and then over

here all we need is to play that warning

sound

so let's actually go into The Sound

Manager and just like we added the

countdown sound let's add another one so

let's say the play warning sound and for

this one let's receive a vector 3 for

the position and we're going to play the

warning sound on this position so now

over here on the stove counter let's go

into The Sound Manager the instance and

let's play the warning sound and pass in

the stove dot transform that position

okay that should do it so we now should

have a nice warning sound and over here

we should have a nice animation on the

burn warning UI so let's see both those

okay so let's pick up some meat and drop

it and right now it's cooking okay great

and once it gets a halfway point

if there go now we have a nice warning

sound all right awesome let's just add

one more tiny thing let's make the bar

itself also flash red when we're about

to burn so once again let's go inside

the stove counter and on the progress

bar UI let's add a nice animator and

let's go ahead and make one so let's

create a new animated controller for the

stove burn flashing bar

let's go ahead and assign it so it's the

one on the progress bar let's add the

stove burn flashing bar then on this one

let's create new animation let's go

inside the assets animations let's make

one and just call it idle for this one

we're going to want the exact same color

as the normal color so let's go into the

bar and set the color just save a

keyframe over there okay so that's what

we want now let's make another animation

so let's stop recording and let's

actually duplicate this one so duplicate

it and for this one name it flash now of

course we need to add it to the animated

controller so let's go over here and

drag it on top okay now for the

animation let's select the Flash and for

this one let's go ahead click on record

let's start off on this one and after a

few frames so let's say maybe after 10

frames let's Flash in red and after 20

frames let's copy paste the same frame

okay so that's our nice flashing bar now

let's just set it up so let's go into

the animator and over here we're going

to have a transition from that

deformation form flashback now all we

need of course is an animator to control

this so let's make a new animator

parameter let's make it a Boolean and

call it is flashing and again make sure

to be careful with cane sensitive

okay so from idle into flash let's go

ahead remove the exit time for the

duration make it instant so zero and for

the conditions when that one is true

okay great and for going back once again

same thing so instant and let's make the

condition when it's false okay that's it

super simple now let's make a script to

run this so let's go ahead create a

brainy sharp script for the stove burn

flashing bar UI let's go ahead and add

it to the bar so that's the flashing bar

UI okay over here let's do pretty much

the same thing that we did on the other

one

so let's go over here onto the stove

burn warning UI I might actually copy

exactly this so let's go on this one and

paste this one then back here in the

editor let's drag the reference to the

self counter and over here the logic is

going to be very very similar so the

only difference is we have an animator

so the animator and we're going to grab

it on private wide awake and later get

component of type animator

so we have the animator then let's

define the parameter so private con

string

for the is flashing

and let's set it is flashing okay we

have our parameter and now down here

instead of showing and hiding we'll just

go into the animator in order to set a

ball

and the bone will be the is flashing and

let's set it based on show so either we

show or hide and we actually don't need

these functions and by default of course

let's leave it on false okay so that's

it super simple Let's test just make

sure to save the prefab and hit on play

okay let's go ahead and cook so let's

pick it up and drop it alright so it's

cooking let's wait for it to be burning

and as soon as it gets there yeah there

you go we've got a nice warning a nice

flashing bar and a nice sound effect so

all three warnings making ourselves much

more polished alright awesome now just

for balancing let's play around the

timers so let's go into our script ball

objects on the frying rest BSO let's

make this one take five seconds

then on the burning recipe for this one

let's make it take six

and finally let's also add another stove

so let's take our self counter duplicate

the prefab let's put it over here so

rotate it to the side and let's get rid

of this one and put this one right in

there so on 7.5 0 and minus 1. all right

so we now have two stoves I can put one

cooking put another one and I can start

cutting down some cheese start cutting

and before they start to burn what's

actually here there you go that one is

about to burn so let's pick it up

quickly and that one is actually gonna

burn but I got it okay great all right

awesome everything's working great now

for one more polish element let's make a

nice visual when we deliver either a

correct or incorrect recipe I think it

wouldn't look good as a warm canvas on

top of the delivery counter so let's do

that let's over here find the delivery

counter let's go inside the prefab and

now in here let's create a new UI canvas

let's name this the delivery result UI

and as usual let's make this a worm

space canvas so put it on worst face

and for the position let's actually lift

it up and then we're going to make it

look at the camera but just like this it

might actually go inside the wall so

let's put it over here to the side a

little bit so let's put it on this

position so on the X of minus 1.6 on a y

of three and on a z of 1.2 okay that's

the position so right there that is

going to be unlocking at the camera now

inside let's create a new UI image it's

going to be our background and for the

size the width and height let's put it

on 2.2 by 0.9

okay that's our background for the

Hunger let's tinted in a nice green so

let's put it something like this

then let's also add a nice outline let's

put it on full Alpha and for the size

let's put it on 0.1.1 then let's also

add a nice shadow component for this one

leave it on half Alpha and let's put it

on 0.2 and minus 0.2

okay so that's a nice visual now on top

of it let's create a new UI text let's

call it the message text and for the

message we're going to say something

like delivery and then underneath

success let's put it on a width and

height of zero let's put it on a super

tiny font so let's say just 0.25 let's

put it in bold and put it down Center

and get rid of wrapping okay that's it

let's just push it a little bit on the

left side so on minus 0.32 on the X okay

and now next to it let's make another UI

image for this one call it the icon

image let's put it with a size of 0.5 by

0.5 and put it over to the right side so

on an X of 0.7 okay and now for these

Sprites including the assets are too

nice sprites so there's a nice cross for

when we get it wrong and there's a nice

tick okay so that's the setup that we

want now on the delivery result UI let's

go ahead add our own look at the camera

component and for this one let's go

different so instead of the camera four

let's go ahead with the unlock at

inverting so there it is this is our

setup now let's make the script run this

so let's go ahead create the new UI new

c-sharp script for the delivery result

UI let's attach the script and open okay

so now here on let's make serialized

films for our elements so a serialized

film

first of all for the background image

and this is actually going to be a Type

image image inside in the engine.ui okay

our background image then we're going to

have another one for the icon image and

we're going to have another one this one

is a text mesh Pro e GUI for the message

text

okay let's save okay so let's drag the

references to the background the message

text and the icon image okay great and

over here let's listen when a delivery

is delivered so let's make a private

start let's go into the delivery manager

the instance and we have all of our next

events so we've got a success and a

field so let's listen into both them

so both the success and on the recipe

failed let's listen to all these and as

always let's write good point code and

rename this so the delivery manager on

recipe success and for this one is the

on recipe failed

okay we have both of our events

so over here it's actually going to be

very simple we just want to play around

the text the icon and the background

color so for example when we fail let's

go

and we want to set the background image

to about a red so for defining the

column let's actually go here and Define

a color for the success color and we're

going to have another one for the failed

color

and then for the Sprites let's also have

that so Sprite for the success Sprite

and another one for the failed Sprite

okay those are on the elements so we're

here in the editor let's just set them

so for the success column let's actually

use the exact same color by the way

here's a quick tip if you go up to film

for example like this one on the color

you can right click and copy and then go

into delivery results and over here

right click and paste there go the

perfect color then for the final color

let's go with the red maybe a bit darker

and also importantly make sure you set

the alpha to phone okay so we have a red

nice and like that okay then the success

Sprite this one is going to be the tech

and for the fail this is going to be the

cross okay those are all of our elements

so over here when we fail let's go into

the background image and set the color

and let's put the fan color then for the

icon image let's set the Sprite to the

Fey on Sprite

and for the message text let's set this

one for delivery and then failed

by the way this backward slash n this

means a new line so we're going to let

you set the text on this one so it

essentially means that it won't write

delivery then new line and then failed

underneath just make sure you're using

the Packer slash and not the forward

slash so use the backwards one there you

go there's a new line okay so that's the

on recipe film and now on the recipe

success let's use the success color the

success Sprite and over here the

delivery success okay so that's great

that should be working now just one more

visual thing let's add a nice animation

so just like we did previously let's go

over here over here and let's add an

animator component

let's create an animation for this one

for delivery result UI so let's go up

here create a brand new animated

controller for this and let's go ahead

and assign it so delivery result UI all

right now let's make an animation so

this delivery result UI let's call it

just pop-up and for this one let's do

just like we did for numbers so let's

scale and rotate it however if we rotate

that's actually not going to work that

is because we have the unlocked camera

and this one is already going to be

setting the rotation so we would end up

with this script finding the animator

for the rotation so that would mess

things up however one nice and simple

solution to this

basically we just put this inside

another game object so let's create a

new game object and let's put it inside

what's an empty game object for the

delivery result rewind then look at the

camera

so we have this one now the reason why I

created it inside is that so over here

we can set everything to zero and now

with that one on zero we can go ahead

and drag this outside of this object and

there you go that one keeps the exact

same settings and on this one we can add

the unlocked camera component and set it

up just like we had so then we'll look

at inverting and on this one we're going

to make a channel live down and there

you go now everything is on zero exactly

as it should be and on this one we can

get rid of the unlocked camera and now

we can indeed play around the rotation

so for the animation let's just go ahead

and set it so for this one let's go up

to one second

and let's record a keyframe on a scale

of one and on a rotation of zero then

let's go back into the beginning and for

this one let's scale it backwards so

maybe something like this maybe a 15

let's put it quite a bit smaller then

let's go up by three frames let's put

that one on -15 so rotation on the other

side and put it quite a bit bigger and

then on frame 10 put it on say 1.1

with a rotation of zero just like that

so there you go there's a nice pop-up

and for the alpha let's also go over

here into the 50 and let's just add the

canvas group let's set this one over

here is on one and then we scroll it

down to zero okay so that's our nice

animation let's stop recording let's

open up the animated controller and over

here let's make our nice animations

transition so transition from any state

into that one let's make it based on a

trigger let's call it just pop-up

and for this one this says no exit time

duration of zero and let's go when the

condition when we have this trigger okay

so that's it although one thing by

default this animation is going to Loop

so let's just go ahead we can select the

animation and over here let's just

untick Loop time so that way the

animation will not Loop okay so that's

great now let's go into the script and

over here let's get our animator so

private animator animator

let's get the animator just get

component of type animator

and let's define over here the private

constring for the pop-up

so we have this and then when we have

either fail or success let's just go

into the animator

and let's set the trigger for our pop-up

both up here and over here now we just

have obviously one issue which is that

it starts off as visible we don't want

that so over here we can just do game

objects set active into false in order

to hide it and when we get either of

these let's set it both to true

then afterwards the animation won't make

it invisible so it will still be active

but it won't be invisible so that's fine

so just with this everything should be

working as we want so let's test let's

just make sure to save it and go back

okay so here we are let's try delivering

an incorrect plate and there you go

Gotta delivery film okay great now let's

try delivering a correct one so someone

wants a cheeseburger so let's cook it

slice some cheese let's get some bread

so bread cheese and pick up the burger

and deliver and there you go a nice

delivery success all right awesome

okay so with these handphone changes you

can already see how we made quite a big

difference in our game we didn't do

anything to change any core mechanics we

just made what was already there pop out

we added a nice visual boundary to make

the map look nice we added some nice

particles when the character is moving

then we added a nice tutorial and

controls right as the game starts we

also added a bunch of effects on the

stove so it flashes has a warning and

some sound and lastly we also added a

nice pop-up when delivery is delivered

whether correctly or incorrectly

now of course we can always keep

publishing the game until Infinity

there's always more small things you can

add to punish the game just a little bit

more but at this point I'm very happy

with what the game looks like so after

all this work let's go into the next

lecture where we're going to play our

game from start to finish and see what

we've done

hello and welcome I'm your kudmaki in

this lecture we're going to look at all

the work that we've done and have some

fun playing the final game okay so here

we are in our nice starting main menu

it's simple but it works I actually

thinking looks pretty good so we have

our main menu working and we also have

the unloading system that we made so as

soon as I click on Play There You Go

loads in loading scene and here we are

on the game scene so we start off with

our really nice tutorial window and down

here we have the controls of course some

of these are dynamics so depending on if

the player rebinds or something this one

is going to update so we can look at

this window for as long as we want the

game is paused in the background so it's

on a paused game state

then whenever ready we can interact

so again that's the game input class

listening to the input and again all of

the code in here is really nice and

clean so when we press enter key the

tutorial isn't directly listening to

that but rather the general kitchen game

manager that main State machine is the

one listening to the input and this one

is listening to that state

so our logic is very well organized all

of the elements only listen to the

things that make sense to them so

anyways here we have tutorial let's

interact and there you go we've got our

nice game start countdown some really

nice animation really nice sound and yep

here we are then we've got our clock

showing the game time and on the left

side we can see our recipes once again

all of the elements they're all Dynamic

they're all spawn randomly and the icons

for all of the recipes they're also all

Dynamic so over here we have the

character control that we built we have

the collisions that we implemented and

of course we have the raycast testing

for interaction so we can identify all

the objects in front

let's begin delivering some recipes so

for example we need to cook some meat so

let's go ahead put it on the stove so

here is the really nice tape machine

that we built so we've got all the

various States we've got the visual

completely separated from the logic so

everything is really nice and of course

here we have the nice burning elements

that we added in the Polish lecture so

that one is burned so let's go ahead and

use the trash bin to get rid of that

so let's go ahead cook another one and

let's make a cheeseburger so let's put

some cheese let's listen to the aunt

interaction key and we can slice the

cheese we can pick up the meat pick up

the cheese then also pick up some bread

and deliver the recipe and there you go

our nice polish visual all right awesome

so here you can already see everything

that we've built the character the

physics the logic the input all of the

UI elements all of the worm UI elements

of the various counters and how they are

on prefab variants of the plates the

separation between the visuals and logic

separation between the sounds and logic

of the Polish elements that we made over

there the nice shadow graph that we made

then of course some of the basic things

that a lot of tutorials won't teach you

like for example how to make a pause

menu how to make the options

how to modify the Sound and Music Volume

how to rebind the Keys and so on

so with all that here throughout this

course we'll learn how to make a really

nice game with lots of interesting

interactions which you can now apply to

any kind of game any kind of genre you

want so like I mentioned in the very

beginning

you can take pretty much what we've made

here which is really just a character

controller and a bunch of interesting

interactions you can take everything

that you've learned here and make

something on a Sci-Fi space like for

example make something like Among Us you

can make something like FTL or perhaps

make some kind of survival crafting game

some of the interactions you would have

like resource nodes in the world then

you can interact together those

resources so with that you could build

something like rust or Minecraft or

Don't Starve so hopefully in this course

you'll learn a ton that you can now

apply to your own custom original

projects and if you've made it this far

then congratulations let's go into the

next lecture where I'll give you my

closing thoughts

hello and welcome I'm your code monkey

and congratulations you have completed

this course awesome seriously congrats

looking at the stats on my courses very

few people stick with it until the very

end so if you're hearing this then

that's excellent you're on the top 10

percent it means you are serious about

learning game development and I

generally hope this course has helped

you on your own Game Dev Journey

throughout this course you'll learn

about the basics of unity and c-sharp

you'll learn how to make a character

controller how to do a physics raycast

and use that for both Collision

detection and identifying objects to

interact with you'll learn about c-sharp

interface and events two extremely

useful c-sharp features you'll learn

about script mode objects how to use the

new input system should graph and tons

tons more and the most important thing

of all you'll learn how to build a

relatively complex game while writing

good clean code I really hope that's the

main takeaway you'll learn from this

course learning how to write better high

quality code learning how to refactor

how to keep the visuals and logic

separate keep the UI the couple from

logic learning all those things has now

made you a 10 times better developer

than when you started

so I really hope you enjoyed learning

all that let me know in the comments

what was the most important thing you'll

learn throughout this course I really

hope this was very fun and very

educational if you enjoyed my teaching

style check out my other courses I

really think the turn-based strategy

course would be excellent for you right

now it Dives even deeper into some

Advanced topics and since you've watched

this entire course all the way you now

have all the knowledge needed to follow

that course it will help you really

simply the final knowledge you gained

especially everything related to writing

good high quality clean code and since

you use Unity check out my ultimate DND

overview course it covers lots of tools

and features of the engine so you can

really use all the tones at your

disposal to make any game you can think

of alternatively if you like visual

scripting I have course on that or learn

how to make a really nice Builder

Defender game and definitely make sure

that you wishlist my upcoming steam game

total one Liberation I won't be posting

devlogs and in those you will see how

the code that I use in my own steam game

is on the same level of quality as what

you learned in this course okay so

that's it for me this course was a ton

of work so I generally hope it helped

you a ton on your gamedev journey thank

you so much for watching and I'll see

you next time

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.