The State Pattern (C# and Unity) - Finite State Machine

แชร์
ฝัง
  • เผยแพร่เมื่อ 15 มิ.ย. 2024
  • The state pattern is a programming pattern that is also known as a Finite State Machine or FSM is a pattern that can be very useful for systems with a small to a medium number of distinct states or behaviors. The pattern can help to clean up and make it very clear exactly WHAT code is running.
    Game Programming Pattern Book (affiliate): amzn.to/315mVBg
    Blog Post on State Pattern: onewheelstudio.com/blog/2020/...
    Project Files: github.com/onewheelstudio/Pro...
    Become A Channel Member: / @onewheelstudio
    My video and streaming kit: kit.co/onewheelstudio/tutoria...
    Timecodes
    Intro 0:00
    Project Description 0:50
    Programming with IFs 1:10
    State Pattern Simple 2:04
    State Pattern Class-Based 5:03
    Final Thoughts 8:52
    Outtakes 9:52
    Discord: discord.onewheelstudio.com
    Patreon: / onewheelstudio
    Twitter: / onewheelstudio
    Devlog: onewheelstudio.com/
    Twitch: / onewheelstudio
    #UnityTutorial #GameDevelopment #programmingpatterns #csharp #statepattern #finitiestatemachine #fsm
  • ภาพยนตร์และแอนิเมชัน

ความคิดเห็น • 121

  • @OneWheelStudio
    @OneWheelStudio  4 ปีที่แล้ว +10

    Is there a programming pattern you’d like to see me cover? Which one?
    For those who like text-based resources, you can check my blog post on the state pattern here: onewheelstudio.com/blog/2020/6/16/the-state-pattern

    • @darryljf7215
      @darryljf7215 3 ปีที่แล้ว +1

      Decorator pattern ?

    • @beri4138
      @beri4138 3 ปีที่แล้ว

      Anything about AI that you can explain without high-level math would be great.
      Books tend to go too far into the kind of math that I don't understand.

    • @Im_RajSingh
      @Im_RajSingh ปีที่แล้ว

      Yes , hierarchical state machine.

  • @MQNGameDev
    @MQNGameDev 2 ปีที่แล้ว +10

    Great video. I use the state pattern quite regularly. I generally add a constructor to each State and pass in the appropriate data that each state needs to work with. Also in my interface I add void OnEnter() and void OnExit() method(S), and in update simply test if the returned value from the current state is different. If so, run OnExit() on it, then switch the current state to the returned state then call OnEnter() on it. This allows a nice way to reset counters, trigger animations, play sound effects, etc when the state is entered and do any cleanup when it is exited.

  • @DonDisainer
    @DonDisainer 3 ปีที่แล้ว +7

    very professional way to make a tutorial, hope every tutorial where like this

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +3

      Thanks for the kind words. I'm definitely liking this style. Also good to know that after 15 years in a classroom I can communicate with folks ;)

  • @IreneTorrubia
    @IreneTorrubia 3 ปีที่แล้ว +4

    I really enjoyed your video! Straightforward, to the point, with clear examples. Awesome!!

  • @iDerp69
    @iDerp69 3 ปีที่แล้ว +4

    Simplest and cleanest state pattern I've seen.

  • @betterlifeexe4378
    @betterlifeexe4378 3 ปีที่แล้ว +6

    What a great tutorial, you really set my up to succeed with the next 2 phases of programming my VR game.

  • @ZZaGGrrUzz
    @ZZaGGrrUzz 3 ปีที่แล้ว +4

    perhaps the best introduction into the state-based AI. Thank you.

  • @jameslavery2958
    @jameslavery2958 4 ปีที่แล้ว +13

    Very nice. I really hope this series continues. Thank you.

    • @OneWheelStudio
      @OneWheelStudio  4 ปีที่แล้ว +4

      That’s the plan! My next video may not be a programming pattern but I will keep working to add to this series - especially for patterns that work for both C# and Bolt.

  • @madewithreallemons263
    @madewithreallemons263 3 ปีที่แล้ว +5

    I really appreciated this video! I could easily pickup and implement my own version! Thank you a lot! I will pickup that book as well and use these patterns in my games. Cheers!

  • @nightshiftapps
    @nightshiftapps 3 ปีที่แล้ว

    Fantastic in depth explanation. Please keep it up!

  • @Crackpotweevil1
    @Crackpotweevil1 3 ปีที่แล้ว +3

    This was incredibly helpful.

  • @misfire8771
    @misfire8771 9 หลายเดือนก่อน

    this video helped more than I can explain. Thankyou.

  • @7thparabola
    @7thparabola 3 ปีที่แล้ว +1

    wow, great tutorial. Probably the best on the topic!

  • @chuckdude514
    @chuckdude514 ปีที่แล้ว

    Thank you so much for the book recommendation, it's definitely making the difference in my learning process. Also, it's kinda rare to see tutorials which focuses on good practices, and you do them good. You got a new sub!

    • @OneWheelStudio
      @OneWheelStudio  ปีที่แล้ว +1

      I do my best. I think tutorials should offer more than just “how to” when possible - that’s the classroom teacher in me 😉

  • @johnpepperwood6213
    @johnpepperwood6213 2 ปีที่แล้ว

    So I logged into another account just to like this video one more time. Thank you very much, this is awesome!

  • @bhanumallepeddi7610
    @bhanumallepeddi7610 2 ปีที่แล้ว +5

    This perfectly illustrates the use of state pattern. However there is a catch. It does not completely remove the code smell. You are essentially delegating the if statements in your main class to the child classes to act upon the state change. However this violates the open-close principle. Incase a new state is added in the future all the child classes you created will get affected. Just wanted to highlight this so it would be useful for others who are starting with design patterns. Overall a good job!

    • @danielemessina1979
      @danielemessina1979 2 ปีที่แล้ว

      Existing states are affected only if their functionality actually changes though, i.e. they need to consider a transition to the new state, in which case it could be justified, but yes it still smells.

  • @cb2818
    @cb2818 3 ปีที่แล้ว +4

    Had to throw a like on this video. You are a very good teacher!

  • @r.f886
    @r.f886 3 ปีที่แล้ว +1

    Great tutorial and explaining thanks

  • @Kalahee
    @Kalahee 3 ปีที่แล้ว +14

    I'm confused how State Pattern is any good. Every time you'll add/remove states, you'll have to edit each state that may need to transition to that state making the whole thing tightly coupled between them and that pretty much goes against OOP modularity expectations.
    I think you should keep all transition business in a controller (FSM) who has access to many information that may or may not concern every states and let it decides which states to move next based on the information it gets, like the simple example, but make each states a ScriptableObject with an interface "Execute(), Validate(NPC_FSM _fsm)". Validation tells FSM if it is a valid state to move to based on gathered information.
    This way you can easily parametrize each states and even have multiple "Attack" states, but with different weapons assigned (Sword, Axe, Bow). Making it central would let FSM switch from any to a specific state, "if attacked, state = attack", but also "if low health, state = run". Just looking at the FSM script you should be able to paint the graph without knowing what states do.
    Best example of this is Animator Controller. Your animations does not know what comes next, controller will make that decision.
    Another way would be to synapse (a transition object) between states (S1 -> T1 -> S2, S1 -> T2 -> S1). The base class would have static information every synapses can access to validate when state question it, a state would loop between all synapses assigned, each synapses would act like transistor gates, and quit on first true. But without a graph inspector like ShaderGraph or even AnimatorController this can get hard to visualize the network from code.

    • @spairus4492
      @spairus4492 2 ปีที่แล้ว +1

      Sorry for responding to an old comment, but your problems with the FSM are fixed if you use a behavior tree instead, right? You don't have to bandaid an FSM, just use a BT

  • @unitydo-elcaminodelvideoju3196
    @unitydo-elcaminodelvideoju3196 3 ปีที่แล้ว +6

    Dont need check if the navAgent is null everyframe, you can to GetComponent in the Start or Awake or the NPCSearch, for thease reason I think the states must have OnEnter, OnStay and OnExit methods

  • @datcong974
    @datcong974 2 ปีที่แล้ว

    why i dont find this channel before! great turorial

  • @Renegen1
    @Renegen1 2 ปีที่แล้ว

    the best Unity educator.

  • @beri4138
    @beri4138 3 ปีที่แล้ว +1

    Awesome video. I'd love to see you cover behavior trees in a similar way.

  • @JohnnyThousand605
    @JohnnyThousand605 2 ปีที่แล้ว +2

    If I'd known about the state and the observer patterns a couple of years earlier my life would've been so much easier =D
    The great thing about a FSM is that even if your number of states gets a bit big, it's still perfectly readable/debug-able because each state is only doing one thing. I have about 50 states in the fighting game I'm working on. While that seems like a lot I've made them generic enough that I'm not going to need any more but if I do I can add them easily and the flow of the system is easy to understand =)

  • @lucapasini078
    @lucapasini078 3 ปีที่แล้ว +1

    Exetremely useful. This is how to get the most from OOP, gj!!

  • @PunishCrow12
    @PunishCrow12 3 ปีที่แล้ว +4

    Great video, really clear explanation of this fundamental concept. One question however: do you suggest to code each fsm from scratch or to use existing ones? For example unity animator is itself an fsm, even if thought for animation. A lot of people use it as logic fsm, even if I think it is somehow limited because likely hard to debug and because it doesn't allow to distinguish between logic and animation states management.
    However, great job. One sub more!

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +3

      I a couple of thoughts. Yes, FSMs can be hard to debug, but that generally comes from their complexity or size. If they get so big that you can't debug them it might be time for a different approach or some refactoring of your code. I would also argue that the second more abstract approach presented in the video will handle larger FSMs more easily. To help with visualization I would probably lean towards something like Playmaker (which is just an FSM) or Bolt's state macro (rather than trying to use an animator). Both could be used with custom C# logic, but do so with visuals. Being more recently familiar with Bolt, using the state macro to call C# code is really quite easy and is a future use of Bolt I could see in my own C# based projects.

  • @muzboz
    @muzboz 2 ปีที่แล้ว +1

    Good stuff.

  • @mr_noodler
    @mr_noodler ปีที่แล้ว +1

    wowzers this is awesome

  • @sonsai10
    @sonsai10 3 ปีที่แล้ว +2

    great video, the state pattern is very similar to the strategy one, seems like they are almost the same code structures but with different aplications

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +2

      There is definitely some overlap in sense of changing behaviors! Especially with the class based FSM.

  • @inventiva4126
    @inventiva4126 4 ปีที่แล้ว +1

    Very clear

  • @DevFrogora
    @DevFrogora 2 ปีที่แล้ว +1

    Man thats why i had subscribed you thanks for hiding un wanted code

  • @jondyason336
    @jondyason336 2 ปีที่แล้ว +1

    thanks!!

  • @RaonCreate
    @RaonCreate 3 ปีที่แล้ว +1

    wow! I just discovered a new tresure !

  • @322ss
    @322ss 3 ปีที่แล้ว

    Thanks!

  • @erz3030
    @erz3030 4 ปีที่แล้ว

    This was very well done, you are such a great teacher, and editor. Object pooling could be a good topic to cover. It could even be hooked into your state machines too I would imagine. Maybe npcs getting chased or hit drop items around them when both hit, and 'killed' (maybe particles spawned from pool when hit, and then simple primitive shapes spawned for 'loot'). And have the AI wandering bots pick up loot or some other similar, and the bot that reaches 10 loot pickups first wins?

    • @OneWheelStudio
      @OneWheelStudio  4 ปีที่แล้ว

      I appreciate the feedback. You're totally right that object pooling would fit easily with this setup. I was feeling hesitant about it for a video as there are so many others that talk about it. That said, I have a fairly generic approach to Obj Pooling in my personal project that creates collections as you go so no need to customize or create them in code or in the inspector! So maybe I can offer my own take on it ;)

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      Here's a preview ;) Object Pooling: onewheelstudio.com/blog/2020/7/15/object-pooling

  • @0Skullhack0
    @0Skullhack0 2 ปีที่แล้ว +1

    I'm happy to see that I'm implementing my FSM almost the same way as you. However, I ran into a problem : if I want 2 NPC to patrol, but one will chase the player when it detects it, the other will flee it, how, or rather where, do I make the distinction ? I kinda want to share the Patrol state, but the transition are differents. I can go the "easy and ugly" route and put a boolean on my npc, or use a "type" or npc, but everytime time I'll want to share some state between different npc, I'll end up with a lot of parameter to determine which transition I should take, which goes against the initial idea of avoiding spaghetti code. Maybe I should look into other patterns ?

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว

      If you have different behaviors between different npcs then I'd go the route of different types of NPCs. If it's just the two types then a boolean really isn't that ugly.
      You could go way out the OOP road and potentially create classes/objects for the transitions themselves!
      AI isn't easy and I think you'll likely end up with a chunk of code no matter what. Every solution has tradeoffs.

  • @fartmerchant
    @fartmerchant 7 หลายเดือนก่อน

    late question: would it make a difference if the states of the NPC class were static fields?

  • @aldigangster123
    @aldigangster123 3 ปีที่แล้ว

    Great presentation. It made it a bit clearer for me. Just curious, when you're saying that FSM pattern may not be the right choice for complex (> 10) behaviors, what would you use then instead?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +2

      It depends on the system and I'm certainly not an expert on AI by any means, but my first suggestion would be to look at behavior trees. The asset Behavior Designer is really well put together and is well designed for complex AI. GOAP (Goal Oriented Action Planning) is another very cool approach, but not one that I've done much with or had a need to dive into.
      All that said, for my personal project I have an enum with 15 or so different game states. I don't use a pure FSM, rather I call events (check our my most recent vidoe) that broadcast the game state. In this case having 10+ states isn't a real problem as chunks of code usually only care about either being in one state or not being in that one state. That means that the code stays pretty clean and there's not massive switch statement or series of classes for different states to debug or manage. Maybe I should do a video on my system?

    • @aldigangster123
      @aldigangster123 3 ปีที่แล้ว +1

      @@OneWheelStudio Thanks for the response! I watched your latest video and am looking now into your other suggestions. GOAP sounds pretty interesting for AI, which I may try to implement. However I probably still need a "AI-less" state machine for the player character, as my code got way to messy. I'm already using the ScriptableObject Architecture from the Asset Store, based on Ryan Hipples Unity talk, for things like interactable gameObjects raising themselves (to the UI, sound, etc.) when the player enters their trigger zone. But haven't thought about combining Events with a state machine. Will def. watch your video in case you make it, already subscribed to your channel - you make really good videos!

  • @morneerasmus1789
    @morneerasmus1789 3 ปีที่แล้ว +1

    With the class-based implementation, how do you handle things that need to run on Fixed Update instead of Update()?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      That's an interesting question. The answer probably entirely depends on the details of what you are doing, but my first thought would be to simply move the code from Update to Fixed Update. Does the code really need to run faster than the fixed update interval? Usually not. You can also increase the fixed update interval.
      You might be able to create some sort of "runInFixedUpdate" boolean in each state and then check the value and only call "do state" if the value matches the place "do state" is getting called from - i.e. a simple IF statement. This might allow you to have both an update and a fixed update, but I'd guess you could get some odd race conditions occasionally.
      If you really NEED to have both, you might explore using WaitForFixedUpdate in a coroutine that lives inside the state... This coroutine could get called from the "do state" function. You'd need some sort of internal boolean in the state that tracks if the coroutine is running so it only gets called once per fixed update. Then in the coroutine "Wait For Fixed Update" and flip the boolean when it's done. This might allow the "do state" function to be called from update, but effectively only run during fixed update? Again this feels messy and fragile, but it might be an option.

  • @omeryilmaz1021
    @omeryilmaz1021 ปีที่แล้ว

    how to add Start and End functions for the States, for example when its switched to angerState from the idleState first thing I wanna do is make the color red

  • @AM-vr4qy
    @AM-vr4qy 3 ปีที่แล้ว

    What's the best thing to do when you want 2 different states to call the DoWander() or similiar method? In terms of not having to reuse the code. I'd also make the states in the base class readonly. Excellent tutorial

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      If you are using the simpler approach with the switch statement you can just call "DoWander" or whatever function from both of those cases.
      If you are using the class based behaviors... I'm not sure I can recommend a "good" way to use a function in multiple behaviors. I suppose you could do some sort of static class and simply call that function from each behavior that needs it... If it's just a behavior or two I don't think duplication is that bad. Also, if you are needing to "mix" behaviors then you may be verging on not have a finite state machine as two of your states are both doing the same thing.
      Happy to try and help more and learn more about what you're trying to do, sounds like an interesting problem to solve :) but might be easier on discord? Feel free to ping me on the OWS discord (link in the description).

  • @daslolo
    @daslolo 3 ปีที่แล้ว

    This is great. Do you think BT are well suited for game state? I'd like to see how you implement BT.

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      I think something as straight forward as game state (at least how I think about it) doesn't need or would even work with a BT. For my project I have specific actions that trigger a change in game state - the logic is pretty cut and dry. For other things like AI for a patrolling NPC which might have several variables (health, movement speed, distance, player status, ammo, armor, weapons, etc) that it is using to make a single decision or change in state I think a BT would be a good fit. As for implementing a BT? I'd just slap down my $50 or so bucks and buy Behavior Designer - it's awesome.

    • @daslolo
      @daslolo 3 ปีที่แล้ว +1

      ​@@OneWheelStudio I used BD a while back and didn't like the clunky node editor one but, preferred Panda because [Attributes] but now that BD has utility and Panda dev is AWOL I'll take another look. Thanks for bringing it up.
      After I asked you that question about game state I remembered that I did just that in Panda. It works wonder with BACK and interuptions, shortcutting through a hub world for example and seeing the many states of rewards, unlocks and such.

  • @paufenollosa
    @paufenollosa ปีที่แล้ว

    Catch a ride!

  • @rezonator4660
    @rezonator4660 3 ปีที่แล้ว

    Is there a reason why your states don't have constructors (except for the C# default automatic constructor)? Would there be practical scenarios where an explicit (parameterized) constructor should be called? Thanks

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      I think that sending the npc info via a parameter on the DoState function has a similar result to a constructor in that you are injecting the data. I personally like injecting the data directly into the function rather than having the DoState function grab the info from a variable (set by a constructor) - it just feels cleaner, but that could just be a personal preference.
      Since there is a local instance of the states on the NPC I'm not sure a constructor vs injecting the data to the function makes much of a difference, but maybe there would be states that have some sort of internal value(s) that needs to get set when the state is created. I struggle to think of an example, but I wouldn't be surprised if there was.

  • @sandrok14
    @sandrok14 2 ปีที่แล้ว

    Very interestring. Can we just create new State() and return that instead of returning existing one from npc class? And maybe return null if we want to stay in the same state

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว +1

      I think the tricky bit is there generally needs to be some coupling between the FSM and the states themselves. That coupling comes from having to make the decision to change states AND which state to change to.
      Returning something like new State() could work, but that state then needs to decide what state to enter and that requires knowledge of the NPC itself plus all the available states which means there is all kinds of coupling or at least a poop ton of data injection. Which might work.
      One way to maybe clean this up some would be to have an EnterState, StayState and ExitState on each state. This would let the state determine what to do, but the FSM would need to "poll" each state to see which state it should enter and the order you poll the states could create some potential issues - bias in which state gets entered first. This is starting to sound a bit like a behavior tree ;)

    • @sandrok14
      @sandrok14 2 ปีที่แล้ว +1

      @@OneWheelStudio Yes that makes sense. Thank you for such a detailed reply!

  • @remus-alexandrusimion3439
    @remus-alexandrusimion3439 2 ปีที่แล้ว

    Maybe stupid question but why don't the constructors for the states contain the reference to the NPC? Why are we giving the NPC as parameter only to the DoState method? Wouldn't it help to have the NPC reference inside the whole state class, in case we need to use other methods?

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว

      I think you certainly could, but the main goal was to make the states fairly independent and decoupled. Passing in the state means the states could make all kinds of changes and the state then becomes dependent on having an NPC as a parameter. Maybe 6 of one and half dozen of another, but I think (it's been a while since I made the video) that was the goal.

  • @jakrol
    @jakrol ปีที่แล้ว

    I have implemented state machines the "if" way and the "enum" way, so I admittedly skipped ahead to the class-based one. I like your implementation. Other implementations I've looked at were not as clean and made passing the parent object of the state machine into the state machine itself difficult (so many people use GetComponent, each and every frame, which I have been told countless times is a beginner's trap from an optimization standpoint).

    • @mrfatuchi
      @mrfatuchi ปีที่แล้ว

      It turns out it actually isnt. I am not 100% but I have read that its natively cached already and that would make sense. If you have a GameObject with components you most likely wanna access those so the object could add references to those components on creation from the get go. Obviously this would work for compile time not runtime, it would simply create those references as I said right away for every GameObject that has getcomponent called on. I mean GameObject is nothing but container for component references after all.Again I am not 100% sure but I read quite few comments that said it is and logically it makes perfect sense I am just not sure why they didnt state this in the API.

    • @jakrol
      @jakrol ปีที่แล้ว

      @@mrfatuchi Just to make sure I understand what you're saying - I've seen a lot of people do all their GetComponents in Awake, Start or OnEnable. I even do it myself. But if it's cached by the compiler during optimization, then just calling GetComponent in Update would yield the same result? I've personally never seen any evidence that calling GetComponent in Update is bad, just hearsay from the forums. I agree the API should be more clear on this.

    • @mrfatuchi
      @mrfatuchi ปีที่แล้ว

      @@jakrol Yeah I also cache it manually, as almost everyone does, but from people's comments who seem to be in the know it looks like its completely uneccessery. And from my own research and knowledge yeah its already cached at compile time. I am just looking OnAnimatorMove() function on Unity Documentation and they did this in it: Animator animator = GetComponent(); then
      if(animator)
      ...
      This is called everyframe so obviously its already cached and they just cache the reference locally for convenience since easier to write animator.something. Unity has so many examples of being vague but I personally think this is a good thing because it forces people to learn more by themselves which in turn makes us better programmers.

  • @funduino8322
    @funduino8322 3 ปีที่แล้ว

    Why did we use an interface for states rather than an abstract class? I felt it will only be used for states rather than other class types

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      You can use either. Really depends on whether you want to define variables or not.

  • @jayocaine2946
    @jayocaine2946 3 ปีที่แล้ว

    what's the point really if your switch is just going to be filled with a bunch of conditionals anyway. I'm not a seasoned programmer or anything. But I think trying to find a way to weed out conditionals first in your logic would be more effective than going straight for this State pattern. I suppose its nice because it gets rid of all those bools when dealing with the update method.

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      I hear that. The real goal and advantage of the state pattern is that you know exactly what state a system is in. No superposition of states. This can make it much easier to debug or add new mechanics. The code itself isn’t necessarily pretty, but it is generally much easier to work with.

  • @Ryan-ww7un
    @Ryan-ww7un 2 ปีที่แล้ว

    In the CanSeePickUp script, you use (npc.transform.position + Vector3.up) a number of times. Why do you add Vector3.up to the npc's position?

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว

      It's been a while since I made the video, but I believe the idea was so you didn't look at the NPCs "feet" but more in the middle of the body. Probably not super crucial.

    • @Ryan-ww7un
      @Ryan-ww7un 2 ปีที่แล้ว

      @@OneWheelStudio I tried removing it to lower the raycast position but for some reason the raycast is still being shot from .5 units above the top of my npc. I'm going to just make an empty game object to designate where the ray should originate from.

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว

      Hmm. Strange that you can’t adjust the start position. Using an empty gameObject seems like it should work. I often do it that way to keep things flexible.

  • @tst2648
    @tst2648 4 ปีที่แล้ว +2

    Okay I have to ask. You have a great voice, but do you voice other channels? I swear you sound like the guy from like two other series’ videos.

    • @OneWheelStudio
      @OneWheelStudio  4 ปีที่แล้ว +1

      Ha! I have been making the Odin inspector videos for the past 6-7 months, but no other channels. :)

    • @tst2648
      @tst2648 4 ปีที่แล้ว +1

      @@OneWheelStudio THAT'S what it is. Thank you! Your stuff is amazing btw!

  • @sekharkarak6781
    @sekharkarak6781 3 ปีที่แล้ว

    I'm a beginner and I wanna ask if I need to learn this for visual programing like in Bolt...???

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      This is not on the list of "needs" for a beginner, but FSMs are actually baked into Bolt in the form of State Macros. You can see the basics of these in action in my "top down" tutorials where I create some very basic AI. Hope that helps!

  • @seththefirst
    @seththefirst 3 ปีที่แล้ว +2

    You make the states static, you would not need to create variables for them inside the user... maybe that could be an improved version of it.

    • @naxaes7889
      @naxaes7889 3 ปีที่แล้ว

      True, but if the states contains data (like timers) then you would have to share them between all entities. So you wouldn't be able to have different cool downs for each entity.

    • @jayocaine2946
      @jayocaine2946 3 ปีที่แล้ว

      why would you want to add code smells to code you're trying to refactor and clean up lol

  • @sethell2
    @sethell2 3 ปีที่แล้ว

    6:34 could we avoid the cost of making base class variables public by just giving them a protected access modifier?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      I don’t see why not. That’s usually what I do in my personal projects. I’ve move away from public variables and functions as much as possible.

    • @salvadorm7564
      @salvadorm7564 3 ปีที่แล้ว

      Sorry to respond to an old comment but the same thought crossed my mind. I don't think you can do that in this case right? Given that the different state classes don't inherit from the NPC class, they just get an instance of it. So they wouldn't be able to access them even if protected? Awesome tutorial by the way, definitely going to use this. Thanks!

  • @mohokhachai
    @mohokhachai 9 หลายเดือนก่อน

    Special

  • @monkeyrobotsinc.9875
    @monkeyrobotsinc.9875 3 ปีที่แล้ว

    youd make a great president, what with the reading and hand motions.

  • @ragavendranbala2923
    @ragavendranbala2923 4 ปีที่แล้ว +2

    Nice Infoo, But please increase the font size of VS to 125%

  • @Hemoplaguer
    @Hemoplaguer 3 ปีที่แล้ว

    I wish you actually coded it in front of us.

  • @panampace
    @panampace ปีที่แล้ว

    Can I get a better explanation of why to abstract my states into classes rather than a long switch/case?
    My use case: a 3d platformer like Mario 64, where three inputs can chain into a variety of moves. I have about 30 "moves" (states) that each have about 6 exit conditions to another state.
    For readability/manageability, I get lost when there's dozens of different files with short little scripts and functions that point to other functions that point to other functions. You say it's worth the redundancy, I don't see why. I'd rather just scroll up and down a switch/case that's laid out like a list and only 2 layers deep. It directly matches my design doc that outlines the moveset. If it's too long to scroll I can always show/hide nested lines of code in my IDE.
    The benefit I see to using classes for states is modularity. For instance, if I wanted the moveset to change by unlocking new abilities.

    • @OneWheelStudio
      @OneWheelStudio  ปีที่แล้ว

      At its simplest I think the class structure allow you to reuse the states. So if you have different ai (for example) that might make use of SOME of the same states you don’t have to recreate the states.
      Also truly long if else statements and switch statements tend to get hard to read and hard to debug.
      Hope that helps.

  • @unclerandy398
    @unclerandy398 3 ปีที่แล้ว

    I am a noob with code but is there a difference between using an interface rather than inheriting from the base class?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      One of the biggest and most useful differences is that you can implement more than one interface but only inherit from one class. So you can build functionality.
      Interfaces also only define a function not variables and the functions will need to be implemented in the classes. Whereas with inheritance you can fall back on the base classes function.

    • @unclerandy398
      @unclerandy398 3 ปีที่แล้ว

      @@OneWheelStudio Ahh so the states can be used by multiple npc types?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว +1

      Yes. Ideally it helps to reduce the amount of code needed.

    • @unclerandy398
      @unclerandy398 3 ปีที่แล้ว +1

      @@OneWheelStudio Got it that makes a lot of sense and thanks for the help I appreciate it.

  • @krethickchakravarthy6533
    @krethickchakravarthy6533 3 ปีที่แล้ว

    How to convert fsm to scripts unity?

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      Do you mean unity visual scripting? If so they are built in with state macros. They are one of the best aspects of the visual scripting.

  • @eschewary367
    @eschewary367 2 ปีที่แล้ว

    Dumb it down for me, what are the basic advantages of State Pattern?

    • @OneWheelStudio
      @OneWheelStudio  2 ปีที่แล้ว

      It helps to organize your code in such a way that it is much easier to debug or make changes - this is because you KNOW exactly which state it is in. The code can only be in one state at a time.
      If you get more than 2-3 if statements strung together with multiple conditions to check it can be a nightmare to debug.

    • @eschewary367
      @eschewary367 2 ปีที่แล้ว

      @@OneWheelStudio Thank you, sounds like what I need! I'll try to implement this.

  • @slowfuse
    @slowfuse 9 หลายเดือนก่อน

    5:27..........annnnnnnnnnd......im fuckin lost...

  • @manz5435
    @manz5435 4 ปีที่แล้ว +2

    Great tutorial. ty. But it would be better if u read scripts off the screen or at least look at the camera while reading.

    • @OneWheelStudio
      @OneWheelStudio  4 ปีที่แล้ว

      Yep I agree. A teleprompter is on my short list of gear items that I need. My script was just a few inches below my camera and it still looks like that. 😛

  • @MAxAMILLIoN757
    @MAxAMILLIoN757 2 ปีที่แล้ว

    Please make your code bigger, way too small to see

  • @sanketvaria9734
    @sanketvaria9734 2 ปีที่แล้ว

    This is super hard to understand.

  • @mohokhachai
    @mohokhachai 9 หลายเดือนก่อน

    Too easy

  • @Kabodanki
    @Kabodanki 3 ปีที่แล้ว

    what ugly code, why adding _Class inside a class name

    • @OneWheelStudio
      @OneWheelStudio  3 ปีที่แล้ว

      That was mostly for my own purposes and having examples of the classes at different stages of implementation, i.e. I had two versions of a given class. So yes ugly and I could have used namespaces to make it prettier, but I went the easy way for the video ;)

  • @amaurylerouxdupeyron4523
    @amaurylerouxdupeyron4523 3 ปีที่แล้ว

    instead of if use switch lmao

  • @palewine
    @palewine 3 ปีที่แล้ว +2

    Good stuff.