Build a Better Finite State Machine in Unity

Ойындар

In this video, we're going to build a flexible and efficient object-oriented state machine in Unity using C#. The days of using an enum state machine are OVER! This tutorial covers everything from defining states, implementing transitions and predicates and moving between animations using code, all with SOLID principles and the State and Strategy programming patterns. Master these concepts, and you'll be well-equipped to design advanced, reusable state machines for your game projects.
🔔 Subscribe for more Unity Tutorials / @git-amend
#unity3d #gamedev #indiedev #statemachine #3dplatformer
▬ Contents of this video ▬▬▬▬▬▬▬▬▬▬
0:00 Intro
1:00 Overview
2:13 States
3:55 Predicates
5:00 Transitions
5:44 State Machine
10:00 Refactoring
14:40 Demo
15:30 Challenge
20:17 Challenge Demo
Source code: github.com/adammyhre/3D-Platf...
Open Source Used In This Video
github.com/KyleBanks/scene-re...
Assets Used In This Project (Affiliate Links)
Dungeon Mason Tiny Hero Duo: (FREE): assetstore.unity.com/packages...
MeshTint Burrow (FREE): assetstore.unity.com/packages...
Cartoon Remaster VFX (FREE): assetstore.unity.com/packages...
Casual Game SFX (FREE): assetstore.unity.com/packages...
Ultimate Low Poly Pack: assetstore.unity.com/packages...
DOTween (FREE): assetstore.unity.com/packages...
DOTween (Pro): assetstore.unity.com/packages...
Follow me!
linktr.ee/gitamend

Пікірлер: 106

  • @git-amend
    @git-amend10 ай бұрын

    Hit the Like button and Subscribe to keep up with this series! New videos every week!

  • @justinjohn7656
    @justinjohn765613 күн бұрын

    This is the purest implementation of a state machine I've ever seen. Most of the ones I've seen have quirks that need to be worked out in order to adapt it into a specific project; this is effectively a black box implementation that will reliably function if you connect the states properly which is incredible.

  • @git-amend

    @git-amend

    13 күн бұрын

    Thanks for the comment! Glad you like it!

  • @Cloud-Yo
    @Cloud-Yo5 ай бұрын

    I find your content to be the most sensible and advanced in terms of game architecture on KZread. There is really not a lot of practical tutorials that cover systems the way your videos do. I'm really happy to have found this channel. Admittedly I'm having a bit of trouble following some of the code examples, mostly due to the way the code is split up and all of the autocompleted code from copilot which sometimes goes by really quickly. But overall this is amazing stuff. Also looking forward to the DI video. Thanks!!!

  • @git-amend

    @git-amend

    5 ай бұрын

    Cheers! I appreciate that! Always trying to find a balance between speed and viewer retention! 😀

  • @Cloud-Yo

    @Cloud-Yo

    5 ай бұрын

    @@git-amend This is my opinion, so take it with a grain of salt, but considering the invaluable nature of the information you are sharing and your level of experience, I would love to see even longer videos explained more thoroughly. I appreciate the time and effort it takes to produce content, so it's just wishful thinking on my part. I'm at the stage in my career where Im starting to pick myself up after falling into the Dunning-Krueger valley of despair and would love to work under an engineer of your level to start filling in all my gaps in knowledge. But... I am very grateful for the fact that you have shared this much already - keep up the amazing work!

  • @dreamisover9813
    @dreamisover98133 ай бұрын

    Always great to find a channel that covers more complex/advanced topics, really liked this video and will check out some of the others too!

  • @git-amend

    @git-amend

    3 ай бұрын

    Glad to hear that!

  • @brianwilson7497
    @brianwilson74973 ай бұрын

    this is such high quality information and feedback on what you're doing. I'm going to rewatch this multiple times. bravo!

  • @git-amend

    @git-amend

    3 ай бұрын

    Awesome, thank you!

  • @ekekw930
    @ekekw9305 ай бұрын

    Great implemenation! Reminds me of Jason Weimann's FSM. You and him are both great C# developers

  • @git-amend

    @git-amend

    5 ай бұрын

    Thank you!

  • @Broudy001
    @Broudy00110 ай бұрын

    Thanks for doing the FSM implementation, always find it interesting to compare the different ways of doing it. I like this one a lot.

  • @git-amend

    @git-amend

    10 ай бұрын

    Glad you enjoyed it! I like comparing other people's solutions to problems as well, especially inventory systems!

  • @simoncote4064
    @simoncote4064Ай бұрын

    I've been scouring Unity State Machine tutorials for the past week, although I understand the concept, I am having a difficult time wrapping my head around the actual implementation of state machines and how it ties in with a character controller. Your code made a switch slip in my head, it is by far the most flexible/generic and clean state machine ive seen so far on youtube. Your background in software eng. clearly shows in your code. Thanks for the high quality content, i'll be on the look out for your next video releases.

  • @git-amend

    @git-amend

    Ай бұрын

    Thanks for the kind words! Glad this helped you out, you might like the latest video about GOAP too, though unrelated to character controllers.

  • @kattakittaxr
    @kattakittaxr5 ай бұрын

    Loving this tut. Great Job!

  • @git-amend

    @git-amend

    5 ай бұрын

    Thanks!

  • @bhuvneetsaggu4011
    @bhuvneetsaggu40114 ай бұрын

    love your voice.. i have seen soo many fsm tutorials.. but your video fits best to my project. thanks

  • @git-amend

    @git-amend

    4 ай бұрын

    Awesome, thank you!

  • @Sosa829
    @Sosa8295 ай бұрын

    Great video as always, I love how you explain the stuff we learn in college in a good way. Is there a reason why you'd implement your own IPredicate interface instead of using the C# Predicate? I think they both work the same way so I was wondering.

  • @git-amend

    @git-amend

    5 ай бұрын

    That's an excellent question, and I'm surprised nobody has ever asked that before. C#'s Predicates are great for simple, usually stateless conditions. Using a custom IPredicate interface, on the other hand, can allow for explicit state management, and flexibility in complex or large-scale applications. You could implement state management through a C# Predicate by using closures, but it is less transparent and potentially cumbersome. Just as an example: public class EnvironmentConditionPredicate : IPredicate { private WeatherSystem weatherSystem; private TimeSystem timeSystem; private LocationSystem locationSystem; public EnvironmentConditionPredicate(WeatherSystem weather, TimeSystem time, LocationSystem location) { this.weatherSystem = weather; this.timeSystem = time; this.locationSystem = location; } public bool Evaluate() { // Example condition: Can only perform action if it's night, raining, and in a specific location return weatherSystem.IsRaining && timeSystem.IsNight && locationSystem.IsInSpecificLocation(); } }

  • @Sosa829

    @Sosa829

    5 ай бұрын

    @@git-amend I see, it's like making it customizable so we can add any information we might need! Thanks for the response.

  • @skyswimsky1994
    @skyswimsky19944 ай бұрын

    Great content. Can't wait for the hierachical video. However, wouldn't it make more sense to have some of the behaviour defined in the Controller be in the state instead? As it stands right now all the state machine takes care of is serving as a sort of callback to the controller for some movement logic depending on some predicate-and-transition logic, assuming that in theory more states get introduced, the controller would just be cluttered with methods and variables again, no?

  • @git-amend

    @git-amend

    4 ай бұрын

    Yes, that's a great observation. As your project grows you would want to start having your states handle more of the logic execution and try to decouple your classes more. The next step in the evolution of this might be to start using the Command pattern so that each state can execute logic without a direct reference to the Controller class. Commands could be assembled using a factory and maintain their own references and logic. Perhaps a topic for a longer video!

  • @abc-wo7pw

    @abc-wo7pw

    4 ай бұрын

    Instead of a Controller I decoupled it into multiple classes such as MovementBehaviour, AttackBehaviour etc and I pass in the appropriate class instead

  • @ranejeb

    @ranejeb

    2 ай бұрын

    @@git-amend +1 for making a longer video on the topic. Currently it feels like current version of state machine doesn't give us the actual benefit of having a decoupled code, since we're resorting to doing all the critical logic in the PlayerController god class. It's not exactly clear how Command pattern can remedy this situation (it's also not clear why Command pattern in the first place), so seeing deeper dive into this topic with an improved solution (while being honest to it's pros and cons) would be very interesting!

  • @marc8150
    @marc81502 ай бұрын

    Holy Shit, that is so much more sophisticated than I expected. Great video and also quite overwhelming for someone like me who coded only one simple statemachine before😅

  • @git-amend

    @git-amend

    2 ай бұрын

    Thanks! Glad you liked it!

  • @marc8150

    @marc8150

    2 ай бұрын

    @@git-amend Definitely! But I struggle to fully understand everything yet, as some concepts are new to me. Do you think it is worth investing the time to understand this highly flexible statemachine or should I just go with something simpler? I actually just wanted to create my own Vampire Survivor game and I know this SM might be a little overkill as there are probably not going to be so much states justifying such a state machine haha. ^^ But I think it'll be a great learning for future projects.

  • @git-amend

    @git-amend

    2 ай бұрын

    @@marc8150 My philosophy is always progress over progression. What you know now will seem trivial to you next year - go with what you know and keep building on it and learning new things!

  • @marc8150

    @marc8150

    2 ай бұрын

    @@git-amend Great input, thank you very much! I'll do it that way and just keep iterating on it!

  • @marc8150

    @marc8150

    14 күн бұрын

    Hey man, just got this video recommended randomly which reminded me of this comment I dropped 2 months ago. I just wanted to say, without really focussing on this tutorial specific but just grinding - building games and improving my knowledge I've now fully understood this state machine video and even implemented it into a game with some adjustments. Can't tell this enough, you're awesome! :D

  • @abc-wo7pw
    @abc-wo7pw4 ай бұрын

    Great tutorial thanks! My game is event driven mostly, how would you make it so that some triggers are only checked when an event(regular c#) is raised?

  • @git-amend

    @git-amend

    4 ай бұрын

    I would make a new type of Predicate, maybe called ActionPredicate, that can maintain state and keep a boolean flag for when the event is raised. When consumed by the method checking transitions it can set the flag to false all the time and only act when the flag is true.

  • @grimsbaldruk4014
    @grimsbaldruk40143 ай бұрын

    Really cool ! Been working with a FSM based on scriptable objects and found it very disturbing (it was made by previous employee, gone when I started), your's is way more intuitive Thanks a lot, will also follow AI video with Strategy pattern !

  • @git-amend

    @git-amend

    3 ай бұрын

    Great, love to hear it!

  • @hailelam4112
    @hailelam41123 ай бұрын

    Thank you so much.

  • @git-amend

    @git-amend

    3 ай бұрын

    You're welcome!

  • @elminsmajlovic4564
    @elminsmajlovic4564Ай бұрын

    If you increase the movementSpeed (lets say) to 600 and run on a smal slop oder bump in the ground the character gets pushed up a little bit. do you have an idea how a i could fix this?

  • @rapaltiar
    @rapaltiar10 ай бұрын

    May I ask what are you using to get these code predictions in rider? I still cannot get them to work.

  • @git-amend

    @git-amend

    10 ай бұрын

    I'm using GitHub Copilot for the code suggestions. If you have the plugin installed, and it's still not working, maybe try the enable/disable toggle using the icon in the bottom bar. github.com/features/copilot

  • @Mamei.007
    @Mamei.0074 ай бұрын

    Hello, nice video, it is a good implementation of the state machine for multiple games and adaptable to various game engines, although I would like your opinion on whether it seems correct to use the Unity animation state machine to modify the behavior of the character Since this same one you can make multiple transitions, choose hierarchies and even add behavior scripts to each animation or SubStateMachine, also want to ask if each state corresponds to a single animation, since if, for example, there are many animations that have the same behavior as a single state (like attacks) would be rewriting the same behavior several times

  • @git-amend

    @git-amend

    4 ай бұрын

    In a simple example like this you could go either way. However, as your game gets progressively more complex, many devs find that driving animations from C# or a tool like Animancer is preferred. For more complex behaviour in a state I would start using the command pattern or start executing strategies instead of just playing one animation directly.

  • @tianqigao869
    @tianqigao86910 ай бұрын

    cool!

  • @kevin41307
    @kevin413073 ай бұрын

    Great tutorial!! I have a question about implement IPredicate interface. How to implement "action predicate" and "complex predicate"?[4:26] These don't mentioned in project. thanks.

  • @git-amend

    @git-amend

    3 ай бұрын

    I think you'll see some examples of those in upcoming videos this year. An ActionPredicate would generally be used to keep track of a button press or some other event. It would have a flag that gets consumed when read (so set true when button pressed, set false after it's been read by the state machine). A more complex Predicate would keep track of things in the game, so it might be used to tell you if a Player has completed a Quest and also has X item in their inventory.

  • @inkofthedragon
    @inkofthedragon4 ай бұрын

    I'm currently using Animancer. The way I've been triggering animations is via StateParameters class. So if entering PatrolState - OnEnter I set stateParameters.CanMove. The AnimationManager is checking the stateParameters.CanMove status in update. If it goes true, then it will trigger the walking animation. Now that I write down this workflow, sounds messy :( haha I think I chose this route because someone had told me that states should not be triggering animations but rather setting conditions for the AnimationManager to observe and then IT triggers the appropriate animation. Should I just be getting the states to directly call on AnimationManager.HandleRun, and skip the middle man of this StateParameters class? I'm trying to start from scratch with your StateMachine. Based on what I've said so far, how would you implement the StateMachine, States, and an AnimationManager (and possibly the StateParameters). How would they communicate with each other in a clean and extensible way? More info if it helps: With the StateParameters implementation, ChaseState sets CanRun to true, when in AttackState one of the abilities is CirclingAroundTarget so the AttackState sets CanCircle as true and so on. Thanks again, I really appreciate your insight on architecture! Looking forward to getting past this hump and on to making games! Sorry for the ramble but I guess to simplify, should I keep as: 1. States -> AnimationManager 2. States -> MiddleMan -> AnimationManager

  • @git-amend

    @git-amend

    4 ай бұрын

    IMO you should continue to make use of the StateParameters class, it's a reasonable approach that decouples your state machine from Animancer. It's also a version of the Mediator programming pattern. The state doesn't need to know about Animancer, and Animancer doesn't need to know about the state. For your scenario, this is probably the best approach, and useful when integrating with 3rd party tools.

  • @inkofthedragon

    @inkofthedragon

    4 ай бұрын

    @@git-amend amazing! I followed your advice with the Mediator Pattern and it's working well and I feel way cleaner and extensible! Thanks again, I'm learning so much after having recently discovered your channel! Quick question, what color theme are you using for your IDE?

  • @git-amend

    @git-amend

    4 ай бұрын

    @@inkofthedragon Sounds good. As for color, I think it's just the default.

  • @jean-michel.houbre
    @jean-michel.houbreАй бұрын

    Good evening, at 08:05, we add a call to OnEnter. I don't understand why, before setting the state with current = nodes[...]; we don't call current.State?.OnExit();

  • @git-amend

    @git-amend

    Ай бұрын

    In this context the SetState method is only used to set the initial state of the StateMachine. State changes after initialization are handled by the private ChangeState method.

  • @jean-michel.houbre

    @jean-michel.houbre

    Ай бұрын

    @@git-amend Ok. I understood that it could be used from outside the FSM. Thanks.

  • @PuppetDev
    @PuppetDev9 ай бұрын

    Is there a reason why we have a separation with the StateNode class? I feel like we could just skip it easily and do everything in StateMachine. Not a criticism towards the video though, it's really great and I like the implementation. I'm just trying try learn by asking.

  • @git-amend

    @git-amend

    9 ай бұрын

    That's a great observation and question. You are correct, of course, you could easily handle all the logic shown in this project within the StateMachine class itself. The primary reason for representing each state as a StateNode is extensibility. An example might be extending the StateNode class to include additional behaviour hooks, such as handling events or tracking the history of the state. Another example might be that if a hierarchical state machine is required, the StateNode could be extended to include references to parent or child states, enabling more complex nested states. Thanks for your comment, that might be a great topic for a future video! Cheers!

  • @PuppetDev

    @PuppetDev

    9 ай бұрын

    ​@@git-amend Ah, thanks for confirming. Yeah, I can see how that would make it easier.

  • @limit6864
    @limit68649 ай бұрын

    Thank you for the great video! But I have one question. In the current video, the player has very little state. There are only four things in this video. But in a normal game, a player can have so many states. Then shouldn't we write down the definition of each transition one by one? I think the "PlayerController" script will be very messy. Is there a good solution to this situation? If you have a very good reference, could you introduce it? Or could you make a video on this topic as an in-depth course? Thank you for reading the long post!

  • @git-amend

    @git-amend

    9 ай бұрын

    That's a very interesting question/comment because just this morning, I was considering making a follow-up video about how to create a GUI Editor that would let you configure a State Machine that would be easier to visualize - similar in style to the Animator window or GUI editors you see for complex dialogue systems. That's really the ideal situation for when a State Machine becomes so complex that it's hard to keep track of everything line by line. Maybe I'll move that higher up the TO-DO list. Thanks for your question!

  • @limit6864

    @limit6864

    9 ай бұрын

    @@git-amend If so, could you talk about this topic in the next video? I'm so curious how to handle more complex states in the video and switch them neatly. I'm curious about this topic because it's a huge problem when you're making a very dynamic and fancy 3D action game. Lastly, thank you so much for your sincere response to my question. Have a nice day.

  • @git-amend

    @git-amend

    9 ай бұрын

    @@limit6864 A video on this topic will take a long time to make, and I'm currently working on videos for a different series. It's a video I'm considering making in the future, but it's not going to be done immediately. Thanks for your patience!

  • @limit6864

    @limit6864

    9 ай бұрын

    ​@@git-amend I think I've been thinking too much about myself. You must have sounded like you were rushing me too much. I really want to watch a video about this later. Thank you for your answer.

  • @zerothehero.takeasip6612
    @zerothehero.takeasip66127 ай бұрын

    Awesome video as always! Couple of questions though. Isn’t this method of designing predicates for the transitions very limited? Having to add transitions via code makes it very designer unfriendly. To give some context to what I am imagining, I am thinking it in terms of a game with a vast movelist that utilizes the state pattern to organize every move. Every attack would be a scriptable object that would have its own defined logic that a designer would be able to tweak. Consequentially, transitions would also be scriptable objects. This way, if a designer were to want for a move to only transition to another move, under x condition with y logic, they would be able to easily implement it, given that the programmer made the appropriate states/transitions. Hence we come to my problem, how would a designer implement a predicate, if it has to be done with code? It just doesn’t seem like a scalable design. My other question would be in terms of implementing several states at the same time. Let’s say that our games wants to allow x state to be able to done simultaneously with the walking state? How would we go about implementing that? I saw some hierarchical state machines, but they seemed kind of clunky. They basically gave each state children which would all be run by the state machine, but it was a mess to make sure to transfer children to different parents when the states changed. Personally I was thinking a list inside a state machine rather than having children on the states, but personally I am not convinced. I was also thinking of making several state machines for different types of states and have a communicator but I felt as though that would increase interdependence. Either way, I learnt a lot with this video. Good job.

  • @git-amend

    @git-amend

    7 ай бұрын

    Thanks for your questions. To answer your first question, this can become designer-friendly by making all Predicates [System.Serializable]. This allows you to perform complex runtime logic while exposing some fields to the inspector. You then just need to make Predicates that are suitable for your designers to use. You can also create predicates that are simply logical operators (AND, OR, NOT) containing their own Predicates. This allows you to create complex logic by drag and drop within Unity. You can further extend this into a node-based Editor tool, which another subscriber has asked about and is on my list of videos to make. Your second question is more complex, but the first thing that comes to mind when things become tangled up is to take a component-based approach. For example, you might want to have a Movement component and an Action component, each with its own state machine. This minimizes dependencies while allowing concurrent state management. Additionally, using a well-structured communication system among components can mitigate the interdependence concern, ensuring that components interact in a defined, controlled manner. In a future video, I will talk about the Mediator pattern, which might help you out in this situation. The Mediator pattern facilitates loose coupling among interacting components by centralizing external communications, ensuring that components do not communicate with each other directly but through a mediator. In the component-based approach, a Mediator can help manage the interactions between different state machines or components in a controlled and modular manner, making the system more maintainable and easier to extend.

  • @zerothehero.takeasip6612

    @zerothehero.takeasip6612

    7 ай бұрын

    @@git-amend Thanks for your prompt and detailed answer as always! I have been trying to make the Predicates [System.Serializable] but it hasn´t allowed me to drag and drop the scripts as you said. Is there any resource that explains what you are talking about in more depth? I tried looking at unity´s documentation and found it lacking for what we are discussing. The only way I can seem to make a drag and drop approach is to make the predicate a scriptable object, but even then this is a bit limiting. Like how would one go about making complex boolean? Making AND and OR predicates and putting them together? And futhermore, many of the booleans that would need to be accessed, would need to come from many different classes/scripts (sure, most would be in the player´s, but there could certainly be other classes that need referencing that would hinder this approach). Maybe I am just not realizing how to use the Serializable aspect you mentioned idk. Also good to know that a mediator pattern can reduce these interdependencies!

  • @git-amend

    @git-amend

    7 ай бұрын

    @@zerothehero.takeasip6612 Unfortunately, I don't have a specific resource for your question. I can try to give you a bit more guidance, though. While interfaces aren't directly serializable in the Unity Editor, a List can be exposed. This approach should help resolve your drag-and-drop issue. For example: [SerializeField] List conditions = new List(); You can use logical operator predicates to construct complex logic in the Editor. You can nest them and make them as complex as you want. For example, a logical AND might look like this: [System.Serializable] public class And : IPredicate { [SerializeField] List conditions = new List(); public bool Evaluate() => conditions.All(c => c.Evaluate()); } In this manner, you can reference any serialized class or Scriptable Object implementing IPredicate via the Unity Inspector. Your concrete IPredicate implementations can find/reference the various GameObjects needed for predicate evaluation. You can use this approach for more than just conditions for changing states - it's useful for building dialogue systems or quest systems - anywhere you need to be able to configure logic in the Editor to be evaluated at runtime. ie: Evaluate() => achivementSystem.KillCount(enemyType) > amount; This is what makes the IPredicate approach so versatile. As I mentioned, I will be making a video on this subject if time permits. Or maybe I should just make an Asset for the store. 🤪

  • @zerothehero.takeasip6612

    @zerothehero.takeasip6612

    7 ай бұрын

    @@git-amend Unfortunately, interfaces can´t be serialized in unity from what I am seeing. Even if you use normal classes, unity allows you to make a list, but not add anything to it. Seems like SO are the only solution.

  • @git-amend

    @git-amend

    7 ай бұрын

    @@zerothehero.takeasip6612 Apologies, I left out a very important part, which is what I get for trying to answer questions when I'm not in front of my computer. You do need to include a method of interface serialization. There are several ways to go about this. 1) I recommend using Odin Inspector/Serializer. This package includes a SerializedScriptableObject and SerializedMonoBehaviour classes which allow serialized Interfaces without any additional work. This tool is invaluable. assetstore.unity.com/packages/tools/utilities/odin-inspector-and-serializer-89041?aid=1101lw3sv 2) Use an open source library. This one is ok, but has a few limitations. You can install it from the Package Manager. With this library you can select classes that implement the interface using a drop down menu. github.com/mackysoft/Unity-SerializeReferenceExtensions Hope that helps you out.

  • @shunpeng5700
    @shunpeng57003 ай бұрын

    Hi, I found that your state machine is very useful. I wonder how we could implement a Transition Record for a transition from this to other state. For example, in IState, OnEnter(ITransitionData data) and OnExit(ITransitionData data). With this, I can reconize from the state that it was transited from what early state, or with extra variable for different configure of the new state. DashState (was From JumpState), or DashState(was From LocomotiveState), have different Dash time. But I don't think that casting it to a implimented class from ITransitionData is good for performance. public interface ITransitionData { public IState FromState { get; set; } public IState ToState { get; set; } }

  • @junaidywijaya
    @junaidywijaya9 ай бұрын

    Hey adam, with this state machine how do i implement sprint, where you have to hold a button or toggling crouch?

  • @git-amend

    @git-amend

    9 ай бұрын

    Not sure if I can explain that in a comment, but I'll try. First you'll need to add a new Input Action for the new button that is a float type - just copy paste the Jump button definition, change its button assignment and rename it (maybe called Crouch), regenerate the C# class and update your InputReader to handle the changes to the IPlayerAction interface - you'll need an OnCrouch empty method; then create a public property in the InputReader like this: public bool IsCrouching => inputActions.Player.Crouch.ReadValue() > 0; This returns true if the player is holding the button. Use that in your PlayerController to decide when to go into or out of your state (along with any other conditions, like IsGrounded) In tomorrow's video you'll see something similar with the Kart's Braking input - the Kart doesn't use a StateMachine, but the InputReader's Brake action is exactly what I just described, and the PlayerController uses that information to apply the brakes (or not). Hopefully that makes sense!

  • @junaidywijaya

    @junaidywijaya

    9 ай бұрын

    @@git-amend yes, i did that, but in the PlayerController script, i use a enumerator to do smooth crouching, and for the predicator i use a stopwatch timer to run whenever i press the crouch button but that messed up the crouch, like it doesn't want to stand and stuck in crouch position

  • @junaidywijaya

    @junaidywijaya

    9 ай бұрын

    @@git-amend oh wait, i think i found it, it works now.. thanks

  • @pliniojrm
    @pliniojrm4 ай бұрын

    From the excellent content you are providing, i wish you could make a video creating an "Utility ai".

  • @git-amend

    @git-amend

    4 ай бұрын

    Interesting. What kind of features do you suppose that would have?

  • @pliniojrm

    @pliniojrm

    4 ай бұрын

    ​@@git-amend The character you have in your video about "Enemy AI". I'm more interesting in seeing how would you implement an "Utility Based AI" if we think that each enemy need to look for considerations to take actions, because in a level like open-world, variables might change depending on the situation, be the character values or the environment values.

  • @mohamadborna3678
    @mohamadborna36782 ай бұрын

    Hi thanks for great tut, but any ideas of about what to do with the stuff going on in coroutine methods of the controller?

  • @git-amend

    @git-amend

    2 ай бұрын

    Not quite sure what you are referring to, can you elaborate?

  • @mohamadborna3678

    @mohamadborna3678

    2 ай бұрын

    assume I have some stuff I dont want to be executed every frame or every fixed frame update, Like attacking for evey 2 seconds in some coroutine, one approach came to my mind was to make the method that starts coroutine in controller class public, and then call it OnEnter of base state class, how do you think about this approach?@@git-amend

  • @git-amend

    @git-amend

    2 ай бұрын

    @@mohamadborna3678 That could work; I think it's a reasonable approach, I would lean towards starting the coroutine from the State (OnEnter) and making sure it's stopped (OnExit). You could also pass in a start and stop coroutine methods using the Command pattern so that the logic is decoupled from your State machine for extra flexibility.

  • @alishi961
    @alishi9615 ай бұрын

    I enjoyed your approach to implementing the state machine pattern, great video. I was just wondering how can I make this into hierarchical state machine? let's say I want to group my grounded states together and all my airborne states together, like attacking for example, I want to use the same primary attack button to perform the attack but the animation and the logic for attacking differs based on being airborne or grounded. This way I don't have to check if I'm grounded or not for every transition, I can simply be in a super state called grounded and in this super state I have bunch of other states like: idle, move, ... and I can go to other states for example I can jump in grounded state but I don't have to link my idle and move to jump I simply transition from grounded super state to jump state. It would be nice if could create a combat system tutorial by the way :) tnx

  • @git-amend

    @git-amend

    5 ай бұрын

    Thanks for the comment. Transforming this system into a hierarchical system is probably longer than I can detail in a comment - however, several people have asked about this and so I'll make a video on this subject in the new year some time and talk about it in the context you've described there since it's a problem many people want to solve! Cheers!

  • @shoot4rank765
    @shoot4rank765Ай бұрын

    Does this state machine system also make sense for my 2D platform game? What do you think about it, any suggestion for 2d metroidvania games?

  • @git-amend

    @git-amend

    Ай бұрын

    Sure, it would work for any type of game!

  • @ItsDan123
    @ItsDan1235 ай бұрын

    I'm curious how ActionPredicates were envisioned, I was under the impression C# actions were similar to Func's but didn't return a value

  • @git-amend

    @git-amend

    5 ай бұрын

    Great question. You are correct that Actions are like Funcs but don't return a value. The idea would be to wrap an existing C# Action so that you could pass it around as an object. You would need to maintain a boolean state in the Predicate to know if the event was fired or not, and make sure to reset the state each time after you check it, so you are ready for the next event to fire.

  • @ItsDan123

    @ItsDan123

    5 ай бұрын

    @@git-amend Alright, is there a simple use-case for a feature you'd implement using that? And while researching this myself I came across the native C# Predicate generic, any reason not to be using that? Is it just the convenience to having the predicate as an object that can be instantiated with the information it needs to evaluate it's result?

  • @git-amend

    @git-amend

    5 ай бұрын

    @@ItsDan123 The original idea for wrapping an Action inside a custom Predicate was to handle single Input System changes - you might want to listen to the InputSystem.onActionChange callback for example and handle it's payload - you can then use that value to determine how the Predicate evaluates. C#'s Predicates are great for simple, usually stateless conditions. Using a custom IPredicate interface, on the other hand, can allow for explicit state management, and flexibility in complex or large-scale situations. You could implement state management through a C# Predicate by using closures, but it is less transparent and potentially cumbersome.

  • @ItsDan123

    @ItsDan123

    5 ай бұрын

    @@git-amend Okay I think it just clicked. It's not about calling the provided delegate like in the Func predicate, it's about observing whether an action has fired or not and retaining that state. So for example if I have a pressure plate that fires an event when the player first stands on it and a door that requires the plate to be active, a predicate which is watching for that action to fire and storing the state change would be one way to hook those up.

  • @git-amend

    @git-amend

    5 ай бұрын

    @@ItsDan123 Yes, that's a good potential usecase. You hit the nail on the head - it essentially would be an event observer.

  • @Abdulwahab-vb6he
    @Abdulwahab-vb6he10 ай бұрын

    As a professional what do you do for living? your seris are amazing i am learning alot of new sruff.

  • @git-amend

    @git-amend

    10 ай бұрын

    Thanks! Glad the videos are helpful. As for my profession, I might actually talk about that in a future video… stay tuned!

  • @wagonwheel6657
    @wagonwheel66577 күн бұрын

    very useful, you could make me pay to find this information. many thanks

  • @git-amend

    @git-amend

    7 күн бұрын

    Glad it was helpful!

  • @kyriakosgeorgandis3272
    @kyriakosgeorgandis32722 ай бұрын

    I'd like to ask, why do we need an ITransition when we have just one Transition class?

  • @git-amend

    @git-amend

    2 ай бұрын

    That's a good question. More often than not, I tend to program to abstractions instead of concrete implementations. This makes the code more extensible, easier to test and promotes loose coupling. Check out this article about programming to interfaces: www.baeldung.com/cs/program-to-interface

  • @kyriakosgeorgandis3272

    @kyriakosgeorgandis3272

    2 ай бұрын

    @@git-amend Thanks so much! Although new to Unity I've been into OOP with java for a long time and I've struggled to understand such concepts whenever I checked other people's code. It's the first time I've ever found a person that expresses their thoughts while coding such complex concepts and I'm able to conceive them! Keep making such amazing tutorials

  • @hydroweapon
    @hydroweapon3 ай бұрын

    good video and all but seriously - how the hell do you remember all this?

  • @git-amend

    @git-amend

    3 ай бұрын

    Thanks! I take a lot of notes with Obsidian 😄

  • @hydroweapon

    @hydroweapon

    3 ай бұрын

    @@git-amend any books etc you can recommend?

  • @git-amend

    @git-amend

    3 ай бұрын

    @@hydroweapon Sure, there is a pinned comment with a reading list in the Programming section of the Discord server, link on the KZread channel about page.

  • @hydroweapon

    @hydroweapon

    3 ай бұрын

    @@git-amend awesome, thanks

  • @mohokhachai
    @mohokhachai8 ай бұрын

    So easy

Келесі