I love how slowly you explain stuff. It easy to understand the point :))
@Michael_H_Nielsen4 жыл бұрын
I think the information is good but please speak faster. I sat the speed to 1.5 :-)
@coemgeincraobhach2362 жыл бұрын
Haha, I have it at X2, and went to look to make it faster.
@midnatheblackrobe2 жыл бұрын
Had to watch at 2x speed to not ram my head into a wall.
@doismilho2 жыл бұрын
Lol me too. Funny that the top comment is exactly this
@TexMackerson2 жыл бұрын
He's explaining MStates to people who write spaghetti code, he HAS to go slow
@coemgeincraobhach2362 жыл бұрын
Ah to be fair it is a good video. More a reflection of my impatience than anything 😅
@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.
@Konitama2 жыл бұрын
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 Жыл бұрын
Yay, now it's spaghetti that's more annoying to trace/read
@nathanfranck5822 Жыл бұрын
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 Жыл бұрын
@@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 !
@PixelPressChannel8 ай бұрын
@@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
@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.
@ozzyfromspace2 жыл бұрын
I agree with you. Functions are more ergonomic imo
@magnusm42 жыл бұрын
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.
@KojiKazama2 жыл бұрын
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 Жыл бұрын
Agreed. I'd probably just opt for making CharacterState an enum and have that handled it in it's own function.
@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
@mighty32572 жыл бұрын
Dictionary for the lookup… How did I not think of that? Thanks a lot for the idea.
@tatoforever2 жыл бұрын
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-cc4ft2 жыл бұрын
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.
@101touchapps2 жыл бұрын
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.
@LifeLedLucid2 жыл бұрын
@@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
@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.
@ZeroSleap4 жыл бұрын
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.
@thepatchinatior2 жыл бұрын
I think that was the intention but the author wanted to keep it as simple as possible
@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.
@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.
@NikolaZagorac2 жыл бұрын
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.
@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.
@dede6giu2 жыл бұрын
not really, as nesting if statments usually causes more expense to the processing than using classes
@spectrecular97212 жыл бұрын
@@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
@lanik81632 жыл бұрын
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.
@detuneCris2 жыл бұрын
@@dede6giu not at all lol, get your facts straight.
@PixelPressChannel8 ай бұрын
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.
@astrahcat1212 Жыл бұрын
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).
@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
@GlitchyPSI2 жыл бұрын
Guard clause 💙
@patrickp41752 жыл бұрын
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.
@durrium2 жыл бұрын
I agree with you man, this was way overkill
@accountdua93752 жыл бұрын
@@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..
@seb68614 жыл бұрын
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.
@BobrLovr3 жыл бұрын
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 .
@PearlyTate3 жыл бұрын
@@BobrLovr true
@chronosbat3 жыл бұрын
@@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.
@aleksandarpantic87324 жыл бұрын
Put it at x1.25 speed and still slow...
@firemind22654 жыл бұрын
Maybe put it on x2.00 then ? :D
@aleksandarpantic87324 жыл бұрын
@@firemind2265 good video, I'll give you that. Keep pushing, very good video editing 👌😁
@Lantertronics2 жыл бұрын
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.
@1001HELL2 жыл бұрын
I'm dumb and need this pace.
@giampaolomannucci82819 ай бұрын
it's better to speed up a slow video than slow down a fast one, audio is less messed up
@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)
@milankeravica71722 жыл бұрын
Wouldn't that make it a state machine, while the video demonstrates the usage of a state design pattern?
@TheExiledMeriler2 жыл бұрын
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
@2simmy22 жыл бұрын
@@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.
@DoorThief2 жыл бұрын
Not to mention that you won't have a bunch of heap allocations that need to be garbage collected
@Hersatz2 жыл бұрын
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.
@mintesnotmelese65524 жыл бұрын
Men Please I want a bunch of Tutorials on State machine pattern programming, You're now officially my fav KZbinr. keep doing this stuff a lot I love it! :)
@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
@LuRybz2 жыл бұрын
could you provide an example? Interesting
@johnleorid2 жыл бұрын
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.
@casefc3s2 жыл бұрын
@@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.
@casefc3s2 жыл бұрын
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.
@delanmorstik76192 жыл бұрын
@@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!
@ScooterCat644 ай бұрын
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.
@garebeargaming92814 жыл бұрын
Spent the past week having a headache and a half trying to fully implement a state machine. And damn you just alleviated my headache.
@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.
@RawDawginRoLo3 ай бұрын
I like the speed of the voice. I can always adjust it but for a beginner like myself it allows me to keep up
@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.
@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()
@Neran2802 жыл бұрын
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.
@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
@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.
@Gomace9 ай бұрын
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.
@juaecheverria02 жыл бұрын
Come back, this tutorial was perfect i need more.
@firemind22652 жыл бұрын
I'll be back 8-)
@juaecheverria02 жыл бұрын
@@firemind2265 you the best, cant wait.
@Rexvideowow Жыл бұрын
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.
@KojiKazama2 жыл бұрын
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.
@3_14pie3 жыл бұрын
You have no idea of how much this video changed everything for me
@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!
@roguedrones2 жыл бұрын
Firemind is a genius Nivmizzit would be proud of.
@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.
@firemind22652 жыл бұрын
Happy to hear! Stay on it!
@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.
@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.
@KawaiiKodeDaddy2 жыл бұрын
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.
@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.
@kalpolproductions8558 Жыл бұрын
This guy slower than my brain! now i can understand! THANKS!
@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.
@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.
@ridlr92992 жыл бұрын
CharacterState should really be an abstract class for this example
@elian_geser8 ай бұрын
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!
@sonsai103 жыл бұрын
tutorial was so great and funny, can't wait for the next advanced coding topic
@DrClementShimizu2 ай бұрын
interesting to see state implemented as a class... i can see the benefit
@ftwgunnerpwns2 жыл бұрын
I really like your explaining speed, it's way easier to digest than most tuts, thank you!
@kingofroms72243 жыл бұрын
Wtf why youtube cant suggest you to me earlier but now thanks I found you keep upoloading
@dead.96282 жыл бұрын
Apparently the AND operator DOESNT exist
@liam34912 жыл бұрын
Your code would still be a mess to maintain, AND operator or not. Use proper design principles.
@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 ?
@dimak.63234 жыл бұрын
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!
@makeshiftgames37992 жыл бұрын
watch it on 1.5x speed, and it's about normal
@phatpingu3 жыл бұрын
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
@phatpingu3 жыл бұрын
Subscribing in 3... 2... 1...
@ludicrouS_4064 жыл бұрын
I have just discovered Educational ASMR 😂. Btw the video was great and really well explained, thank you
@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-sx2yy2 жыл бұрын
that's because he's lame at programming, simple as that.
@kotted2 жыл бұрын
Nice. Recently learnt about the virtual functions so it's really nice to find use for them here
@tin20012 жыл бұрын
4:10 - I feel old thinking about setting the school Macs to all play that quack sound... Back in 1993.
@dolphin_dog2 жыл бұрын
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.
@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"
@Basil13ful Жыл бұрын
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 :)
@1221fun2 жыл бұрын
thank you!!! it's really useful conception for me!!
@maikeltoxix17162 жыл бұрын
would like to see more advanced coding. most tutorials are kinda plain.. thanks, for a newbie like me its good understandable
@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.
@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 KZbin video. Perhaps you're up to the challenge? Hopefully someone is. Thanks,
@teawacrossman-nixom76962 жыл бұрын
Thank you I love the concept, food for thought
@maow92402 жыл бұрын
is it just me? setting video speed to 2X feels like just a normal speed video?
@Jamesthe12 жыл бұрын
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.
@favour54422 жыл бұрын
When 1.5x feels perfectly normal 🌝
@algorithm13132 жыл бұрын
Not a game dev A soft dev Nice video super helpful 🔥🔥
@zielony12122 жыл бұрын
Yandere Dev should watch this video...
@lyflfflyflff3 жыл бұрын
I don't understand where all these 'isGrouded' and '!isRunning' in the state machine?
@chips4092 жыл бұрын
Everybody gangster until the Italian guy starts coding spaghetti
@simoxeh2 жыл бұрын
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
@Zabzuro14 жыл бұрын
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.
@TheLucausi4 жыл бұрын
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.
@firemind22654 жыл бұрын
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?
@firemind22654 жыл бұрын
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.
@espermeadows18822 жыл бұрын
Your way of teaching is sooo so nice, thank you 🙏
@Larock-wu1uu2 жыл бұрын
You got me at "sitting in the basement"! 🙂
@SuperWarZoidАй бұрын
wait once u return the jump state, where do you actually call the jump() method?
@pwnwin2 жыл бұрын
I’m pretty sure this video taught me how to make double jumps among many other things lol
@K3rhos Жыл бұрын
Hummm... this is not really better, it's a completely overkill solution for this. Just use inverted if + return;, to get a clean list of the conditions you don't want, so you don't get a staircase of if statement. Problem solved. In most cases, try to don't overengineer your code to get a "clean code" because like in this case you are trying to clean your code with overkill solution that just add more CPU consumption and will be probably useless in the future. What you need to ask when trying to clean your code is: "Do I really need to improve this or maybe it's not worth ?"
@astrahcat1212 Жыл бұрын
I agree, but it's not really a matter of CPU optimization. I think it's more so that OOP programming thinks reverse of procedural programming. OOP you need an object to do a thing, and procedural you write all the functions and then figure out what needs to use the functions.
@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.
@francescagreetham18042 жыл бұрын
I really enjoyed this!
@Gummypuss6 ай бұрын
I know I want large diverse move system this may help me in the future when I actually begin coding that nightmare.
@betterlifeexe43783 жыл бұрын
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 :)
@Anthonyfchannel3 жыл бұрын
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.
@betterlifeexe43783 жыл бұрын
@@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.
@romainsalvan63314 жыл бұрын
I think a much cleaner way to handle state management is to use an enum CharacterState
@TheLucausi4 жыл бұрын
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.
@robertonome24482 жыл бұрын
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
@TidaliCreative7 ай бұрын
0:18 literally how I sat there hahaha
@swiatstdio59772 жыл бұрын
> "better coding" > method names starting with lowercase character Choose one
@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?
@diligencehumility69712 жыл бұрын
When you made the "your mom" joke, I had to leave a like!
@ducodarling2 жыл бұрын
*Not a game dev* What I don't get is the performance. It might not make-or-break anything, but how many objects need to be created and updated just to jump? At the very least, you could make an array of state constants, and store an index on that array instead of all these (new) state objects. It just seems like there will be a lot more jumping, than jumping + other things, so why not aim to make jumping as smooth as possible?
How do you handle situations where you can be in multiple "states?"
@APNDisco3 жыл бұрын
People who disliked were offended by the mom joke 😂 great work! You earned a new like and sub
@raptorswire72124 жыл бұрын
Great tutorial, but it would be great if you would show the whole finished code in the end
@Mefrius Жыл бұрын
Why you make gaps between words so big? Because of that it's hard to listen and i had turn on 1.5x speed (which is not good for algorithms)
@PearlyTate3 жыл бұрын
I did exactly what you did and it doesnt work, do you think i may have lost something?
@richardpitak96693 жыл бұрын
why not to use logic operators?
@sup3rsmash83 жыл бұрын
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!
@4R8YnTH3CH33F2 жыл бұрын
Meh, I agree with the problem but I think this solution is not the one. Splitting everything up into a million classes simply hides the clutter and can lead to debugging becoming even harder. Some systems in a game are going to be complex, and obscuring the true complexity of a system by hiding it in a bunch of helper classes is not doing anything to actually address the complexity, it merely creates an illusion of simplicity.
@Booyah2 жыл бұрын
I think this is the first video I've watched on youtube where it takes SO LOOONNNGGG to get to the point, even on x2 speed. You're going to lose half of your audience before you even begin to introduce the solution if you're spending this long going over and over and over the problem itself, especially at this rate of speech.
@ClassicBentobox2 жыл бұрын
Is this a really long roundabout way of using an array?
@gorkemvids48393 ай бұрын
Btw, you shouldn't handle inputs in the character's update. but good advice. use state machines
@torch47622 жыл бұрын
God damn, the intro is fantastic. How would using enums compare?
@moviemaker3102 жыл бұрын
Why are your methods in camel case? Clear code also means adhering to the language's standards. I'd also reconsider returning a completely new object every time something else happens. At least cache the states.