Better Coding in Unity With Just a Few Lines of Code

Get your code looking nice, clean and maintainable, by applying this simple pattern for your state management in Unity.
Inspired by: gameprogrammingpatterns.com/s...
www.firemind-academy.com/

Пікірлер: 493

  • @Zicore47
    @Zicore472 жыл бұрын

    State machines are great, but they don't reduce spaghetti code. In all your examples you could invert the ifs and return early to reduce nesting. Also keep in mind that virtual methods can add a performance overhead. Stick to KISS and composition over inheritance. Still a good tutorial for learning the concept.

  • @Konitama

    @Konitama

    2 жыл бұрын

    Yeah this is called a Guard Clause and I've been using it a lot more in my own code to reduce if conditions

  • @nathanfranck5822

    @nathanfranck5822

    9 ай бұрын

    Yay, now it's spaghetti that's more annoying to trace/read

  • @nathanfranck5822

    @nathanfranck5822

    9 ай бұрын

    People who avoid simple structural coding because "wahh it looks messy" are hilareous. I bet they'd put bags in bins in three layers of boxes when they organize their shelf storage too. Have fun unpacking all that later

  • @K3rhos

    @K3rhos

    9 ай бұрын

    @@nathanfranck5822 It's way better to use inverted if with return, it's way easier to read and also way better when you need to put Debug.Log right before the return; So you can trace where it's passing or not, when with a classic if statement you will need to add a tons of "else" when something goes wrong, a real spaghetti code !

  • @CardrisCreations-iq7zs

    @CardrisCreations-iq7zs

    2 ай бұрын

    ​@@nathanfranck5822Nah man, this is WAY easier to trace if there are too many nested ifs lol You have an IDE that takes u to the implementation yuou want to see with a click lol It is crazy to say that just bloating a bunch of logic together with no visual organization is easier to read just because it presents less architectural complexity lol

  • @Michael_H_Nielsen
    @Michael_H_Nielsen3 жыл бұрын

    I think the information is good but please speak faster. I sat the speed to 1.5 :-)

  • @coemgeincraobhach236

    @coemgeincraobhach236

    2 жыл бұрын

    Haha, I have it at X2, and went to look to make it faster.

  • @midnatheblackrobe

    @midnatheblackrobe

    2 жыл бұрын

    Had to watch at 2x speed to not ram my head into a wall.

  • @doismilho

    @doismilho

    2 жыл бұрын

    Lol me too. Funny that the top comment is exactly this

  • @TexMackerson

    @TexMackerson

    2 жыл бұрын

    He's explaining MStates to people who write spaghetti code, he HAS to go slow

  • @coemgeincraobhach236

    @coemgeincraobhach236

    2 жыл бұрын

    Ah to be fair it is a good video. More a reflection of my impatience than anything 😅

  • @davedoublee-indiegamedev8633
    @davedoublee-indiegamedev86332 жыл бұрын

    It:s not a bad approach but it can devolve into an inheritance hell with 30 classes for something. If you wanna keep things simple, you can do the same by just organizing your code well with functions. A different function will be called depending on the conditions. So you will treat functions as objects. Also, don't have variables like isDead or isJumpinh. Have functions that return the result instead (e.g. isDead() returns true if HP is 0). That way you avoid setting the state, you always have it ready.

  • @ozzyfromspace

    @ozzyfromspace

    2 жыл бұрын

    I agree with you. Functions are more ergonomic imo

  • @magnusm4

    @magnusm4

    Жыл бұрын

    You still need to check those conditions and the code within can become big. How do you choose what function to run when? You still need to run through conditions on which function to use. A grounded function returns grounded. So now you have to check to run that function. Unless you use delegates and return a function that should be run. So it returns the function to run. State machines are helpful when you work with characters in characters. For example crouching increases your jump height, let's you deploy certain objects, different abilities don't work, other abilities change and some are the same. You might also have to do some other checks like a ledge grab when falling but also a ground and wall check. One way is how he showed with inheritance. Idle and running states inherit the grounded class and execute that functionality while jumping inherit InAir and does that functionality, or doesn't. It's your choice. Have a character state that has an input function, when you're stunned then you don't call your inherited state's input function cause you don't need that when stunned.

  • @KojiKazama

    @KojiKazama

    Жыл бұрын

    Depending on the state that you're in, your child class may have functions not in super. Example the JumpingState will likely have cool-downs, allowed interruptions, combination actions, and variables that are not in the other states. This works out clean because if writing all in one class, you need to keep track of your private vars on which is the jumping cool-down, attacking cool-down, dashing, etc. And you have to build additional code that says if you are doing x and not y and z is not happening, this is ok, but if your state is Jumping, the input doesn't even have the action for y and z so you cold never perform it.

  • @notBradYourself

    @notBradYourself

    Жыл бұрын

    Agreed. I'd probably just opt for making CharacterState an enum and have that handled it in it's own function.

  • @Gortart
    @Gortart2 жыл бұрын

    You generally don't want a seperate class with just 1 method to override because you can just use delegate. And rather than returning a new instance of the state, the states should return a state flag that the caller should use to look up what to do next. Enum with a dictionary to look up would work well. And this is not really fixing spaghetti code. You would have to constantly make seperate classes for each new state as you add mechanics. If you added silence that stops some of the abilities but not all, you would have to make IdleSilenced, JumpingSilenced etc. The player should have some kind of attack timer and shouldn't be able to attack every frame. So should I make IdleCanAttack even though some attacks are only possible while in the air? Or name it IdleAttackTimerZero and have quite a bad time writing them down all the time? How do you even manage going from JumpingSilenced to IdleAttackTimerZero? At some point you HAVE to use nested ifs or you're just gonna make the state list grow 2x times each time you add something. In the given example, the isDead check should be at the very top of the update method and just return if the player is dead(or just do some being-dead logic then return). Checking isGround and isRunning could be quite confusing and you can add get-only property(something like CanUseBigAbility) and just return isGround && !isRunning. It's pretty much the same, but it's a lot better to manage. Spaghetti codes are bound to appear in any kind of complex system. Coder's job is not to eliminate them entirely, but to contain them in a safe box so it doesn't spill to everywhere. And haha your mom joke funni yes very funni

  • @mighty3257

    @mighty3257

    2 жыл бұрын

    Dictionary for the lookup… How did I not think of that? Thanks a lot for the idea.

  • @tatoforever

    @tatoforever

    2 жыл бұрын

    You described a couple of flaws that state machine behavior model has. And yes, there's no way to avoid some sort of nested if/else branching. Unless the system is so simple but this is rarely the case. In the context of AI, something that is not widely used but helps a lot in the decision making process (eg Switching behavior state), the part that is always prone to spaghetti code, is Utility AI.

  • @Zach-cc4ft

    @Zach-cc4ft

    2 жыл бұрын

    Yes I agree, I think this is kind of a bad way to approach the problem of spaghetti code, I feel like this creates a problem of making too many classes and things that is harder to manage than it would be to properly manage the spaghetti code of different states and would end up being a lot harder to read. Inheritance is great but I feel like its overused when it comes to things like this where it really doesn't make a lot of sense and actually makes it harder to read/manage.

  • @101touchapps

    @101touchapps

    Жыл бұрын

    i read this comment, i turn off unity and shutdown my laptop and throw gamedev dream out of the window. i think i will go work at mc donalds serving burgers. lol. gamedev is hard.

  • @LifeLedLucid

    @LifeLedLucid

    Жыл бұрын

    @@101touchapps you're watching vids to improve, if there is something you don't understand, take it as an opportunity to improve even more. I hope you continue your gamedev dream

  • @ZeroSleap
    @ZeroSleap3 жыл бұрын

    I believe the CharacterState would be better as an Interface,as there's no real reason for a base class implementation of handleInput. Plus the interface route enables inheritance of another class or interfaces. If a base class implemantation of handleInput is needed,an abstract modifier for the CharacterState class can be used instead.

  • @thepatchinatior

    @thepatchinatior

    2 жыл бұрын

    I think that was the intention but the author wanted to keep it as simple as possible

  • @jarrettonions3392

    @jarrettonions3392

    7 ай бұрын

    Yes. That is the solution i impleneted last night after learning about them. They work great! Agreed better. Good to learn inheritance too as it's something ive been hearing a lot about too.

  • @TGameDev
    @TGameDev2 жыл бұрын

    Imo you could also save the headache by implementing functions and guard clauses. So for instance that nested nightmare would look more like this: If (isDead) return 0; // he ain't moving anyways If (!isGrounded) return 0; If (attackPressed && isIdle) attack(); // Etc... also, to those curious you don't need brackets if there's only one action following the statement. Notably a break or continue (in place of return) work better in certain scenarios, such as being in a for loop. Hopefully this helps.

  • @aleksandarpantic8732
    @aleksandarpantic87324 жыл бұрын

    Put it at x1.25 speed and still slow...

  • @firemind2265

    @firemind2265

    4 жыл бұрын

    Maybe put it on x2.00 then ? :D

  • @aleksandarpantic8732

    @aleksandarpantic8732

    4 жыл бұрын

    @@firemind2265 good video, I'll give you that. Keep pushing, very good video editing 👌😁

  • @Lantertronics

    @Lantertronics

    2 жыл бұрын

    I think it's paced perfectly. I find that a lot of polished, high-quality Unity tutorials (like Brackeys) go too fast and I have to rewind a lot.

  • @1001HELL

    @1001HELL

    2 жыл бұрын

    I'm dumb and need this pace.

  • @giampaolomannucci8281

    @giampaolomannucci8281

    3 ай бұрын

    it's better to speed up a slow video than slow down a fast one, audio is less messed up

  • @spectrecular9721
    @spectrecular97212 жыл бұрын

    IDK, I think this boils down to whether you want your code to "look pretty", or you want a more performant/optimized game. This approach would probably be much more expensive than other options... certainly more expensive than nested 'if statements' checking conditions. Or just use a 'state' enum, or a single 'PlayerState' class. No need to over engineer anything.

  • @dede6giu

    @dede6giu

    2 жыл бұрын

    not really, as nesting if statments usually causes more expense to the processing than using classes

  • @spectrecular9721

    @spectrecular9721

    2 жыл бұрын

    @@dede6giu IDK if its handled any differently in IL code, but if statements are one of the most basic and primitive opcodes supported by some of the oldest CPUs, whereas classes typically require building and managing virtual tables and their respective address spaces, which are definitely more than 1 line of asm code

  • @lanik8163

    @lanik8163

    2 жыл бұрын

    I always find it funny when people say your code is bad (long and error prone) and then proceed to show you something even longer and much harder to manage. I'd say that as long as you think about the order of your conditions carefully and group some of them together or use delegates it'll result it better and more readable code. And like you said, you won't be wasting memory just to call a fucntion.

  • @detuneCris

    @detuneCris

    2 жыл бұрын

    @@dede6giu not at all lol, get your facts straight.

  • @CardrisCreations-iq7zs

    @CardrisCreations-iq7zs

    2 ай бұрын

    Bruh, performance is useless if the code is HELL to maintain lol especially if more devs are gonna work on the code. Just imagine nesting states for a huge game with 100 different states lol There is just no way, it definitely needs cleaner architecture in order to scale.

  • @LordBordNoob
    @LordBordNoob2 жыл бұрын

    Much like others have said, using enums and a dictionary with delegate functions is a much better solution to this. Or simply having functions that take care of each behaviour. If you constantly assign new objects and get rid of them like this on the fly, you will inevitably cause more memory fragmentation and a much bigger overhead for the CPU and the garbage collector. The 'new' keyword is something that should be used only when there is nothing else that you can do.

  • @NikolaZagorac
    @NikolaZagorac Жыл бұрын

    I'm about 20% done with my game mechanics, and have around 20 classes already... It seems like the more I unwind my code, the more complex it gets, but the more complex it is, the easier it is to work with.

  • @seb6861
    @seb68613 жыл бұрын

    I still don't consider my self a game dev until i could make at least one game and not just little project that i do to learn different stuff.

  • @jayocaine2946

    @jayocaine2946

    3 жыл бұрын

    no matter where you are in your skillset, you can make a full game. Your coding isn't holding you back, it's your project management skills. You can make a full game just using if statements and the update method .

  • @PearlyFostter

    @PearlyFostter

    3 жыл бұрын

    @@jayocaine2946 true

  • @flyorfloat

    @flyorfloat

    3 жыл бұрын

    @@jayocaine2946 Lol I remember doing that on roblox studio a long time ago (code is in lua) before switching to Unity so that's 100% true.

  • @7oca7hos7
    @7oca7hos72 жыл бұрын

    Well, idk. I think using oop for this problem is a bit of an overkill. You just could have handled all the conditions inside the attack() function, using boolean operators and the return keyword to avoid nesting. The user presses the attack button, then the function is triggered and it checks the conditions for doing the attack. In this way you have all the conditions in one place for that specific context, making the update function much cleaner. I think also that the code will be easily understandable for other people, and for you too when you'll read it after a while

  • @GlitchyPSI

    @GlitchyPSI

    2 жыл бұрын

    Guard clause 💙

  • @patrickp4175

    @patrickp4175

    2 жыл бұрын

    It was for the wannabe gamedevs I think. To show them how c# can be used. The guys which want to do all the things... except learning the fundamentals.

  • @durrium

    @durrium

    Жыл бұрын

    I agree with you man, this was way overkill

  • @accountdua9375

    @accountdua9375

    Жыл бұрын

    @@durrium The demo that he shows us just a example... as he said it's really good to use this pattern to make a big game..

  • @polarisinglol
    @polarisinglol2 жыл бұрын

    Awesome video! I recently got into Unity due to an assignment in my University which will be graded and am really loving it so far. Even though I already knew most of the stuff in the video I have to say it was a pleasure to listen and watch and I think you definitely helped a lot of people who are just getting started with programming languages and coding in general :) Thank you!

  • @thatoneuser8600
    @thatoneuser86002 жыл бұрын

    12:28 that conditional statement looks like something that could easily be duplicated across multiple states, which isn't a good thing. It also violates TDA (Tell don't ask principle) where you're querying the state of Input and performing operation based off of the returned value, so to me, it would make sense if the update state functionality based off input would be in some update method in the Input class that returns a state, depending on the factors you require for it to return the proper state. Then, all you would do is return the result of that method in handleInput()

  • @Neran280

    @Neran280

    2 жыл бұрын

    If I undestood you correctly you want to encapsulate the querying of the button press and the state transition into an own Input class and that class returns the CharacterState object? The Input system that unity provides is already an encapsulation, but it lacks some feature. So its good to define an own Input class that can also for example provide interfaces to deactivate inputs during cutscenes, etc. But I do not think that this class should also handle the state of your character. Also because this is a state machine, the Input class must have knoledge about the state transitions. Like into what state are you transitioning when in the idle state and jumping? Or isnt this possible at all? So in my opinion this transitioning logic makes more sense to be part of the corresponding state class.

  • @kreed1415
    @kreed14153 жыл бұрын

    State machines rule, however I would suggest you look into a more efficient solution that has less boilerplate code. If you have to create a brand new class for every state it gets incredibly tedious as your game grows. Consider making a StateMachine class that inherits from monobehavior that has a dictionary of which represents state then simply run the method for each state. it also makes declaring each state very simple and concise

  • @LuRybz

    @LuRybz

    2 жыл бұрын

    could you provide an example? Interesting

  • @johnleorid

    @johnleorid

    2 жыл бұрын

    Running code inside of states is a problem on it's own when it comes to character controllers. For example: if your player can jump, you will have the code for jumping in the grounded state, in the idle state, in the wallrunning state, in the sliding state, ... you get it. So I found it way better to have states which just run abilities (like the jump ability) - so there is only one state class and all it does is passing Update() down to it's referenced abilities. Professional Character controllers like the one from Opsive (asset store), are using the same pattern. And for everything else than characters or game state, I'd avoid using state machines and go with a component pattern instead.

  • @casefc3s

    @casefc3s

    2 жыл бұрын

    @@johnleorid Opsive's code is not a good basis for good programming practices. Yes it works and has a lot of functionality, but it is very poorly structured. I wouldn't call it "professional" beyond that they sell it as a product and it does well purely because it has a lot of functionality. Maybe it's changed recently, but those huge 10k line classes or whatever it was are a great indicator that things have not been well thought out or maintained.

  • @casefc3s

    @casefc3s

    2 жыл бұрын

    Why is making a class more tedious than writing an Action? Creating a state that implements focused interfaces is much more extensible and controlled. A couple hot keys and a C# template are all that's required. The Dictionary is an extra step that seems like it will end with doing unnecessary string comparisons against a big list of possible states somewhere down the line.

  • @delanmorstik7619

    @delanmorstik7619

    2 жыл бұрын

    @@casefc3s Because you will have class for each state AND method for ..each action in each state object. If you have worst case scenario, depending of you needs, you will end up with 10 diferre t classes for state, each of them having 10 methods.. jump, attack.. etc 100 methods!!!! If you did only use if if if.. you would have less than 100 if for sure. And also the example in the video was terrible example. The author should have chosed more complicated example where his solution would be obviously superior. Also the code itself was tons of unnecessary nested ifs. Why would you have nested if in each if if the player is dead. If the player is dead just return false. I hate when people give pseudo-example for clarity... Making the example dangerous! Now tons of new developers will do this solutions in their game without trying to find a better one for themself!

  • @mintesnotmelese6552
    @mintesnotmelese65524 жыл бұрын

    Men Please I want a bunch of Tutorials on State machine pattern programming, You're now officially my fav KZreadr. keep doing this stuff a lot I love it! :)

  • @garebeargaming9281
    @garebeargaming92813 жыл бұрын

    Spent the past week having a headache and a half trying to fully implement a state machine. And damn you just alleviated my headache.

  • @2simmy2
    @2simmy22 жыл бұрын

    I would recommend keeping your state as an enum instead of different classes then have a switch that shoots off to their own methods. Doing so will leave access to common data accessed by multiple states. This will also allow access for multiple states at once by using a flag enum if it's necessary (but i would recommend avoiding it)

  • @milankeravica7172

    @milankeravica7172

    2 жыл бұрын

    Wouldn't that make it a state machine, while the video demonstrates the usage of a state design pattern?

  • @TheExiledMeriler

    @TheExiledMeriler

    2 жыл бұрын

    You wouldn't achieve same code design idea with enum states. You end up with just creating a switch with going through all the enumeration, keep updating it with new states you added, keeping everything for function in single place. This solution doesn't really need give any need in touching anything but states themselves directly, so it won't break random stuff you could forget in main behavior code

  • @2simmy2

    @2simmy2

    2 жыл бұрын

    @@TheExiledMeriler That's a good point. An alternative to adding a ton of classes would be to use some form of delegate that gets switched out when changing the state of the class. This is only useful when most states need to access most data from the root class so making multiple classes would be redundant.

  • @DoorThief

    @DoorThief

    2 жыл бұрын

    Not to mention that you won't have a bunch of heap allocations that need to be garbage collected

  • @Hersatz

    @Hersatz

    2 жыл бұрын

    Enumeration is the same as using a bunch of boolean. It also push your code towards the switch anti-pattern, which is very bad. State pattern (its a pattern for a reason, widely used -check the gang of four for other patterns to start learning this incredibly usefull stuff-) allows the programmer to set up specific states where methods called in said state either do something, do nothing or do something different than the other methods. Usually all state should be implemented (i.e. they have a parent class) through abstract class or an interface which dictates what methods are to be implemented in every state of the state pattern. A good, simple, example would be a player grounded state, player airborne state and a player dead state. All three would have some theoretical methods : - Jump() - Move() - Attack() Player Grounded state: All three methods do something Player airborne state : Jump() does nothing (player is airborne) | Move() see movements halved for slight midair control | Attack(), in this specifc use case, does nothing. Player dead state : Does absolutely nothing since the player is dead. No movement, no attack. Note that a few different ways of managing which state is the current state exists (state enter & exit, state handler, state update, etc. ). I cannot stress enough how powerful this pattern is to get rid of conditionnals. It is also very easy to implement when you understand its functionalities. Plus, it is highly modular in nature, and easily respect the principle of being [Open for extension, closed to modification] -See SOLID principles-. You may even use it as a hierarchical state machine, where states exists inside of other states. Great stuff.

  • @andythedishwasher1117
    @andythedishwasher11172 жыл бұрын

    This was extremely understandable and helpful. State management seems to be one of the trickier initial hurdles in Unity, so I think your subject matter was on target as well.

  • @magnusm4
    @magnusm43 жыл бұрын

    I've seen Table Flip Games's tutorial and the great Unity finite state machine tutorial. But honestly it's really complicated. You send a new state from another state, which I honestly find scary to land in a soft lock. Flip Games makes a Finite State Machine class that handles everything and makes a reference to it in his main player class. And the guy in Unity's version he handles the current state in the player's main control script. And even has a function for transitioning to a new state where he sets the new current state and calls Enterstate, passing in his player class so that the state can access his Rigidbody and move it from the state.

  • @astrahcat1212
    @astrahcat12127 ай бұрын

    Of course, if you REALLY want simple and easy code, you could just not use oop at all and make everything a public static method (so like procedural programming).

  • @3_14pie
    @3_14pie2 жыл бұрын

    You have no idea of how much this video changed everything for me

  • @sonsai10
    @sonsai103 жыл бұрын

    tutorial was so great and funny, can't wait for the next advanced coding topic

  • @martinmica4260
    @martinmica42604 ай бұрын

    I love how slowly you explain stuff. It easy to understand the point :))

  • @dimak.6323
    @dimak.63233 жыл бұрын

    The first question got me yelling YESSSS ! I was looking just for that because I didnt know what alternatives do I have with writing code ! Thanks a lot man!

  • @ChinchillaDave
    @ChinchillaDave4 жыл бұрын

    Well produced, paced and edited educational content with a hint of humor. Great explanation of FSM! Excited to see what you do next Firemind.

  • @matthewmathis62
    @matthewmathis622 жыл бұрын

    Wow! You just revealed the state example, and it makes sense. It's a good way to write code. I like it! I'm glad you've said this, because I'm sure that I've written spaghetti code before. Coding is one of my favorite things to do, because it's so fun! And I appreciate you taking the time to make this tutorial. I would like to all of the concepts like the one in this video, shared conveniently in one KZread video. Perhaps you're up to the challenge? Hopefully someone is. Thanks,

  • @CastielQuinzel
    @CastielQuinzel2 жыл бұрын

    I'd rather code spaghetti. My avatar uses a very long list of code to make sure he dies when he is supposed to, doesn't go through walls, picks up items, opens doors, go to different rooms and use objects.

  • @ftwgunnerpwns
    @ftwgunnerpwns2 жыл бұрын

    I really like your explaining speed, it's way easier to digest than most tuts, thank you!

  • @vorlon478
    @vorlon4782 жыл бұрын

    Awesome job explaining this complex topic! Keep it up!

  • @juaecheverria0
    @juaecheverria02 жыл бұрын

    Come back, this tutorial was perfect i need more.

  • @firemind2265

    @firemind2265

    2 жыл бұрын

    I'll be back 8-)

  • @juaecheverria0

    @juaecheverria0

    2 жыл бұрын

    @@firemind2265 you the best, cant wait.

  • @Gomace
    @Gomace3 ай бұрын

    The only thing that I personally did not quite understand, and had to look up, was what virtual and override did. Although I understood that it did the job you wanted it to do, I did not know why these two new things were necessary. According to what I found while watching this video: Virtual and Override actually come in the same category as another word called Abstract. These three words are all related to inheritance. (There are a few more like Interface and internal that are relevant to this conversation, but for this example using these aforementioned 3 should be enough.) Virtual and Abstract are both keywords to be used almost in the same way by the class you want other classes to inherit from, as shown in the video. The difference being that Abstract forces the child class to Override it with a new method/function, while Virtual says you can if you want to; but calls itself instead if the child class does not Override it. This is useful to know because Abstract classes can just be empty, with only the name and passing argument requirements being created, while Virtual presumes that you've created a usable method/function in the parent class. I hope this was clear, and I hope it was correct. I only read one forum post for this, but it seemed logical.

  • @NeonDarius7843
    @NeonDarius78432 жыл бұрын

    More of this please!!! This was great! Well made! I wanna code like that in Unity! I literally think this would be useful for making platformers, RPGs, fighting games, Etc.

  • @attenurmi936
    @attenurmi9362 жыл бұрын

    Thanks! I've just started geting into Unity and coding and have already done a lot of if-soup. :D So this saves me a lot of headache in the feature.

  • @PabloPerroPerro
    @PabloPerroPerro4 жыл бұрын

    So well explained! Thank you

  • @hellhunter9478
    @hellhunter947810 ай бұрын

    This tutorial is pretty straight forward I like this approach it would make the player class look more human and also you get rid of the entire if statements from that class.

  • @nikolatasev4948
    @nikolatasev49482 жыл бұрын

    For a large game this is great, but for a small game having the states as enums is more than enough. Then handle input can call the right methiod like HandleInputStanding, and that can have a bunch of early returns to keep the if soup at bay.

  • @ChadWWolfe

    @ChadWWolfe

    2 жыл бұрын

    Absolutely! Actually, it really just depends on the use case even in larger games. State Machines should only be used in cases where there is complex state driven behavior. Otherwise, that becomes spaghetti code. Even the given example is far too simple to excuse a complete state machine.

  • @kotted
    @kotted2 жыл бұрын

    Nice. Recently learnt about the virtual functions so it's really nice to find use for them here

  • @whoisthiswhoknows
    @whoisthiswhoknows2 жыл бұрын

    I started comp sci this year and this is the first coding video I've actually understood. So I guess that class is useful.

  • @firemind2265

    @firemind2265

    2 жыл бұрын

    Happy to hear! Stay on it!

  • @chips409
    @chips4092 жыл бұрын

    Everybody gangster until the Italian guy starts coding spaghetti

  • @vizualwanderer
    @vizualwanderer2 жыл бұрын

    state machines are cool and have intrigued me a lot, however, once you're in Jump state you don't really handle "just jump functions," do you? You also need other functions in there to transition back/to run or idle state, no? So you're pretty much creating a class for every state and set state shares elements that invoke other states in them besides there main function.

  • @FurquimRafa
    @FurquimRafa3 жыл бұрын

    Great video! I do not consider myself an advanced programmer and I could understand everything

  • @ludicrouS_406
    @ludicrouS_4063 жыл бұрын

    I have just discovered Educational ASMR 😂. Btw the video was great and really well explained, thank you

  • @roguedrones
    @roguedrones2 жыл бұрын

    Firemind is a genius Nivmizzit would be proud of.

  • @kingofroms7224
    @kingofroms72243 жыл бұрын

    Wtf why youtube cant suggest you to me earlier but now thanks I found you keep upoloading

  • @user-bq8ty8qk4n
    @user-bq8ty8qk4n3 жыл бұрын

    Keep on keeping on! Great tutorial, thank you

  • @Gonzakoable
    @Gonzakoable3 жыл бұрын

    I'd actually move state to be a monobehavior component and create them only once needed. Move the transition logic to the machine state level

  • @KojiKazama
    @KojiKazama Жыл бұрын

    I really like this approach. About 5-6 years ago when I did some Unity dev, my code looked exactly like you described. If if if if if if attack1(). This really helps with chaining actions and tracking things like attack combos. Now you can easily specify in each state what the possible actions are. Attack1State will have ATTACK = Attack2State, ATTACK + JUMP = AerialAttack1State. Thank you for sharing.

  • @teawacrossman-nixom7696
    @teawacrossman-nixom76962 жыл бұрын

    Thank you I love the concept, food for thought

  • @gizel4376
    @gizel43762 жыл бұрын

    really nice! so if i understand well, this line: State = State.handleInput(); // is calling the function associated with the actual state, looking for some if statement(or even case i guess) that will either return a new state or the same state ?

  • @hernandeztorresederjairdej5564
    @hernandeztorresederjairdej55643 жыл бұрын

    Please do more videos like this for other kind of situations, for example how to handle the story mode of a game, cause I don't want to check if the player already talked with the npc each time🤣

  • @parsnipthepossum8962
    @parsnipthepossum89622 жыл бұрын

    I had to read the text in the thumbnail a couple times to realize it didn't said "code not better spaghetti" but "code better not spaghetti"

  • @khaliderrahaouy5930
    @khaliderrahaouy59302 жыл бұрын

    You helped me, Thank you friend !

  • @francoisulrich6404
    @francoisulrich64042 жыл бұрын

    Very helpful, thanks!

  • @elian_geser
    @elian_geser2 ай бұрын

    Hey Man! Super nice! I def learned smth from this video, smth great! U being a chill talker made it relaxing to learn. Some parts i felt like u took some time to get to the point but otherwise it is a super well explained tutorial👍 Thank you a lot!

  • @Rexvideowow
    @Rexvideowow11 ай бұрын

    I prefer the simplistic approach. if (AllTheseChecklists()) {...} That way, the code is readable, we know we are checking for things, and all those things can be isolated to the single function. As for AllTheseChecklists() itself, I prefer to use the traditional method of using a result. bool result = false; then you go: result = IsCharacterGrounded ? true : false; then on the next line you go: if (result) { result = IsCharacterAlive(); } and continue on in that fashion: if (result) { result = HasEnoughResources(); } and so on. This way, your code will always stop at the first point of failure and will return result; at the end of it. It is efficient.

  • @espermeadows1882
    @espermeadows18822 жыл бұрын

    Your way of teaching is sooo so nice, thank you 🙏

  • @betterlifeexe4378
    @betterlifeexe43782 жыл бұрын

    enum State { States, Here, Call , Methods, Or, Coroutines, When, Processed } internal void changeState (State state){} //this keeps it all in the same class and IMO more readable :)

  • @Anthonyfchannel

    @Anthonyfchannel

    2 жыл бұрын

    I do it so, but when I think of it, It would be way more simple to have a class for each state. It keeps the code shorter and it's easier then to add a new state without modifying the parent class.

  • @betterlifeexe4378

    @betterlifeexe4378

    2 жыл бұрын

    @@Anthonyfchannel ... or you can add a new state by adding an enum and method. I mean they both work, but I just don't see how managing several classes encapsulated by a namespace or document is easier than managing several elements in an enum at the top of a class encapsulating several methods. Nor do I see how it would be shorter or quicker.

  • @favour5442
    @favour5442 Жыл бұрын

    When 1.5x feels perfectly normal 🌝

  • @notarvis
    @notarvis2 жыл бұрын

    I was confused when I couldnt find skip ad button at the start of the video, because I thought I was being offered yet another ai tool :D

  • @ridlr9299
    @ridlr92992 жыл бұрын

    CharacterState should really be an abstract class for this example

  • @beeplove7
    @beeplove73 жыл бұрын

    Great tutorial.. Thanks a lot man

  • @Spaceman68ok
    @Spaceman68ok2 жыл бұрын

    Would it be better to make a CharacterState's default method return IdleState? Or maybe make a CharacterState class an interface for it to not have a default method and to not write virtuals and overrides? I'm not really experienced so I want to know.

  • @francescagreetham1804
    @francescagreetham18042 жыл бұрын

    I really enjoyed this!

  • @sealsharp
    @sealsharp7 ай бұрын

    So this was recommended to me by youtube as the thing i should absolutely watch on this beautiful sunday morning. And this seems really overengineered to me.

  • @user-uk9er5vw4c
    @user-uk9er5vw4c9 сағат бұрын

    "spaghetti code anxiety" you people are putting anxiety everywhere

  • @Gummypuss
    @Gummypuss25 күн бұрын

    I know I want large diverse move system this may help me in the future when I actually begin coding that nightmare.

  • @Gorgggg
    @Gorgggg3 жыл бұрын

    Exactly how I did it some years ago. But If sb is doing something like this in Unity, I would propose having the CharacterStates as monobehaviours themself, so they can expose properties to the unity editor. For example: class CharacterState: MonoBehaviour {...} class JumpState: CharacterState { public float JumpForce; //

  • @SMT-ks8yp

    @SMT-ks8yp

    Жыл бұрын

    Or you can store these data in a ScriptableObject and pass it to the state-classes with constructor.

  • @Larock-wu1uu
    @Larock-wu1uu2 жыл бұрын

    You got me at "sitting in the basement"! 🙂

  • @phatpingu
    @phatpingu2 жыл бұрын

    Duuuuuude... Your explanation.. You GET IT! Sometimes, when people explain things, they forget what it is like NOT to know something.. and assume that the listener is going to understand each thing.. but you managed to put your self in my shoes and YEAH! The result was: I was 100% able to follow everything you said, step by step.. on 2x speed! :-p hehehhe

  • @phatpingu

    @phatpingu

    2 жыл бұрын

    Subscribing in 3... 2... 1...

  • @Basil13ful
    @Basil13ful8 ай бұрын

    could be nice to set CharacterState as abstract and its method "handleInput" too, to force its child classes to implements it, and to prevent an parent instanciation :)

  • @simoxeh
    @simoxeh Жыл бұрын

    I liked the tutorial and I think I would have liked to see the jumpstate code also to get the full picture. I'm still confused as to how it works. I might have to write coffee and see myself. thanks for the starting point though

  • @popbob4780
    @popbob4780 Жыл бұрын

    mom can we have fireship? we have fireship at home fireship at home:

  • @goblinslayer6375
    @goblinslayer63753 жыл бұрын

    Firemind make your code great again.

  • @andersoncdz1
    @andersoncdz1 Жыл бұрын

    I guess using interface instead of inheritence would be more scalable and use a pattern like strategy maybe. Or use a dependency injection to a class that handles states, using interfaces .

  • @TheKr0ckeR
    @TheKr0ckeR2 жыл бұрын

    I like your humour! Thanks for great guide

  • @Cindy_Crawdad
    @Cindy_Crawdad Жыл бұрын

    that drawing could be album art for a cassette tape demo of a punk rock band called F.I.R.E.M.I.N.D.

  • @NikCification
    @NikCification2 жыл бұрын

    This video and tip was amazing!! Thank you, Sir. Please make more videos like this and provide more great coding tips. Thank you.

  • @raptorswire7212
    @raptorswire72123 жыл бұрын

    Great tutorial, but it would be great if you would show the whole finished code in the end

  • @saikiran-vw8ux
    @saikiran-vw8ux4 жыл бұрын

    Nailed it!

  • @1221fun
    @1221fun2 жыл бұрын

    thank you!!! it's really useful conception for me!!

  • @kalpolproductions8558
    @kalpolproductions8558 Жыл бұрын

    This guy slower than my brain! now i can understand! THANKS!

  • @swiatstdio5977
    @swiatstdio59772 жыл бұрын

    > "better coding" > method names starting with lowercase character Choose one

  • @romainsalvan6331
    @romainsalvan63314 жыл бұрын

    I think a much cleaner way to handle state management is to use an enum CharacterState

  • @TheLucausi

    @TheLucausi

    4 жыл бұрын

    could be much cleaner, but unmanageble sometimes. Do you want to fill enums with states or simply create a new state class that handle the entire state? If you think about it, where do you handle this enums check? it's here the trap.

  • @cb2818
    @cb28182 жыл бұрын

    earned my sub. you are a great teacher.

  • @unclerandy398
    @unclerandy3983 жыл бұрын

    Are there any other areas that the state machine works besides ai and player input

  • @NalinJ
    @NalinJ3 жыл бұрын

    Very nicely explained :)

  • @kboltiz
    @kboltiz2 жыл бұрын

    Hey I need help. Is there a way I could tell Unity which state can be reached through the current state (preferably without if statements?), I like I want Idle -> Attack and Idle -> Jump but I don't want Attack -> Jump. How do I do this?

  • @algorithm1313
    @algorithm13132 жыл бұрын

    Not a game dev A soft dev Nice video super helpful 🔥🔥

  • @int4_t
    @int4_t2 жыл бұрын

    If there are nested ifs, then I would just do ands (&&) or &. Both of them work, but if you have too many booleans, then only if you're gonna use it at that if just paste the boolean code at that if and delete the original if

  • @tin2001
    @tin20012 жыл бұрын

    4:10 - I feel old thinking about setting the school Macs to all play that quack sound... Back in 1993.

  • @sup3rsmash8
    @sup3rsmash82 жыл бұрын

    I would probably create the states in each their own respective field before the player spawns instead of creating a new one every time a state needs to be changed, just to save on memory garbage. But other than that, good tutorial!

  • @bugsephbunnin4576
    @bugsephbunnin45762 жыл бұрын

    This is literally what I was looking for, thank you

  • @firemind2265

    @firemind2265

    2 жыл бұрын

    Very much welcome :)

  • @zielony1212
    @zielony12122 жыл бұрын

    Yandere Dev should watch this video...

  • @falxie_
    @falxie_2 жыл бұрын

    How do you handle situations where you can be in multiple "states?"

  • @noli-timere-crede-tantum
    @noli-timere-crede-tantum2 жыл бұрын

    5:09 so your character can't jump unless it's idle? Is that so you can avoid needing extra conditional checks?

  • @AlFredo-sx2yy

    @AlFredo-sx2yy

    2 жыл бұрын

    that's because he's lame at programming, simple as that.

  • @Betruet
    @Betruet2 жыл бұрын

    Great video well explained :]

  • @pwnwin
    @pwnwin2 жыл бұрын

    I’m pretty sure this video taught me how to make double jumps among many other things lol

  • @TheBoxyBear
    @TheBoxyBear2 жыл бұрын

    Interesting idea, however it can lead to lot of duplicate code for checking in out and creating states, especially when actions are valid in multiple states. What I would do is check inp at a centralised space and call the methods in the state related to the various actions the player can take. The base state provides empty implementations for each one and each state specific class only has to worry about implementing the valid actions its state.

  • @TheBoxyBear

    @TheBoxyBear

    2 жыл бұрын

    Also this really only works with single state and not combinations of states. You can always mimick them by creating a new state that babeces as two existing states combined but you will end up repeating code since you can't reference instance methods of a now non-existent state. Another completely different approach would be to define the state as a set of properties like AttackReady, JumpReady, Stunned. Instead of having to check everything when performing an action, you can just reference the property as a boolean and do the action if the property says the state allows it. You can also have the getters call other getters to simplify them too. You can start by defining each state property as an auto-property you assign manually somehwere and as your add mechanics, you can redefine the properties with a custom getter without having to change state checks

  • @hans_xwh
    @hans_xwh2 жыл бұрын

    I like to use like a thousand variables, it makes me look like im coding a lot :)