Build a Better Finite State Machine in Unity

  Рет қаралды 26,344

git-amend

git-amend

Күн бұрын

Пікірлер: 135
@git-amend
@git-amend Жыл бұрын
Hit the Like button and Subscribe to keep up with this series! New videos every week!
@Cloud-Yo
@Cloud-Yo 11 ай бұрын
I find your content to be the most sensible and advanced in terms of game architecture on KZbin. 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 11 ай бұрын
Cheers! I appreciate that! Always trying to find a balance between speed and viewer retention! 😀
@Cloud-Yo
@Cloud-Yo 11 ай бұрын
@@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!
@catpyjamas
@catpyjamas 3 ай бұрын
I had a team member that implemented an FSM that was a bit different than this, but it was also very powerful. The way he had it set up, each character would inherit from the base state machine class, and in that inherited state machine, he would initialize all the states. Then each state would take an action in its constructor that basically was a method that declares a bunch of StateMachineTransition objects. Those are added to a list, and each transition also had an OnEnable/Disable method as well as update/fixed update on it. That way, it also separated out all the state machine states/transition declarations out of the player controller component class. Still though, eventually as I used it in my own project, it got too cumbersome when I had like 40 different states on an enemy AI. But that's a state machine issue in general, it can only take you so far. Glad it happened though, since that's how I discovered this amazing channel. I was looking for a GOAP approach and found your video on that.
@git-amend
@git-amend 3 ай бұрын
Awesome, glad to hear that. Glad you are here!
@justinjohn7656
@justinjohn7656 6 ай бұрын
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 6 ай бұрын
Thanks for the comment! Glad you like it!
@dreamisover9813
@dreamisover9813 9 ай бұрын
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 9 ай бұрын
Glad to hear that!
@brianwilson7497
@brianwilson7497 8 ай бұрын
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 8 ай бұрын
Awesome, thank you!
@simoncote4064
@simoncote4064 7 ай бұрын
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 7 ай бұрын
Thanks for the kind words! Glad this helped you out, you might like the latest video about GOAP too, though unrelated to character controllers.
@ekekw930
@ekekw930 10 ай бұрын
Great implemenation! Reminds me of Jason Weimann's FSM. You and him are both great C# developers
@git-amend
@git-amend 10 ай бұрын
Thank you!
@dustintaub
@dustintaub 4 ай бұрын
Your content is the best Unity/C# reference I have on the internet. If I'm thinking about a pattern or process I want to implement, I check here first. You're code and tutorials are the best.
@git-amend
@git-amend 4 ай бұрын
Awesome, thank you!
@Broudy001
@Broudy001 Жыл бұрын
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 Жыл бұрын
Glad you enjoyed it! I like comparing other people's solutions to problems as well, especially inventory systems!
@P3trout
@P3trout 4 ай бұрын
Absolute GEM this channel .. thank you for your work !
@git-amend
@git-amend 4 ай бұрын
My pleasure!
@bhuvneetsaggu4011
@bhuvneetsaggu4011 10 ай бұрын
love your voice.. i have seen soo many fsm tutorials.. but your video fits best to my project. thanks
@git-amend
@git-amend 10 ай бұрын
Awesome, thank you!
@kattakittaxr
@kattakittaxr 11 ай бұрын
Loving this tut. Great Job!
@git-amend
@git-amend 11 ай бұрын
Thanks!
@grimsbaldruk4014
@grimsbaldruk4014 9 ай бұрын
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 9 ай бұрын
Great, love to hear it!
@GTZ-98
@GTZ-98 8 ай бұрын
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 8 ай бұрын
Thanks! Glad you liked it!
@GTZ-98
@GTZ-98 8 ай бұрын
@@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 8 ай бұрын
@@GTZ-98 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!
@GTZ-98
@GTZ-98 8 ай бұрын
@@git-amend Great input, thank you very much! I'll do it that way and just keep iterating on it!
@GTZ-98
@GTZ-98 6 ай бұрын
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
@solid-parker237
@solid-parker237 4 ай бұрын
I feel like I'm listening to Vincent from Cyberpunk as if he's helping me lay out my game's architecture.
@git-amend
@git-amend 4 ай бұрын
Not sure if that's a compliment or not, but thanks I guess!
@solid-parker237
@solid-parker237 4 ай бұрын
@@git-amend it is
@skyswimsky1994
@skyswimsky1994 10 ай бұрын
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 10 ай бұрын
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 10 ай бұрын
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 8 ай бұрын
@@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!
@aleksapetrovic7088
@aleksapetrovic7088 Ай бұрын
Yes please. ❤
@sweilz
@sweilz 3 ай бұрын
It's great.🎉 Can you teaching more about Hierachical StateMachine?😊😊
@git-amend
@git-amend 3 ай бұрын
It's on the list to videos to make, so hopefully one day!
@LuizMoratelli
@LuizMoratelli 12 сағат бұрын
At any other video do you change the FSM to a Hierarchical to be easy to do states for attack?
@Sosa829
@Sosa829 11 ай бұрын
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 11 ай бұрын
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 11 ай бұрын
@@git-amend I see, it's like making it customizable so we can add any information we might need! Thanks for the response.
@kevin41307
@kevin41307 9 ай бұрын
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 9 ай бұрын
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.
@pliniojrm
@pliniojrm 10 ай бұрын
From the excellent content you are providing, i wish you could make a video creating an "Utility ai".
@git-amend
@git-amend 10 ай бұрын
Interesting. What kind of features do you suppose that would have?
@pliniojrm
@pliniojrm 10 ай бұрын
​@@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.
@zerothehero.takeasip6612
@zerothehero.takeasip6612 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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 Жыл бұрын
@@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 Жыл бұрын
@@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 Жыл бұрын
@@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.
@diolix635
@diolix635 2 ай бұрын
Hello great video, i have implemented your state machine in my game and i found one edge case with the any transitions in the GetTransition method. In the loop, we dont test if the current state is the target (To) state of the transition. foreach (var transition in anyTransitions) { if (transition.Condition.Evaluate()) return transition; } I had a bug where i couldn't get out of crouch state, because any state transition to crouch when crouch is pressed, even the crouch state. My fix : foreach (var transition in anyTransitions) { if (transition.To == current.State) continue; if (transition.Condition.Evaluate()) return transition; }
@Mamei.007
@Mamei.007 10 ай бұрын
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 10 ай бұрын
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.
@antijulius
@antijulius 3 ай бұрын
What are you using to draw your diagrams? I'm sure you've answered this before but I've been digging through the comments without any luck. (Really appreciate the diagrams by the way.)
@git-amend
@git-amend 3 ай бұрын
That's called Excalidraw
@hailelam4112
@hailelam4112 8 ай бұрын
Thank you so much.
@git-amend
@git-amend 8 ай бұрын
You're welcome!
@holmbergen
@holmbergen 3 ай бұрын
How would you handle UI states for example pause menu or a player selection screen without tightly couple menu states to the player controller? Using events/eventbus?
@shunpeng5700
@shunpeng5700 9 ай бұрын
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; } }
@jean-michel.houbre
@jean-michel.houbre 6 ай бұрын
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 6 ай бұрын
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 6 ай бұрын
@@git-amend Ok. I understood that it could be used from outside the FSM. Thanks.
@boon8950
@boon8950 5 ай бұрын
Question: How would I use a UnityEvent in the state class's OnEnter method (I made base class inherit from monobehaviour so that I can put it on a game object and see inspector variables such as the UnityEvent)
@git-amend
@git-amend 5 ай бұрын
I think this question is too complex to answer without seeing your code. You might want to ask on Discord and perhaps someone can give you some guidance after they've been provided with more context.
@tianqigao869
@tianqigao869 Жыл бұрын
cool!
@wagonwheel6657
@wagonwheel6657 6 ай бұрын
very useful, you could make me pay to find this information. many thanks
@git-amend
@git-amend 6 ай бұрын
Glad it was helpful!
@abc-wo7pw
@abc-wo7pw 10 ай бұрын
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 10 ай бұрын
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.
@maciejgoralczyk8174
@maciejgoralczyk8174 4 ай бұрын
How can one implement EventPredicate? Such class would take event in constructor (this is where it gets tricky), and would evaluate to True when the event would be invoked (from its class)
@git-amend
@git-amend 4 ай бұрын
This has been a discussion on Discord (a while back). You can have a read on the server here to see some discussion and examples: discord.com/channels/1192509369594679488/1192845332552351754/1215196015477653505 Or search for 'Action Predicate' or 'ActionPredicate' on the Discord server.
@maciejgoralczyk8174
@maciejgoralczyk8174 3 ай бұрын
@@git-amend The problem was that the Action was Invoke from Predicate class. In the end I used reflection to get the event in the predicate, because I wasn't able to pass it through constructor
@limit6864
@limit6864 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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 Жыл бұрын
@@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 Жыл бұрын
​@@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.
@Jecyn14
@Jecyn14 3 ай бұрын
This is probably something i missed in an earlier video, but i have a problem where if i walk off of a platform, gravity doesn't effect my player until i've stopped moving around. Any idea what could be causing this? Jumping works fine with gravity being applied after the timer ends, and isGrounded is being set to false when i walk off the platform, even though im able to walk around in the air
@Jecyn14
@Jecyn14 3 ай бұрын
Figured out where i made the mistake. In the handle horizontal movement function, i was setting the y velocity directly, but needed to reference the rigidbody's velocity.y instead.
@alishi961
@alishi961 11 ай бұрын
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 11 ай бұрын
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!
@mohamadborna3678
@mohamadborna3678 7 ай бұрын
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 7 ай бұрын
Not quite sure what you are referring to, can you elaborate?
@mohamadborna3678
@mohamadborna3678 7 ай бұрын
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 7 ай бұрын
@@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.
@ItsDan123
@ItsDan123 10 ай бұрын
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 10 ай бұрын
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 10 ай бұрын
@@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 10 ай бұрын
@@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 10 ай бұрын
@@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 10 ай бұрын
@@ItsDan123 Yes, that's a good potential usecase. You hit the nail on the head - it essentially would be an event observer.
@shoot4rank765
@shoot4rank765 7 ай бұрын
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 7 ай бұрын
Sure, it would work for any type of game!
@Abdulwahab-vb6he
@Abdulwahab-vb6he Жыл бұрын
As a professional what do you do for living? your seris are amazing i am learning alot of new sruff.
@git-amend
@git-amend Жыл бұрын
Thanks! Glad the videos are helpful. As for my profession, I might actually talk about that in a future video… stay tuned!
@PuppetDev
@PuppetDev Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
​@@git-amend Ah, thanks for confirming. Yeah, I can see how that would make it easier.
@rapaltiar
@rapaltiar Жыл бұрын
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 Жыл бұрын
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
@elminsmajlovic4564
@elminsmajlovic4564 6 ай бұрын
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?
@lke5207
@lke5207 4 ай бұрын
Awesome!Could you continue this series? I'm wondering how to make a dialog system between Hero and NPC.
@inkofthedragon
@inkofthedragon 10 ай бұрын
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 10 ай бұрын
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 10 ай бұрын
@@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 10 ай бұрын
@@inkofthedragon Sounds good. As for color, I think it's just the default.
@kyriakosgeorgandis3272
@kyriakosgeorgandis3272 8 ай бұрын
I'd like to ask, why do we need an ITransition when we have just one Transition class?
@git-amend
@git-amend 8 ай бұрын
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 8 ай бұрын
@@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
@junaidywijaya
@junaidywijaya Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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 Жыл бұрын
@@git-amend oh wait, i think i found it, it works now.. thanks
@shoot4rank765
@shoot4rank765 3 ай бұрын
Is this system work for enemy AI?
@git-amend
@git-amend 3 ай бұрын
Watch the next video in this series, that's what it's all about. kzbin.info/www/bejne/m4OQcnqoatN-e7c
@hydroweapon
@hydroweapon 9 ай бұрын
good video and all but seriously - how the hell do you remember all this?
@git-amend
@git-amend 9 ай бұрын
Thanks! I take a lot of notes with Obsidian 😄
@hydroweapon
@hydroweapon 9 ай бұрын
@@git-amend any books etc you can recommend?
@git-amend
@git-amend 9 ай бұрын
@@hydroweapon Sure, there is a pinned comment with a reading list in the Programming section of the Discord server, link on the KZbin channel about page.
@hydroweapon
@hydroweapon 9 ай бұрын
@@git-amend awesome, thanks
@mohokhachai
@mohokhachai Жыл бұрын
So easy
@universegames7692
@universegames7692 2 ай бұрын
So you define playerController in baseClass ???
@SLthenus
@SLthenus 8 күн бұрын
I don't like interface coz it's force our inheritance function to always Public.
EASY Unity Enemy AI using a State Machine
26:04
git-amend
Рет қаралды 13 М.
Expression Trees in Unity: The SECRET to Flexible Game Logic
14:50
Ice Cream or Surprise Trip Around the World?
00:31
Hungry FAM
Рет қаралды 21 МЛН
ТВОИ РОДИТЕЛИ И ЧЕЛОВЕК ПАУК 😂#shorts
00:59
BATEK_OFFICIAL
Рет қаралды 5 МЛН
Better AI in Unity - GOAP (Goal Oriented Action Planning)
45:16
When to use Factory and Abstract Factory Programming Patterns
12:13
Using Octrees and A* for Efficient Pathfinding
31:22
git-amend
Рет қаралды 9 М.
choosing a game engine is easy, actually
15:08
samyam
Рет қаралды 582 М.
Code Class - Hierarchical State Machines
29:41
AdamCYounis
Рет қаралды 21 М.
Finite State Machines in Godot 4 in Under 10 Minutes
7:16
Bitlytic
Рет қаралды 312 М.
How to Code Behaviour Trees in Unity C#
23:19
git-amend
Рет қаралды 17 М.
Ice Cream or Surprise Trip Around the World?
00:31
Hungry FAM
Рет қаралды 21 МЛН