Better Coding in Unity With Just a Few Lines of Code

Поділитися
Вставка
  • Опубліковано 27 січ 2025

КОМЕНТАРІ • 511

  • @Zicore47
    @Zicore47 3 роки тому +183

    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 3 роки тому +10

      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 Рік тому +4

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

    • @nathanfranck5822
      @nathanfranck5822 Рік тому +1

      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 Рік тому

      @@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 !

    • @nathanfranck5822
      @nathanfranck5822 10 місяців тому

      @CardrisCreations-iq7zs You can easily get a nice structural single function with a small amount of state using enums for state and switch statements. All nicely packed together and readable top-to-bottom - that is a direct 1-to-1 match for the code-flow he suggests using interfaces

  • @looty20-q8q
    @looty20-q8q Рік тому +10

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

  • @Michael_H_Nielsen
    @Michael_H_Nielsen 4 роки тому +828

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

    • @coemgeincraobhach236
      @coemgeincraobhach236 3 роки тому +29

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

    • @midnatheblackrobe
      @midnatheblackrobe 3 роки тому +25

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

    • @doismilho
      @doismilho 3 роки тому +9

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

    • @TexMackerson
      @TexMackerson 3 роки тому +58

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

    • @coemgeincraobhach236
      @coemgeincraobhach236 3 роки тому +12

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

  • @ZeroSleap
    @ZeroSleap 4 роки тому +67

    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 3 роки тому +5

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

    • @jarrettonions3392
      @jarrettonions3392 Рік тому

      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.

    • @KulaGGin
      @KulaGGin 12 годин тому

      _" believe the CharacterState would be better as an Interface"_
      No, it wouldn't.
      _"as there's no real reason for a base class implementation of handleInput"_
      No. There is. It's called hierarchical state machine. You put the default implementation in the most base class and then you either extend or override in the classes that inherit.
      In this case handleInput might be just empty method and you only override it in states that need to handle it. And there are many many states that don't need to handle input: transitional states, getting hit states.
      If you ever do it on a real project, you'll quickly find out that Interface is a wrong approach, you will end up with much more code compared to a base class.
      I currently have a hierarchical state machine with 20 character states and interface-based solution is just a nightmare.

  • @andythedishwasher1117
    @andythedishwasher1117 2 роки тому +6

    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.

  • @davedoublee-indiegamedev8633
    @davedoublee-indiegamedev8633 3 роки тому +191

    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 роки тому +7

      I agree with you. Functions are more ergonomic imo

    • @magnusm4
      @magnusm4 2 роки тому +2

      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 2 роки тому

      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 2 роки тому

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

  • @TGameDev
    @TGameDev 3 роки тому +10

    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.

  • @mintesnotmelese6552
    @mintesnotmelese6552 4 роки тому +33

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

  • @NikolaZagorac
    @NikolaZagorac 2 роки тому +4

    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.

  • @spectrecular9721
    @spectrecular9721 3 роки тому +20

    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 3 роки тому +2

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

    • @spectrecular9721
      @spectrecular9721 3 роки тому +10

      @@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 3 роки тому +11

      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 3 роки тому +6

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

  • @2simmy2
    @2simmy2 3 роки тому +62

    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 3 роки тому +4

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

    • @TheExiledMeriler
      @TheExiledMeriler 3 роки тому +11

      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 3 роки тому

      @@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 3 роки тому +3

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

    • @Hersatz
      @Hersatz 3 роки тому +10

      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.

  • @polarisinglol
    @polarisinglol 3 роки тому +5

    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!

  • @garebeargaming9281
    @garebeargaming9281 4 роки тому +6

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

  • @seb6861
    @seb6861 4 роки тому +49

    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.

    • @BobrLovr
      @BobrLovr 3 роки тому +33

      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 .

    • @PearlyMishima
      @PearlyMishima 3 роки тому +2

      @@BobrLovr true

    • @chronosbat
      @chronosbat 3 роки тому +3

      @@BobrLovr 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.

  • @LordBordNoob
    @LordBordNoob 2 роки тому +15

    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.

  • @kreed1415
    @kreed1415 3 роки тому +61

    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 3 роки тому +7

      could you provide an example? Interesting

    • @johnleorid
      @johnleorid 3 роки тому

      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 3 роки тому

      @@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 3 роки тому

      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 3 роки тому

      @@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!

  • @7oca7hos7
    @7oca7hos7 3 роки тому +107

    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 3 роки тому +6

      Guard clause 💙

    • @patrickp4175
      @patrickp4175 3 роки тому +16

      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 2 роки тому

      I agree with you man, this was way overkill

    • @accountdua9375
      @accountdua9375 2 роки тому +9

      @@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..

  • @thatoneuser8600
    @thatoneuser8600 3 роки тому +55

    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 3 роки тому +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.

  • @hellhunter9478
    @hellhunter9478 Рік тому

    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.

  • @Gortart
    @Gortart 3 роки тому +358

    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 3 роки тому +4

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

    • @tatoforever
      @tatoforever 2 роки тому +1

      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 роки тому +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 2 роки тому +11

      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 2 роки тому +8

      @@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

  • @3_14pie
    @3_14pie 3 роки тому

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

  • @elian_geser
    @elian_geser 10 місяців тому

    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!

  • @astrahcat1212
    @astrahcat1212 Рік тому +2

    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).

  • @ChinchillaDave
    @ChinchillaDave 4 роки тому +49

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

  • @whoisthiswhoknows
    @whoisthiswhoknows 3 роки тому +6

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

  • @KojiKazama
    @KojiKazama 2 роки тому +4

    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.

  • @juaecheverria0
    @juaecheverria0 3 роки тому +2

    Come back, this tutorial was perfect i need more.

  • @ScooterCat64
    @ScooterCat64 6 місяців тому

    As long as the code does what it's supposed to without performance issues and is easy to read and understand by the programmer, the code is fine.

  • @CastielQuinzel
    @CastielQuinzel 3 роки тому +2

    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.

  • @nikolatasev4948
    @nikolatasev4948 3 роки тому +13

    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.

    • @KawaiiKodeDaddy
      @KawaiiKodeDaddy 3 роки тому +4

      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.

  • @ftwgunnerpwns
    @ftwgunnerpwns 3 роки тому +6

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

  • @RawDawginRoLo
    @RawDawginRoLo 5 місяців тому

    I like the speed of the voice. I can always adjust it but for a beginner like myself it allows me to keep up

  • @sonsai10
    @sonsai10 4 роки тому +14

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

  • @aleksandarpantic8732
    @aleksandarpantic8732 4 роки тому +75

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

    • @firemind2265
      @firemind2265  4 роки тому +41

      Maybe put it on x2.00 then ? :D

    • @aleksandarpantic8732
      @aleksandarpantic8732 4 роки тому +8

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

    • @Lantertronics
      @Lantertronics 2 роки тому +4

      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 роки тому +1

      I'm dumb and need this pace.

    • @giampaolomannucci8281
      @giampaolomannucci8281 11 місяців тому +4

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

  • @TidaliCreative
    @TidaliCreative 9 місяців тому +1

    0:18 literally how I sat there hahaha

  • @Gomace
    @Gomace 11 місяців тому

    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.

  • @notarvis
    @notarvis 2 роки тому +1

    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

  • @roguedrones
    @roguedrones 3 роки тому

    Firemind is a genius Nivmizzit would be proud of.

  • @Rexvideowow
    @Rexvideowow Рік тому +1

    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.

  • @kingofroms7224
    @kingofroms7224 3 роки тому +2

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

  • @dimak.6323
    @dimak.6323 4 роки тому

    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!

  • @matthewmathis62
    @matthewmathis62 3 роки тому +1

    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 UA-cam video. Perhaps you're up to the challenge? Hopefully someone is.
    Thanks,

  • @phatpingu
    @phatpingu 3 роки тому +1

    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 3 роки тому

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

  • @1221fun
    @1221fun 2 роки тому

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

  • @chips409
    @chips409 3 роки тому

    Everybody gangster until the Italian guy starts coding spaghetti

  • @espermeadows1882
    @espermeadows1882 3 роки тому

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

  • @kotted
    @kotted 3 роки тому

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

  • @teawacrossman-nixom7696
    @teawacrossman-nixom7696 3 роки тому

    Thank you I love the concept, food for thought

  • @attenurmi936
    @attenurmi936 3 роки тому

    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.

  • @ParsnipThePossum
    @ParsnipThePossum 3 роки тому

    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"

  • @kalpolproductions8558
    @kalpolproductions8558 2 роки тому

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

  • @sealsharp
    @sealsharp Рік тому

    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.

  • @DrClementShimizu
    @DrClementShimizu 4 місяці тому

    interesting to see state implemented as a class... i can see the benefit

  • @magnusm4
    @magnusm4 3 роки тому +3

    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.

  • @diligencehumility6971
    @diligencehumility6971 3 роки тому

    When you made the "your mom" joke, I had to leave a like!

  • @saisankeerthredybommana754
    @saisankeerthredybommana754 3 роки тому

    Very nice video bro 👍🏻

  • @algorithm1313
    @algorithm1313 3 роки тому

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

  • @ludicrouS_406
    @ludicrouS_406 4 роки тому +2

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

  • @ra8620
    @ra8620 3 роки тому

    Inheritance is block chain rules primary keys reference of foreign keys like rules

  • @vorlon478
    @vorlon478 3 роки тому

    Awesome job explaining this complex topic! Keep it up!

  • @Gummypuss
    @Gummypuss 8 місяців тому

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

  • @tin2001
    @tin2001 3 роки тому

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

  • @ridlr9299
    @ridlr9299 3 роки тому +1

    CharacterState should really be an abstract class for this example

  • @francescagreetham1804
    @francescagreetham1804 3 роки тому

    I really enjoyed this!

  • @Basil13ful
    @Basil13ful Рік тому +1

    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 :)

  • @ItsHelmetBro
    @ItsHelmetBro 2 місяці тому

    Long story short:
    If you are working with multiple bools just combine them in a sequence of binary-like code for example "int check = 000000 "each zero means false and when you need to check something just use if (check = 100000) {//do something} and i if you want it to be true just do check += 100000 for the first "bool" or check += 1 for the last one etc...

  • @Larock-wu1uu
    @Larock-wu1uu 3 роки тому

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

  • @betterlifeexe
    @betterlifeexe 3 роки тому +2

    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 3 роки тому

      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.

    • @betterlifeexe
      @betterlifeexe 3 роки тому

      @@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.

  • @simoxeh
    @simoxeh 2 роки тому

    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

  • @romainsalvan6331
    @romainsalvan6331 4 роки тому +2

    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.

  • @andersoncdz1
    @andersoncdz1 2 роки тому

    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 .

  • @bugsephbunnin4576
    @bugsephbunnin4576 3 роки тому +1

    This is literally what I was looking for, thank you

  • @maikeltoxix1716
    @maikeltoxix1716 2 роки тому

    would like to see more advanced coding. most tutorials are kinda plain..
    thanks, for a newbie like me its good understandable

  • @cb2818
    @cb2818 3 роки тому

    earned my sub. you are a great teacher.

  • @maow9240
    @maow9240 2 роки тому +1

    is it just me? setting video speed to 2X feels like just a normal speed video?

  • @dead.9628
    @dead.9628 3 роки тому +3

    Apparently the AND operator DOESNT exist

    • @liam3491
      @liam3491 3 роки тому

      Your code would still be a mess to maintain, AND operator or not. Use proper design principles.

  • @Zabzuro1
    @Zabzuro1 4 роки тому +4

    Creating a new object for every input is a terrible design choice. In your way, you do not change the state, you create a state every time you want to change state. More "correct" way to achieve state machine thing is, once you need a state just simply create it when you want to change the state don't return a new state, just find the same old state's reference and return it instead.

    • @TheLucausi
      @TheLucausi 4 роки тому

      I agree with the perfomance issues that this guys do. Allocate a new state everytime we need it it's not worth at all. Instead create a state object that is accessible in easy way.

    • @firemind2265
      @firemind2265  4 роки тому +1

      Hey there,
      not sure I get your point. Are you saying that if there is input that does not change the state, returning the old state is more efficent? Because that is pretty much what I propose here (see 13:47). If the input does not affect state, return this. Which is the reference to the previous state. But I'm probably misreading your comment. Can you maybe elaborate a little bit further?

    • @firemind2265
      @firemind2265  4 роки тому +1

      Hey there, thanks for the comment.
      I totally get your point, however I believe these are two different approaches in programming you can take. Yours is more on the object oriented side, where one object contains the state over its lifetime, while the one I'm proposing here is more on the functional side, which imposes that objects are immutable, which means if you wan't to change the object, you rather create a new one. I get that this may seem as it would introduce performance issues, however due to garbage collection and modern hardware creating new Objects will 100% not be the performance bottleneck of the game unless you are building games for very low end hardware like Arduino etc, but then you probably don't want to use C# and Unity in the first place.
      But yeah you can 100% also go with the more Object oriented approach, however I have found this one to be better read- and maintainable, in the end it comes down to what you feel most comfortable with.

  • @TheBoxyBear
    @TheBoxyBear 2 роки тому

    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

  • @Jamesthe1
    @Jamesthe1 3 роки тому

    Using objects for states is over-engineering imo. The real sin here is not using an input event and state enums.
    When input is received, it should have its own separate function. This can be achieved by creating a function with a name like "OnInput," then adding the function to InputSystem.onEvent with +=, and then subtracting it in OnDestroy(). Relevant states should be checked and updated here.
    Next, our state. "Dead," "Jumping," and "OnGround" never happen at the same time, so it's better to put these in an enum and check for the desired state in our OnInput function. As per movement (if we don't want to create separate JumpingMoving states), we can have another state enum to contain "Still," "Walking," and "Running." Adjust this and compact it to how you desire; the code is much more flexible however with a single state enum.
    Our objective here is to make our code not just clean, but manageable too. If we create objects, this will lead to "clean" code with extra work.

  • @vizualwanderer
    @vizualwanderer 3 роки тому +4

    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.

  • @gorkemvids4839
    @gorkemvids4839 5 місяців тому

    Btw, you shouldn't handle inputs in the character's update. but good advice. use state machines

  • @pietrofirmino
    @pietrofirmino 2 роки тому

    Success my friend!

  • @dolphin_dog
    @dolphin_dog 2 роки тому

    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.

  • @raptorswire7212
    @raptorswire7212 4 роки тому +10

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

  • @lyflfflyflff
    @lyflfflyflff 3 роки тому +1

    I don't understand where all these 'isGrouded' and '!isRunning' in the state machine?

  • @richardpitak9669
    @richardpitak9669 4 роки тому +2

    why not to use logic operators?

  • @favourdev
    @favourdev 2 роки тому +2

    When 1.5x feels perfectly normal 🌝

  • @liamoconnor7423
    @liamoconnor7423 Рік тому

    I'd just use an enum in this case, have different functions for different states, then have each state's functions in their own region for ease of finding the code.
    Huge file, but organised

  • @josephsmith5110
    @josephsmith5110 4 роки тому +2

    It should be noted that this comes with a (in most cases negligible) penalty to performance because it uses dynamic dispatch instead of static dispatch.

  • @notfound8392
    @notfound8392 3 роки тому

    Why subtitles are unavailable ?

  • @makeshiftgames3799
    @makeshiftgames3799 2 роки тому +1

    watch it on 1.5x speed, and it's about normal

  • @Gonzakoable
    @Gonzakoable 4 роки тому

    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

  • @DeathxStrike18
    @DeathxStrike18 3 роки тому +1

    or use a switch statement...
    or if (!isdead & isgrounded & !ismoving) dont need to nest

  • @kclmnop4372
    @kclmnop4372 3 роки тому

    I'm new to code... wondering why we couldn't just make another bool variable ableToAttack that checks all these conditions...
    Then just have
    If (ableToAttack && mouseclick)

  • @TheKr0ckeR
    @TheKr0ckeR 3 роки тому

    I like your humour! Thanks for great guide

  • @APNDisco
    @APNDisco 3 роки тому

    People who disliked were offended by the mom joke 😂 great work! You earned a new like and sub

  • @robertonome2448
    @robertonome2448 3 роки тому +1

    I still to date wonder why and how people don’t use or have never heard of state machines… it’s like trying to build a house and punching the nails with your bare hands instead of using a hammer

  • @pwnwin
    @pwnwin 3 роки тому

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

  • @SuperWarZoid
    @SuperWarZoid 3 місяці тому

    wait once u return the jump state, where do you actually call the jump() method?

  • @khaliderrahaouy5930
    @khaliderrahaouy5930 3 роки тому

    You helped me, Thank you friend !