Better Coding in Unity With Just a Few Lines of Code

298,683
0
Published 2020-04-02

All Comments (21)
  • @Gortart
    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
  • @martinmica4260
    I love how slowly you explain stuff. It easy to understand the point :))
  • @Zicore47
    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.
  • @polarisinglol
    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!
  • Men Please I want a bunch of Tutorials on State machine pattern programming, You're now officially my fav Youtuber. keep doing this stuff a lot I love it! :)
  • @TGameDev
    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.
  • @3_14pie
    You have no idea of how much this video changed everything for me
  • 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.
  • Spent the past week having a headache and a half trying to fully implement a state machine. And damn you just alleviated my headache.
  • @ZeroSleap
    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.
  • @LordBordNoob
    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.
  • @Gomace
    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.
  • @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.
  • @dimak.6323
    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!
  • @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.
  • @7oca7hos7
    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
  • @roguedrones
    Firemind is a genius Nivmizzit would be proud of.
  • 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.
  • @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.