Better Coding in Unity With Just a Few Lines of Code

preview_player
Показать описание
Get your code looking nice, clean and maintainable, by applying this simple pattern for your state management in Unity.

Рекомендации по теме
Комментарии
Автор

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

martinmica
Автор

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.

Zicore
Автор

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.

davedoublee-indiegamedev
Автор

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

Gortart
Автор

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

Michael_H_Nielsen
Автор

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

mintesnotmelese
Автор

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.

TGameDev
Автор

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.

ZeroSleap
Автор

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

_pie
Автор

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.

hellhunter
Автор

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.

andythedishwasher
Автор

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.

LordBordNoob
Автор

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

garebeargaming
Автор

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

ocahos
Автор

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.

spectrecular
Автор

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.

NikolaZagorac
Автор

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 <string, Action> which represents state then simply run the method for each state. it also makes declaring each state very simple and concise

kreed
Автор

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)

simmy
Автор

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!

polarisinglol
Автор

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.

seb
join shbcf.ru