Wow, I've never seen such tutorial before. Explaining patterns in "question-answer" dialog is really easy to understand. Classes scheme is also really useful. That's what I've been looking for
@shaunyitisme32935 жыл бұрын
That new style of pair programming / mentoring is really nice to understand what you're showing. Nice job, I hope you gain more viewers!
@InfallibleCode5 жыл бұрын
Thank you! I’m glad you like it.
@ankitmehrotra61043 жыл бұрын
Yeah
@donixdev4 жыл бұрын
17:45 That sneaky 2f transformed to 0.2f
@ginocode4 жыл бұрын
Wow never seen someone do the sketch-like tutorial without coming off as either cringey or condescending. This was really well done and actually proved that a tutorial like this can work to great effect. Great job!
@kartman1463 жыл бұрын
It was pretty cringey IMO, the actual tutorial is great so i think that's why he gets no hate
@ginocode3 жыл бұрын
@@kartman146 Cheesy, yes, but not cringey in my opinion. But I totally get how someone else might see it differently lol. At the end of the day, I think it’s a pretty good method of teaching either way
@julianerickson5954 жыл бұрын
I started running into the problem of if-statement spaghetti as you mentioned and this tutorial was very helpful in transforming my existing code to the state machine pattern. Thanks a lot.
@ZOMBIEBUST3R Жыл бұрын
It is amazing to me that the conversation at the beginning of the video is the exact same thought process I had before looking for a refresher video about State Machines. and for this exact situation and project type as well. I'm amazed the first video I opened fits so well with what I wanted. Great video, I love how you add a bit of explanation about why and when to use this pattern. It is as important to know about the pattern as it is to know when to use it.
@holmbergen5 жыл бұрын
I've implemented this for my weapon system (still working on some issues). It works great! It's actually been quite fun to work on the different states - it's so simple and keeps my code clean compared to the mess it was before! Thank you Charles :)
@InfallibleCode5 жыл бұрын
Awesome!
@TackleProd3 жыл бұрын
I've seen them all, but you're one of my favorites to watch right now to learn Unity!
@SigmaChirality4 жыл бұрын
I spent 2 days writing then deleting state machine code for my game. Then I watched this video, and it resolved the issues I was having. Thank you.
@modiddymo4 жыл бұрын
I just used this tutorial to implement a FSM with the state pattern in a project I'm working, and I love it! I can now add more states as my battle system gets more complex (and I think it will). And it's so much easier to reason about the code that's already there. Thank you so much for this! Keep it up!
@nGAGE0nline4 жыл бұрын
Wow, this pattern is amazing. It makes enemies yield when their currentHealth is less than twice their totalHealth :D (silently fixed) typo aside,... Amazing delivery on explaining the concept of a basic state-machine. I love your videos. Informative as well as entertaining :) Keep it up!
@EricWilliamsCG3 жыл бұрын
I saw that too, got really confused when the enemy didn't immediately yield.
@brianwilson74979 ай бұрын
you have such a good relationship with yourself my dude, good tutorial
@JackKell1005 жыл бұрын
One small improvement that could be made so that you did not have to implement an Attack and Heal method in the base State class would be to have the battle system generate AttackButtonPressed and HealButtonPressed events. When a BattleState is created it could choose to subscribe to the events that it cared about such as Attack and Heal and could make decisions based on that. This would scale better, decrease coupling, and improve readability / code intent.
@CSPlayerDamon5 жыл бұрын
It indeed generally makes more sense to have an Enter and (perhaps) Exit methods to override and subsequently use the state machine itself to handle connecting the different states. To clarify even further, Attack would not be a method, but a state itself. You'd also have a BattleReady state. The BattleReady state shouldn't know internally that the player can attack. That's up to the state machine. So OnAttackEvent, IF we're in the BattleReady state, then enter the Attack state. The Attack state can internally know that it should return to the previous state OR (imo better) the StateMachine itself can revert back to the BattleReady state after the Attack is completed (Enumerators can help implementing that). Also, SetState should be the one responsible for calling the Enter and Exit methods. Then you have a system, the StateMachine, connecting all its different sub-systems, the States, which is also responsible for calling the behavior described in the state. Doing it as shown above is not bad, especially when you want to be explicit on what your system can and cannot do, but I believe it's a halfway between the previous system and the system I described. Lastly, the events you described would be helpful, but you'd be kind of breaking the encapsulation and the intent of classifying the states. You'd essentially be making a state that upon being "connected", would add some events to be called on the StateMachine at some point. So you're going from the StateMachine to the State back to the StateMachine. The only reason I would do that is if I created a GenericState, with Enter and Exit events that you can manipulate outside of the state itself. It's not bad for it to be there, but quite unnecessary if you don't intent to make some kind of StateMachine that can be serialized and edited and extended only / mostly through the Editor and not so much (if at all) through code. I'd love to hear if anyone has a different opinion of this, it's mainly how I learnt to create States through University and my own experience.
@jonathansaindon7885 жыл бұрын
I agree with that. This is called an event driven state machine.
@sh1k1kate2 жыл бұрын
Thank you a lot!!! Your way of making it an inner dialogue rather than monologue is best way not to get frustrated when following the tutorial🤟
@thethirdkate3 жыл бұрын
Great video, just another comment to say that I enjoyed the question/answer format - it's very reassuring to have my noob questions answered like that!
@urealaden38374 жыл бұрын
Probably one of the best tutorials on State Machines that I've found. Nice touch with the programmer and mentor setup. Looks like you got yourself a new subscriber
@eter_inquirer4 жыл бұрын
If only learning from your peers was this smooth sailing
@doge92033 ай бұрын
this is so freakin cool, why did I not understand this sooner when I first watched the video
@ZoepX2 жыл бұрын
This was one of the best tutorials I have ever had the pleasure of watching in this website! thank you so much!!
@Kandyman7364 жыл бұрын
That was the best state machine explanation and very creative alternating state presentation. I get it. This sir, is worthy of the Infallible Code channel name. We're this reddit, I'd give you gold.
@sethell23 жыл бұрын
I have a quick question: When you use SetState(new XXX(Battlestate) ) are you creating a new Object every single time? If so, would that generate a lot of garbage overtime? Thanks
@AM-vr4qy2 жыл бұрын
Yeah possibly best to new and cache the states in start up
@wolfpackgaming6294 жыл бұрын
just a little tip you might already know, if you type ctor and hit tab twice (I think it's twice) visual studio will build the constructor for you
@jorgevelasco-theartofgames86872 жыл бұрын
Imagine being coding and sudently Charles walks into your room for no reason and when you say "oh hi" to him he just says "oh hi" like if he were surprised. Like, Charles are u ok?
@andrewshandle4 жыл бұрын
I'm a fan of your channel but I have a mild criticism on this video. I don't think abstracting out the States only to then immediately couple it to the UI (at about 8:30) is a wise move. By ignoring Separation of Concern, if anything, the new code is more complicated than leaving it as part of the same class (using Private methods to keep the cyclomatic complexity low). Also, by not tying it to the Interface it also makes testing a lot easier. You should be able to wire your entire battle system to a simple texted based Console if needed because it shouldn't need or care about MonoBehaviors to run.
@artemisDev5 жыл бұрын
Just what i need, just in time. What a coincidence!
@InfallibleCode5 жыл бұрын
Nice!
@reststop36324 жыл бұрын
Great content and you also nailed the presentation.
@dweebosupremo59044 жыл бұрын
Thanks for this vid. I appreciate the human touch of the "skit" parts.
@Brademmerson2 жыл бұрын
Love your way of delivering information dude, so helpful! Thank you!
@maxismakingstuff4 жыл бұрын
Thank you for this video and your channel over all. Thanks to this tutorial I wrote my own statemachine for input in Unity. I then got addicted to handling stuff this way through coroutines I started to replace the unity animator for sprites with code, all stemming from the original statemachine. Great channel.
@danielemessina19793 жыл бұрын
on top of the quality of the programming advice, this guy can act
@CodemasterJamal4 жыл бұрын
My buddy @Rob Lang showed this video to me. It's funny cuz the opening to this video is exactly how our conversation went.
@mrshurukan2 жыл бұрын
This helped a lot! And not just with the State Machine, but with Unity as a whole (I just learned about these yield break; and yield return; and their usage with Coroutines, that's awesome!) Thanks a lot, hope you get more subscribers!
@magnusm43 жыл бұрын
3:45 I was thinking the same thing. I want to make a basic finite state concept that's as vague as possible so it's gonna be possible to adopt by multiple systems such as players, game modes, menus etc. And also what you said about keeping it finite. I would actually like to keeping open for extension by anyone. How i'm doing it: an open variable to abstract state. A bool for custom state. Then I sort of break the state machine by having a bool. If the bool is false, run as usual. But any object such as a new vehicle or item can set the public state to their unique state, and then sets the bool to true. This will make it automatically run the custom state. This allows you to easily test any new state and it's behavior while being able to implement new features without being restricted to a set number of conditions. It's a finite state machine, but with one state being optional, and open to be switched out. I want to think like a modder. If the game had third person gameplay, three vehicles and weapons in an inventory. How would I go by to make a whole new type of item or vehicle without having to rewrite the base code and add it to the list? Say I wanted to add an item that, when holding it. Makes me float and I can jump higher while floating down slower with shooting feature and being able to crouch or bail. If neither crouch nor bail exist in any of the 3 vehicles and I want it classified as an object. Questions like these are what I ask myself all the time when designing my basic core for my game development. I want to be able to reuse it as much as possible. Possibly in every game I make regardless of genre. Like Vector3. It has only 3 variables and has finite set methods to use but it's so flexible that you can't make a 3D game or even some 2D games without it.
@magnusm43 жыл бұрын
I wish more people went into some deeper forms of using a state machine. I've had the issue where I want anybody who makes a character to start with a base set of mechanics and values such as drag, friction, jumping etc. But I also want to be able to change these values or stop using certain mechanics and use their own. Such as maybe an underwater state changing the rules completely and you need completely new grounded/touching surface states. Then there's also operations that should run at all times like Rigidbody such as custom made controls like the timer to a jump button so it counts as pressed for 0.2 seconds after being pressed. Or some things you don't just want to be stopped when switching between states. Then there's of course sub states. Like with animations where holding nothing and holding a staff uses the same leg animation for running and jumping but a different one for attacking. Think of Doom Wads. Base set of values and functions. But it first reads in the basics then overrides everything the Wad does instead.
@kattensaklart93234 жыл бұрын
Why do the virtual methods in the abstract State class have to be coroutines? Would not normal methods cut it for some reason?
@RobertGercia Жыл бұрын
I love this format!
@gilbertgabriel66703 жыл бұрын
What a brilliant way to teach people. Good work!
@hakanviajando2 жыл бұрын
In the abstract state class, you used a protected BattleSystem battleSystem property, didn't this action limited this whole state machine to be only used with battle system state machine? With that, can't we just get rid of the abstract StateMachine class and just use the BattleSystem class as our state machine?
@cranial33084 жыл бұрын
dude you are amazing, this was an instant sub and like, keep up videos like this man. Good work and thank you, so much appreciation right now
@notecolt27424 жыл бұрын
holy shit i just came across this video and the way its set up is a really good way of teaching the viewer. Nice job!
@flamingodev3 жыл бұрын
Thank you. Really clear and cool tutorial. Helped me a ton
@Kaikaku6 ай бұрын
A bit late, but the overview at 2:00 seems incorrect? Shouldn't be Start, Attack, and Heal functions in State and Begin, PlayerTurn, and EnemyTurn (among others) the classes implementing State?
@Kaikaku6 ай бұрын
Also, the State is part of StateMachine and not of BattleSystem
@Silver-fh4fb4 жыл бұрын
Little typo at 17:36. 2f should be .2f if you want 20%.
@mustafaamirnaifalimari90413 жыл бұрын
Congrats. Your code is now marginally slower, more complex and less readable than before. The gang of four are proud.
@giovanemachado83393 жыл бұрын
thanks god you have such a prestative twin brother! great content
@makovkawait35015 жыл бұрын
Why did u create abstract StateMachine if u also pass BattleSystem into State constructor?
@mmokzlrsn Жыл бұрын
wow great design and clear instruction thank you
@axelseven72 жыл бұрын
If anyone is having trouble with losing the reference to the state when reloading the scene in unity, just add the [SerializeReference] attribute to the state property.
@gregoryhoward75943 жыл бұрын
Nice video. Unique in delivery as well.
@TangoGolyder5 ай бұрын
I have a question that Where will the new state class instance created and passed as a parameter of method "SetState(new ())" saved on memory? I assume it will be somewhere on the heap but I'm not sure. If so, will it create more garbage on the heap?(new class instance that no pointer is referencing it after the state switched)
@n8dev3 жыл бұрын
incredible tutorial as usual
@CodingWithUnity4 жыл бұрын
What a great channel, awesome video
@hemantvats64913 жыл бұрын
Which IDE you are using ? its very helpful and time saving. i think its time to change VS..
@Andrew-tl9gk2 жыл бұрын
IMO the pattern has some flaws. For example that the state itself does logic that depends on outside factors like the enemy. For example the behavior "if the enemy is dead" could happen in a lot of different positions in the code, he could die by position for example outside of an attack. The more complex things get the less we can handle this and the more bugs can occur. Instead we could use a reactive approach (UniRX helps us A LOT by that): When the enemy has 0 HP or less he could emit a "i am dead" signal which then others (e.g. the state machine) can react to. We could go further with this and dont let the state's handle any transitions. Instead the states could emit signals (e.g. walking-state emits "no more grounded" or jump-state emits "grounded again") and then a state-machine "brain" could react to those signals (RX gives us tons of helpers to make super complicated cross-behaviors super simple and solid) and switch states or emit other signals.
@squirrelzar Жыл бұрын
This is a highly simplified overview of a state machine. If one wanted to build something that can handle more complexity then sure, this might not scale well. But you don’t need a complex solution for a simple problem, that’s just a waste of time
@sagiziv9275 жыл бұрын
At 2:00 l, in the UML you showed that start, heal and attack are classes (That inherit from State), but eventually you implemented them as methods. Is the a mistake in the diagram¿
@InfallibleCode5 жыл бұрын
Hmm that’s a good point. The UML was supposed to be conceptual but it’s actually misleading given the code that I ended up writing. I’ll be more careful when I use UML to explain concepts in the future. Thanks for the feedback!
@ravanin5 жыл бұрын
why new states on every setState( ) call?
@paulshepherd3002 жыл бұрын
Fantastic Content !!! thanks
@left_eyebr0w3 жыл бұрын
I love this video wholeheartedly
@michaeltyers7336 Жыл бұрын
Awesome you have a twin to do these videos with
@CaverHTC4 жыл бұрын
Thanks for the tutorial, really learned something here :)
@InfallibleCode4 жыл бұрын
Glad to hear it!
@exthase_original4 жыл бұрын
I smell something fishy at 12:26 : you press "heal" and heal yourself and the text says that your opponent feels renewed strength? :D
@cinocigames99944 жыл бұрын
Great video, thank you! Really helped me get started on my own FSM!
@pikupikuseru3 жыл бұрын
Well. I had an issue with this, in that spam clicking the attack button basically "queued" a ton of attacks, and both characters would reach 0 HP after the 2 seconds had passed. I originally thought of having a way to disable the UI after issuing a command. Instead I fixed it by using a ```yield break``` at the end of the PlayerTurn.Attack() method instead of WaitForSeconds(). now I'm trying to figure out a way to implement an AnimationIntermission state to hold the ```yield return WaitForSeconds()```, and eventually try to use this pause period to implement combat animations and damage numbers. I'm still not sure if this is the most elegant approach, as I am having issues trying to figure out how to make the state know whose turn it should transition to after it ends, since I want to use the same State as an intermission for both the PlayerTurn and EnemyTurn. Maybe I'm thinking too hard, and the disable/enable method is the best way to go? Either way, thank you for the tutorial! It really made turn based combat much less intimidating to tackle :>
@alexfightsevil Жыл бұрын
The project files link is not the same code as what is used in the video
@thewowo4 жыл бұрын
Exactly what I was looking for!
@sheppowed44833 жыл бұрын
Can we use a state machine for a player controller? (like swimming, walking)
@konsumgeist2 жыл бұрын
I tryed it, works very well and the Tut was nice, thanks. I wonder about one thing, if i always allocate a new class for every state, what happens to the old one which it replaces? I cant see a destroy. Is it been garbage-collected automaticly since there is no reference nor a function in it anymore?
@ewwitsantonio3 жыл бұрын
Great video! Side question... can I ask, in the BattleSystem script, why are the properties set up they way they are? "Public BattleUI Interface => ui" for example. My understanding is instead of the private field, you could just simply say "Public BattleUI Interface" and be done with it. Right? What functionality does this bring? Asking because I don't understand and would like to learn, not because I'm trying to challenge you or anything. :)
@chitrang77504 жыл бұрын
❤️ Huge Thanks Brother. You have one more fan added in your List.
@FlawlessCaleb2023 жыл бұрын
On the button click method you have State.Attack(), did you make attack static?
@mehmedcavas30695 жыл бұрын
yes the pattern i use :D It is actually really good, clean and readable :)
@mehmedcavas30695 жыл бұрын
Okay, I used it completely wrong but still very similar :D
@void_star_void5 жыл бұрын
These intros 🤣🤣
@jakeaus19844 жыл бұрын
Great tutorial, thanks for creating this!
@SlayPlenty3 жыл бұрын
ok so in order to get airdodge and air attacks in a 2d platformer id need a state that tells the controller that we're in the air? it feels abstract trying to convert the logic from a turn based game
@kidsteveee5 жыл бұрын
re: 18:48, where are the links?
@InfallibleCode5 жыл бұрын
Thanks for the heads up! I’ll post them ASAP and let you know when they’re up.
@InfallibleCode5 жыл бұрын
Updated the links!
@gamekonet2 жыл бұрын
Well done for this amazing work, the way you did answer the questions and scenarios is pretty amazing and unique, hope you best of luck and that you would reach your goals👏
@KonradGM4 жыл бұрын
i like this tutorial but i feel for state machine and state pattern especially it would be better to make a completely project independent example , including transitions etc
@jdigi784 жыл бұрын
Thanks for the video, but the downloaded project doesn't match the video at all
@rodrigonovais96244 жыл бұрын
Any way to prevent user spams the action button?
@LegeticGaming3 жыл бұрын
What is that font/theme for the editor? I really like how the function names are bold and such.
@jonathanjonsson31434 жыл бұрын
Hi! Thank you for a great tutorial! One question: I get that the state machine is set up for the Battlesystem class. But what if I wanted a State Machine for something else (another class)? Like a state machine set up for plant growth - would I have to create another State-script to inherit from? Or what if I would like GrowthSystem states to inherit from States...? I hope that you understand my question and thank you! Have a nice day
@gabrielaudette45912 жыл бұрын
You can create one state machine(store) & state for each system. Also you can abstract a generic state and a generic store (state machine) to avoid code duplication for every state machine (store) & state you have
@pixboi2 жыл бұрын
I've been looking for a method of putting states into a hashmap. I could then deduce the state of the controller, hash it, and automatically transition based on this hash, without any IFS or elses. Do you have any idea how this could be done? My problem has been, that the hash is too exact, having the dimensions of 0-1, while all the states don't necessarily care for all the parameters.
@timdouglas20112 жыл бұрын
god I love your tutorials
@thomasbrounstein98223 жыл бұрын
Unless I'm misunderstanding, it seems like this creates a huge stack. Is there any way around this/is it not an issue?
@pokefanover9000000004 жыл бұрын
Is that computer case the NZXTS340 Elite? It looks amazing!
@toadill5 жыл бұрын
This is beautiful!! Thanks!
@frankiwinnie51802 жыл бұрын
hello Charles very good tutorial. I am trying to implement this on a card game but I have a question. Is it possible with this way of state machine pattern to loop patterns? So what I mean after the "endgame" state I want to return to Begingame state and play the game again. So if I only code SetState( new BeginGame) will it run in like in the first turn? If no how can I do that?
@mykilpee4 жыл бұрын
Very nice, are you able to see what state it's in in the editor? (This is the problem I've had)
@abdou0232 жыл бұрын
So, first i need to watch Brackeys video then come here to implement the state machine?
@pauloviniciuscoral11284 жыл бұрын
Hi! Great video and explanation. I have a question. Instantiating these states in BattleSystem.SetState(new SomeState(BattleSystem)) with the 'new' keyword could cause performance issues with the garbage collector?
@sebastianbryant42162 жыл бұрын
Thanks for the extremely helpful video and expert presentation 👏 👍
@InfallibleCode5 жыл бұрын
NEXT VIDEO: Design Patterns in Game Development 👉 kzbin.info/www/bejne/p4SVhIOiaKx4ac0
@aksimilumaspvp72783 жыл бұрын
saved a lot of time thxxxx
@swinefeaster4 жыл бұрын
Thanks for the video. I get the pattern, but I'm wondering if unity has a built in mechanism for this or whether StateMachineBehaviour is only meant for unity animations specifically? i'm looking to implement a few states for a spaceship - Normal, Exploding, Losing, Winning
@ZoidbergForPresident5 жыл бұрын
Any reason using abstract State class instead of Interface? Also, I think I could use a couple of schemas somewhere in the video for overall vision... Alsoooo, what if I wanted to player input to go forward between states/turns instead of waitforseconds? Alsooooooooooo, how to gray the buttons when not in PlayerTurn state, which would be better then ignoring the action, agree?
@EgorBakanov5 жыл бұрын
In this case abstract State class let us type less because it can have default methods implementation. Interfaces can not do it in the current C# version.
@AlDumbrava4 жыл бұрын
I was wondering what's the benefit of using IEnumerators instead of just calling the methods directly from the main loop. In my mind I don't really see a benefit to running attack / heal code from a separate thread.
@JasonStorey4 жыл бұрын
Actually unrelated to your question. IEnumerators... (aka coroutines) do NOT run on a separate thread. the reason you use enumerators is that they partition work into "steps" that you can split across multiple synchronous frames. so you would be able to put pauses, or to split large work over multiple frames of gameplay rather than pausing until the work is done. For more information on this topic, check out "Unity 3D Gamedev Stream #5" and start at about 1:25:00 for a deep dive into what enumerators are and how they work in unity.
@adamkis71374 жыл бұрын
17:42 if (BattleSystem.Enemy.CurrentHealth
@MaZyYTube4 жыл бұрын
He has there a cut where you can see 0.2f. He should make a note or hint there. You can see it at 17:49
@tonyb983335 жыл бұрын
So is this really the best way to do this? Or are you setting up for a third video in the series? Your states should not be implementing heal or attack methods. Take for example what you were trying to do in the first video, implement a Paused state. A Paused state needs nothing from an Attack function or a Heal function, and really neither would any other state other than the player and enemy turns. A better implementation of the pattern is to have State provide methods for OnStateEnter, Execute, and OnStateExit. The states themselves don't need to know anything about attacking or healing, those are specific only to player/enemy turns (and ideally just a general "BattleUnitTurn" state). SharpAccent has a pair of pretty excellent videos implementing this pattern, one with pluggable ScriptableObject actions, and another version using plain C# classes if anyone is interested in seeing an implementation of this variation of the pattern.
@CSPlayerDamon5 жыл бұрын
Already posted a detailed way to implement a state machine as an answer to JackKell100 's comment. Indeed, Attack and Heal should be states themselves. On top of that, you shouldn't be able to stay in that state, but revert back to a previous state or another state all together - that solely depends on the way you connect things in your state machine.
@saito8534 жыл бұрын
Thank you for this comment, I was thinking the exact same thing: why would the State class have heal or attack methods, didn't make any sense to me.
@mmdjn2 жыл бұрын
Thank you so much!
@kifercastillo78764 жыл бұрын
May I ask why is it necessary to do this if in the end is going to do the same but more complicated? if you know please tell me