Monster shadow

VIDEO

Game Manager - Controlling the flow of your game [Unity Tutorial]

Description:
Controlling the flow and state of your game is a fundamental step of game development. I'll show you how to structure your game logic to easily flow between each state (ie: player turn, enemy turn, victory, etc) and share a few tips along the way. ❤️ Become a Tarobro on Patreon: https://www.patreon.com/tarodev ========= 🔔 SUBSCRIBE: https://bit.ly/3eqG1Z6 🗨️ DISCORD: https://discord.gg/GqeHHnhHpz ✅ MORE TUTORIALS: https://www.youtube.com/tarodev About Tarodev: Develop video games like a pro! Whether you're a beginner or a seasoned game developer, you'll find lots of useful tips and tricks to boost your development career. Visit the channel: https://www.youtube.com/channel/UCAg2py6olXgod71Ix06HnUQ
ADD A COMMENT

Tarodev
Game managers are a vital part of any game. If you enjoyed the video, let me know so I can continue making helpful content :)
CorgiCoders
Learning Unity feels like I'm learning React again.
SPi
I still don't get how gameobjects can speak to other object codes. There are built in methods like oncollision and stuff that wait for events and return data, but i dont get how i can communicate between game objects and share information.
Tarodev
I just recently made a video on all the ways objects can communicate. Here it is: https://youtu.be/dtv7mjj_iog
Seth Dossett
at 5:50 what is the difference in using OnEnable and On Disable methods to subscribe and unsubscribe the event? this only way ive done it and ive not used OnDestroy?
შონია
Can we subscribe lambda function to the event and then unsubscribe that lambda. SomeEvent += () => print("Something"); SomeEvent -= () => print("Something"); is this possible?
Muhammed Mustafa Savar
Which extension do you use that has a hammer icon? the icon next to numbers that refer to which line you are?
Blackout Gaming
I learnt absolutely nothing from this video! this was because i wasn't paying attention. *_*note to self. rewind video and pay attention*_*
Blackout Gaming
@Tarodev sorry lol. I keep getting distracted. Good for your view count though!
Tarodev
Got me in the first half bro...
Sander Decleer
Hey, I've been watching a lot of your tutorials these last few days and I find your content entertaining and to the point. I do have some questions concerning this video. You say you keep the complexity low and easy to adapt, yet you need to enter and edit each leaf node in your game flow to change the way the logic plays out. Also, each leaf node needs to know about the existence and implementation of the game manager. Is this something only suitable for prototyping or how would you scale this up? How would you handle your UnitManager and your team color select screen when more options become available or required? Seeing this system handle change (as you demonstrated with the decide state) can really sell its benefits or show its downsides. I would really appreciate your input on these matters as it is something I spend lots of time thinking about myself.
Zack Mcracken
In a scripted language like python where circular references are a problem an event system might be a godsend.
Zack Mcracken
@Tarodev Design patterns have the potential to reduce the cost of extending and maintaining projects but for most developers they actually increase those costs.
Sander Decleer
@Zack Mcracken Thanks for your reply. I see the advantage of totally decoupling everything and using a message system once you application grows larger. For a smaller system or subsystem I believe readability and ease of seeing all moving parts in a sequential fashion has its merits. So there direct message calls could be an option. The thing I disagreed most with in this video would be that the state change is controlled by the simpler classes, thus making them dependent on the implementation of the gamemanager. The core application logic should be contained there, and other objects should only expose events or another way for the game manager to determine what happened and act accordingly. Event systems are one option for that. Excuse the rant, I appreciate your time and insight.
Tarodev
@Zack Mcracken I'm assuming you over-engineer everything. For small to medium games, this pattern is just fine. In fact most shipped games would be using this pattern. To say ignore it entirely just because there is a more complex and scalable solution is silly. Use the quickest and most efficient tool for the job at hand.
Zack Mcracken
@Sander Decleer Do yourself a favour and forget everything youve seen in this video. If you have a gamemanager that keeps track of game state then you need an event system to communicate between objects. So thats A LOT more code than just calling methods on classes. The information you pass between the objects must either be stored in each object until the next Update call (so every object that needs to know some information needs to store its own internal copy of it instead of just calling a method on the class and requesting the information) OR you need to store all information passed between objects in the gamemanager as part of the game state. So now you effectively have one giant class containing all these GLOBAL variables.
Mehmed Cavas
I used the gamemanager exactly the same way like here in the past
hooi kah seng
may i know what extension you using ? when i click Alt + Enter show notihng
hooi kah seng
@Tarodev thank 😄
Tarodev
I'm really sorry about that. It's resharper... At the time I didn't realise it was a plugin feature... It has a free trial if you're interested checking it out.
Валентин Матвеенко
Nice tutorial. But i would strongly not recommend making any managers or controllers - they completely break single responsoblitiy principle. The better approach would be to create a state machine not from enums, but with states being classes. This way you encapsulate logic and make clean, resusable code.
NiceLife
@Tarodev Yes, you are right. Using state machine, I ended up adding in more managers for particles, sounds and any additional interaction with the game. Although, I was in control of my code. If it's a bit big project, do go with state machine and it'll help you understand everything and would be so east to debug problems as well. For eg, I was making a Hunting Game and I wanted to make Animal behavior, and state machines really saved so much of my time. Had completed the simple brain of animal with-in a day and without any problems. Where as using enums would be taken me 3-4 days of work to bug-fix etc. So, i would really like to see your state machine implementation.
Tarodev
State machines (I do use them) also come with a bunch of problems. For example unless your states are monobehaviours, your 'Jump' state can't even hold your jump particles, audio, jump height, coyote time, etc etc. You need to store it all on the state manager, along with every other states references. It's like solving one problem, but only half the way... For any small project, I'll use a simple enum game manager as it quick and easy. Making code reusable and easily maintained only matters when it will in fact be maintained. Even then, spending 10 hours making code maintainable to save you 5 minutes updating something in the future is a bad use of time. This is VITALLY true for game devs as we tend to make 20 prototypes before settling on a game to complete.
Quân Trần
tks u <3
SpicyMelon
Ohhh I have always avoided naming it "GameManager" cause I thought that unity put the cog there cause unity already has some script named "GameManager" and I was about to override it.
HERNANDEZ TORRES EDER JAIR DE JESUS
Could you explain alternatives to avoid hard coding?
A M
Create a publisher subscriber system - an eventbus that manages the subscribing to and publishing of events.
Phạm Đỗ Hữu Tài B2 - 29 -
bro, i want an app to speed up the game but i don't know how to do it
Sunrise Sunset
Apologies if it's already been asked, but why is the GameState enum declared outside of the GameManager class?
Sunrise Sunset
@Tarodev Makes sense, thank you! Great tutorial!
Tarodev
Just so when referencing the enum outside of the Game Manager class we don't have to do GameManager.GameState.State, we can just do GameState.State. No other reason 😊
Wearing Bubbles
Free GameManager in 10 mins. You earned a like and subscribe. No questions ask.
Tarodev
Welcome aboard
Макс Михневич
oh yeah, good old "game manager" approach, pretty common, not necessarily good though when it comes to scaling.
Tarodev
@AlexjW3 yup it's a good thing to think about. Personally it's all about the complexity and scale of your project. I've built a tactics game using just this workflow and it was perfectly fine. The good thing about a full state machine is that you can reuse it in a generic way across multiple systems. What I suggest is using the simplest option, unless you know ahead of time it will cause problems. That's basically the philosophy I use across the board.
AlexjW3
@Tarodev What are your thoughts on using this design pattern vs. a state machine pattern? I build my project with your system, after reaching a level of complexity I'm thinking about rewriting as a state machine.
Tarodev
Game manager should be a pretty simple script which just orchestrates. It shouldn't have any system specific logic, keeping is relatively lean even at large scale. What do you prefer to use for large projects?
1nferno
Great tutorial, many thanks good sir!
Perry Gretton
Hi, Tarodev, that's a great tutorial. I learned a lot from it. I was wondering if you have the code available in downloadable format.
Perry Gretton
I'd love to try this out, but I need the code. I mentioned this before and I thought you were going to give us a link. Can you do that please, because this is the best tutorial on this subject.
Perry Gretton
@Tarodev Much appreciated.
Tarodev
Ahhh, I didn't realise I hadn't added it to the description. I'm away right now but I'll try remember to put it in. Sorry about that mate!
SEE ALL COMMENTS


Transcript:

a game manager is a way to keep track of the state and flow of your
game uh as you can see here i've got a
little game set up we've got our players here and the enemies on the right there
with the fire on their head and i can press this
button and my team will attack the other team
but as you can see i can just keep pressing it and overwhelm the enemy
and there's not really much challenge to it so i would like to be able to
firstly i would like to show the player a select color screen so that
they can choose the color of their unit and then i would like to only let the
player attack when it's their turn and then have the enemy attack when it's
their turn and then ultimately either change to a
victory state or a lose state so let's get started
let's create a new object and let's call it game manager
and then a new script by the same name [Music]
and as you can see it's such a common practice that unity detects
the word game manager and if they say it they'll change the little icon to a cog
there put that on your game manager object and
open it up let's start by making a static instance
of this game manager so we can easily grab it from
any where in our game [Music]
just set instance equals this i'm not going to go too much into the detail of
singletons or static instances but for now
you just need to know that it just allows us to grab it from anywhere
so the whole point of the game manager is to
manage the state of your game so that's what we're going to do first
create an enum and call it gamestate and the first state that we want is the
color select screen isn't it so this state will be called select color
and then let's say it's the player turn and then the enemy turn
and then after the player turn enemy turn player turn enemy turn
we eventually will want either a victory screen or a
lose screen now in our game manager let's create a variable of type game
state let's call it state and now we need a
way to actually change the state of our game
let's make a method for that public void update game states
and this method will take in a type game state and we'll just call that the
new state in here we will set our state equals to
the new state and then we might want to run
unique logic depending on the state so let's create a little switch statement
here which takes in the new state and if you press alt enter you can just
generate the switch levels and it will generate all of those for
you and now in here we'll be setting the state
and then we'll come down here and then if we need to run specific logic for
each of these states we could simply add a function here for example
handle select color
and then that will be run when the state is changed
to select color another thing we need in here
is to actually notify anybody who cares or any script that cares that we have in
fact changed the state and this is the new state so we need an
event for that so let's make a public static event
of type action and it will take in our new state and we'll call this on
game states changed [Music]
all right so now that we've got that event let's actually trigger it
after this so we'll do that and we'll send in our
new stage sorry this is actually warning me it's
basically just saying if i trigger this and nobody has
subscribed to it i'm going to throw an error at you
a null error so you can protect against that by just
saying has anybody subscribed if so invoke this function just like that
so now that we've got that when the game starts up
[Music] let's actually call our first state
change let's say update game state and we'll send in our first
state select color okay so easy as that now this is not
actually doing anything right yet because we haven't actually
attached any uh state-specific logic to it
uh so what we need to do first is show uh the player the select color
screen so this event down here let's let's hook
into that event so over in my menu manager i've got a
reference to that color select panel which i showed you at the start of the
video so what we need to do is subscribe
to this game manager on state changed event
so in our menu manager in our awake function let's subscribe to it
game manager on state changed plus equals which is how we subscribe to
events in c sharp and let's create a new method
now it's good uh it's good practice to always unsubscribe from an
event uh when you're finished with it to avoid memory leaks and so on so on
our on destroy event when this class gets
destroyed we will instead of subscribing to it we
will unsubscribe from it just like that so now when game manager
calls this calls this on state changed we're going
to run this function let's change that to state and basically
all we need to do here is if it's if the state is select color
we will show our panel otherwise it's always going to be hidden
so an easy way to do that is just color select panel
set active and if state equals select color then we're going to show it
otherwise hide it okay so now when we start our game up
it shows our color select screen which doesn't actually do anything at the
moment so let's
do something about it on our color select
we can just move my face over here so you can see
you'll see on these on the button events i have
hooked into the unit manager select color function
so blue or red okay so over on our unit manager i've got
this function called select color it takes in the color and basically it
will just say to all of our player units here's a
red material here's a blue material pretty simple um you can just ignore
that though now once the u once the player has
actually selected this color we're done with the select color state
so now we can say game manager instance
update game state and what was our next state
it was the player turn so let's do that let's send in
player turn so now it's going to come down here again we're going to set the
new state it's going to come to player turn
we might need to handle some player turn logic here so let's create a new
function just like that
and then it's going to perform that logic and then come down here again
and trigger the state changed event again so what do we need to do here
well it would be nice to only allow the player to actually press this button
when it's on his turn uh we don't want him to press it when the enemy's
turn is playing that would be unfair so in in my uh menu manager
i've got a reference to that attack button as you can see there
so in our menu manager uh we've actually already subscribed to this event so now
we can say we need to actually change this attack
button to an actual button so let's do that
button attack button and we'll remove that reference
and now we only want to allow the users to press the button
when it's the player turn so we can do attack button
interactable equals and we just say if the state is equal to
player tone also when the player actually presses
the attack button we want to then take it to the next
state we don't want the player to be able to continuously press the button so
as you can see here i've got this attack button pressed and on the attack
button i've just got a button trigger and the
menu manager attack pressed so when the when it's
pressed i'm just i'm just telling the unit
manager to tell all the players to attack
and then i will say the game manager um instance update game state
and now let's say it's the enemies turn in our game manager now that we go into
the enemy turn let's create some logic for that
handle enemy turn uh now in here let's actually make this
an async function and we'll just add a little bit of uh
artificial wait time just so that the player units have a time to attack this
is uh not great design i'm just doing it for
the sake of the tutorial and we'll just do a task delay let's
wait for about actually let's wait for about two
seconds now our enemies can attack so let's say
unit manager instance attack and
we'll say the enemy faction [Music]
let's add another artificial wait time there to allow the enemy to attack
and then here we should then find out if the all the enemies are dead
or all the players are dead so a good way to do that would be a
another state here and we'll just call it decide
and we can add a new case [Music]
handle decide now uh this is not the most performant
way to do it but for the sake of the tutorial basically
what i'm going to do is i'm just going to grab
all the units find objects of type units
i'll say if units any uh unit
of faction basically just looking for are there any units of
enemy and if not if no enemy units will say update game state
and we'll say win victory because there's no more enemies
else if now this is a very sloppy way of doing it but just
just for the sake of the tutorial uh if there are no players left
then we'll say well you lost otherwise let's update the game state back to the
player turn let's also add an artificial weight here just so
that we can see the decide
or else it's just going to flash by our eyes way too fast
all right so let's see what we have made a red team attack
enemy turn over to the side back to player 10
oh look at that damage oh it's not looking good not looking
good 1v3 at least i took one of them out
and i lose so there you go i showed you how to create a game manager
a fundamental of game management i showed you how to run specific logic
for each state and trigger an event which other parts
of your game logic can hook into and run their
own logic a game manager is perfect for keeping
all of your game flow all in one place keeps it neat organized and easy to
debug so if you learn something give it a
thumbs up subscribe and i'll see you next time
you