The best part about this video for me was the refactoring, too often you see state machine lessons jump into the component-based implementation without an explanation as to why it's being made that way. Going from a messy script, to a longer but cleaner enum-based system, to the compact and extensible component-based system is an ESSENTIAL part of the learning process because if you don't know why you're doing what you're doing, you haven't really learned. You've made my past mistake of copying code you can't read.
For those how feel overwhelm by the logic behind the state machine pattern, re watch the video a few times and take notes of everything about what each script/function does, that way you will learn about the state machine rather than just memorizing the whole thing. this pattern it s one of the best things to learn in game dev . Thanks Adam for being a great teacher and an lovely person, and congrats on the founding of Insignia
This state machine tutorial is fantastic! Your detailed explanation of state transitions and the logic behind it really clicked for me. The way you handle state machines is intriguing and makes coding feel less daunting. Looking forward to more in-depth tutorials. Thanks for shedding light on this topic! I have always wondered how to go about implementing this. Thank you Adam
I was experiencing the Enum downfall and started watching videos on how to implement something like this. Pretty overwhelming for me initially, then I stumbled upon your video. I've been a long time subscriber but only knew about your pixel art related content. I'm super grateful for this and your explanations, thank you. Looking forward to the follow up!!
One little addition I might throw in here is the concept of finite state transitions. Something along the lines of "You can do an attack while Idle but not while walking". As the developer it is crucial to really think about the behaviour of the thing you are trying to create and use a logic that represents this as closely as possible. Overriding states through user input is only one of the many ways one can achieve that. A similar logic would be something like keeping a list of states your state can transition to or even implementing this in the states themselves if they are very closely tied together, like an aerial attack that can always only happen out of an aerial state
This is definitely a topic we'll cover in the follow-up video. Transition pairs were actually one of the first things I added to insignia's state system and then never used because of the tree structure I'll be showing next.
Necroposting, but I wanted to add that doing it like this is also nice because you can plan this very intuitively & abstractly in the design phase - for example, you can draw a graph with your states as the edges, the transitions as directed edges, and the conditions for a given transition as a label. So, in practice, you can have edges like "airborne →(hits ground)→ grounded" and "airborne →(is close to ledge & presses "grab")→ ledgehang" With transition conditions in parentheses. This way, you get to design your movement pretty freely without having to worry about code at all yet, and it'll still translate pretty much 1:1 in the coding phase. Of course, the hard part is in checking those conditions now.
Also, specifically for aerial attacks, implementing it as something like a "sub-state" or even a nested state machine might be worthwhile? Cause both "airborne - idle" and "airborne - attacking" are definitely different states, but you also definitely want both of them to end as soon as you hit the ground, so you don't get weird edge cases like "you can fall through the ground if you hit it during an aerial attack animation" cause you forgot to copy some transition, which can't happen if they're both substates of an airborne state that has that transition no matter what
You're awesome, I love how thorough you are! You always cover all the bases and I know you take the time to organize your thoughts before presenting them to us. Thank you, for being an excellent teacher.
I think you explained State Machines so well .This video made me think how different aprouches can be when coding . I'd love to watch a video from you about creating a new editor window or an animator. I love any content you share. Thanks a lot
EDIT: You change the code base to not need it starting at 32:11 I do not know if you did this just so it is easier for people to understand, but instead of checking "if (state.isComplete)" on update you could instead have a event on the sate that the state Machine Handler subscribes to, which would make it run faster.
Hey Adam, just wanted to say thank you so much for this video. I’d got to the point where I’d implemented running, jumping, sliding, crouching, attacking; and i was becoming more and more uncomfortable with the code. I started researching state machines and watched a bunch of videos, but nothing resonated with me. I was envisioning something concise, readable, re-usable and scaleable but I was struggling to implement it. This video perfectly encapsulates it. I wish i was able to define it so clearly like you. But thank you so much, once I’ve watched this a few more times I think I will be able to implement what i’ve dreamed of beautifully. I’m especially excited about the follow up hierarchical state machine. I’ve been building in Godot and for the most part prefer it to Unity, yet I do prefer the type system with C#. I hope I can type this sufficiently in gd script. Thanks also for the little nuggets, that mapper that makes sure the jump animation is timed perfectly: genius. I would never have thought of that. Amazing stuff. I’m so proud to be a patron: your content is sublime. Good day!
Hi Adam, I have no words to express how much I enjoy your work, the quality of your pixel-art and how easy and clear your manage to explain your code. I become a gamedev this year and the 2 softwares I need/must improve are Unity and Aseprite, I am doing some Udemy courses, but nothing is so polished as your work, so I must ask, do you have any complete class that tackles Aseprite + Unity? if so, please send me the link! Sorry for the big post, and thank you for such quality videos ❤
THANK YOU for possibly being the first person on RUclips to correctly use the Animator for Pixel Art, so many authors go thru a weird loop of creating bools and animator bools, then setting up animation entry and exit, then having to turn off all the blending options for each new animation, then changing said bools from the code to have the animation change... While it's simply a matter of using play(). But I do think you could potentially use this Animator state machine to control game logic, right? As far as I understand you can actually attach a script to each animation. So you could in theory, if you feel like using this animator as a state machine, by connecting things and whatnot, potentially use it as a state machine in itself. And this is something I would love to see explored! And they look like they have enough functionality to make a pretty full fledged state machine. OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
It's videos like this that make me feel like I can create my own AAA game. Then I load up the IDE and have no clue what I'm doing. XD Your videos are the things that give me hope
Excellent video, thank you! I’ve been doing my state-machines a bit differently with the base state not inheriting from MonoBehaviour, but I really like your approach. It addresses a lot of things that felt were a bit awkward with my own approach. I’m very much looking forward to the future videos, especially the hierarchical state-machines, something that would have been so useful for my current project.
I really enjoyed this and can't wait for the next one. Typically what I like to do is create a Character class that essentially operates as a store for everything a living creature will need, and then you override that with the Player class or BasicEnemyAI. It seems like there's a lot of overhead setup with making new game objects and setting state to them and configuring props in those components and dragging their references onto the actual character, and then passing in those references to the individual states every time. Wouldn't it be easier to do something like the Character class where you can pass that into the state so it can hold a single loose reference for things like animators, rigidbodies, health components, etc?
There are many ways and variations to create a state machine. Use this video as a starting point in your journey. It’s quite an advanced topic at pro level.
I went with a component state machine too because I felt it allows me to leverage existing unity functionality, so I just used the monobehaviour's Update / OnEnable / OnDisable, instead of custom functions and I enable/disable my components. It's still reassuring to see someone more experienced use the component based approach. Very nice format, with introducing the enum based version and walking through the refactoring. One thing I missed is at least a mention of how your behaviour tree visualisation is made. Is it an asset? Is it a custom editor window you made? Looking forward to the next instalment!
Not sure if i may have missed something, but using your state machine and going from air state to idle state after being grounded doesn't play my idle animation rather just the first frame of idle. Running to idle is working correctly, but I cannot find any reason why it wouldn't do the same for air and idle Edit: So it seems my only solution is to fix the animator.speed in idle state on enter to 1, as the speed is being set to 0 by air state. For some reason when I would enter walk state after being in a 0 anim speed idle, it would set it back to 1, so I'm not quite sure what was causing an issue as it should work both ways as it does in your video, but I'll still throw the solution out there for those that may run into the same issue as me
This is the tutorial on controlling the movement, animations, and a State Machine pattern of a 2D character, that I have been looking for for so long. Thank you, Adam!
What is "override void Exit()" used for? You mentioned Enter() would be the initial startup of the state, then Do() plays in Update(), but I might have missed when you commented on Exit().
he calls it at the end of the video when checking if the new state is different from the old state to allow the old state to do whatever it needs to when it's interrupted.
Ohhh Man I am getting mad right now !!! Brought new Top down engine asset && wanted to have some sort of tweaking to add it to my new game but I can't able to get the way they had written the code .... it's some what readable but tweaking is a lot difficult spend over 5 full days to find such a great tut !!! Thanks Dude !!😇
Hey Adam, I’ve been watching your videos pretty much since I began as a pixel artist, and they’ve helped me tremendously, especially over the last few weeks since a lot of the topics you cover are issues I have with my own art lol. I’m not sure if you’ll see this comment, but would you ever consider doing a video of a “pixel art review”? Not of a viewer’s, but rather character sprites from other games, and how you’d personally improve or change them? I’ve seen a lot of games be shown on this channel as examples, and rather than obvious ones like Metal Slug or other well-known games with good pixel art that would be hard to say much about than what’s already known, I’d actually think it’d be really cool if you did more obscure or lesser known pixel art styles/sprite work, like the Megaman Zero or ZX series’ sprites, since they both use the same character base. The pixel art in those games are probably the least covered online since everyone mainly focuses on the Classic Megaman games or the X series, so it’d be really cool to see from you. Again, love your content and have a great day if you’re reading this!
Good explanation. But gets more involved in isometric games with several directions, especially if your system has to deal with both 2d sprites and the 3d models. May also want to break some animation mid play, while transitioning smoothly to the new sequence. Some animations could be conditional (i.e. a monster with low health will be stumbling on walk). And then higher level scripting for cutscenes could be reusing the pathfinder and setting the ai states manually, while also interacting with a physics system. Would love to see a survey of different approaches and their trade offs.
THANK YOU SO MUCH FOR THE VIDEO! I have a problem where my raycast code from my enemy (not run by a state machine) is sometimes not detecting the collision with my player (is run by a state machine). I was wondering if you knew if the fixed update method in the state machine could be slowing down other aspects of my game, resulting in missed collisions? Thanks!
Thanks so much for making this video! I just found your channel today randomly- and I can see this is solving things that I am struggling with in my own game (yeah i have a huge movement script of tons of 'if' statements). As a beginning C# user it's so hard for me to understand when something isn't working right! This will help so much!
I went through a 4 week stint where for some reason none of my animations were playing (past frame1) I couldn't figure it out! But then found that anything messing with the (animator.speed) was what was stopping the animations from playing. I'm guessing cause it's making the speed be zero. I want to use that animator speed idea but ...hmmmm its a puzzle.
i want to know your opinion on the blendtree,isn´t more code clean just put one blend tree called "xmove" with idle and run in it and set a code like this: animation.SetFloat("xmove", Mathf.Abs(xInput)); with coding is more easy to control if something is bad but is a lot more complicated i supose,i am just in the start of coding so i dont know which one is better
Great Video :) Ive got one little question regarding the aseprite importer. I always avoided it since it seems to be messing up my animations when I add or remove frames from the file. When I for example add 2 Frames to an animation tagged "Walk", every other animation behind that will be shifted by two frames in the Unity animation clip. The workflow itself seems nice but issues like these really bother me, is there any way to savely export the animationclips in a way that the old ones just get replaced. I need to use the exported Animator Controller and exported animation clips since its important that the animations also scale the characters slightly, making it impossible to use the pre defined read only ones :/
When I tested it before filming, I was able to add frames to a tag in Asperite after the initial import and had no issues seeing the Unity animations update accordingly. This is the first time trying it in earnest, since I've got my own systems that I've been using for a long time. It surprised me with how simple it is for basic animations like this, so I might use it in future game jams. Of course, there are limitations that don't make it very extensible. Eventually you typically need to build your own thing, but that's what these tutorials are for :)
Thank you for this! Do you mind sharing how you would use this for Attack inputs? Unlike ground/air states which should be interrupted immediately based on whether we're on the ground, attacks should last the entire duration of the attack animation before resetting to another state. With the last modification you made in the video that Sets state on every Update() based on some logic, the state machine no longer relies on state.IsComplete so I'm not sure how to incorporate this behaviour of waiting for the state to finish. Any advice would be appreciated. Thank you!
This would be dependent on how much control you want to have. In Insignia, I have properties that live on the player called "canMove" and "canAttack", which I check before cancelling into states. It's then the responsibility of the action states to set these to true. A better approach could be to have these booleans as a property of the states themselves, and so you'd be checking if the current "state.canMove" is true before branching into any kind of movement interruption, etc. It would be really game-dependent, as there are even different conditions for different kinds of attacks in my game. e.g. Air attacks are interrupted when landing, while ground attacks are interrupted when falling.
Hey Adam, I hope everything is good. I was fascinated with the helper function used in the video. It got me intrigued that you used math to solve the animation problem. So, it got me thinking, what do you recommend for learning math for game development. Are there any resources that you recommend, or I should go back and study math from the beginning?
I would encourage you to be project oriented in your learning. If the project you're making needs specific math, you'll encounter it while trying to solve the associated challenges. Otherwise you'll just be learning for learning's sake (nothing wrong with that, either!)
Everybody gets this wrong, the states are not finite. That doesn't mean anything. The machine is finite, or in other words there is a FINITE NUMBER of states.
hey adam, do you know of a way to have a game do attack animations with different weapon models without copy and pasting the animation and changing every frame?
how can i make something like a attack or dash behavior? I can't get it. I made it in my own way, with spaghetti code, but i can't understand how to make the thing i created work within system in the video.
Hi Adam, I really like your videos, they teach me a lot, but I'm having a hard time understanding the running animation for a 64 pixel hero, I know you already have a running tutorial, but the hero there is 32 pixels, ideally I would like to see a tutorial on creating Armin's run from Insignia if possible, or a running tutorial for a 64 pixel hero, thanks for your attention.
is there a reason you made each state a script that was attached to a game object and not just a static class that any object can reference or say a scriptable object system? Seems like more work making each state a sub game object.
They are components primarily to allow for instance data to be set in the inspector, at the game object level. A static class would not allow for this, and scriptable objects are designed as data objects, not really intended for runtime logic.
@@AdamCYounis I mainly meant to hold the data for what the state does and have a script that swaps between the states and takes the data from a different source than having say 200 sub game objects holding 200 scripts under the player in the hierarchy which seems less performant to me. So A manager script that references the Data for each state. Since states aren't changing the data on the fly then why would it need to be modified at runtime?
Note that if you have knowledge of UI toolkit, making a simple node based UI for the selected state machine would be a big plus performance wise for more complex entities. Using monobehaviour over pure class does have a slight computational drawback, and it pollutes the entity's hierarchy with, not only the components themselves, but also with unused transforms. Imagine having 50 states for a complex boss, all packed up in the prefab of that boss 😱. Also, although I guess it's going to be talked about in the next video, using a state machine controller can help decouple a lot of the boiler plate code for handling the switching of states. Otherwise, the state machine usually ends up being an ugly spaghetti code blob, switching from one state to the next with ifs and elses. Last thing: note that using Unity's "animator" state machine is perfectly fine for any state machine if your game can handle the, again, computational drawback from the parts of the system you don't use (like blended, as specified in the video). With a bit of work, you can make a pretty generic and solid StateMachineBehaviour.cs based system.
Interesting, i have made my own state machine system from scratch, i have made videos about how i did it, it's generic so you can use it for multi different NPCs and not designed for only one object
Man, i still don't get your approach to state machines. I think where I struggle is how the code executes, particularly the do, enter, fixedDo etc take place. Been trying to understand this for months. Maybe it's just one of those things im never going to get.
24:38 - The update function of the "state machine" class (PlayerMovement for the sake of this tutorial) calls state.Do(), as well as SelectState() which handles Enter() and Exit().
@@AdamCYounis I have no idea what state Do, enter or exit actually do. I understand them conceptually; do, enter, exit something. I just really struggle with how they run logically; how they run line by line. The state object is, i believe, just a framework you can use over and over, and code within it can be trailered for things common across states etc. I just struggle how they are interpreted by Unity and order of code execution. This probably sounds complete jibbirish but I'm not used to creating objects in programming, and how to use them. im more of a functional programmer, and used to keeping things on one page.
@@cyberblitzTBH I'm not super familiar with Unity or with Adam's exact system, but maybe that'll help me explain this stuff to you in a more agnostic programming perspective. Basically, every frame, Unity calls Update() on all the active game objects Objects with a state machine will now call state.Do() and SelectState(), because that's what they were told to do in their Update() function. state.Do() is just a function, the same as functions in the paradigm you already know. It's going to do something. Maybe it tells the enemy AI to approach the player, as an example. Maybe it spits out "Hello, World." It doesn't matter. It is just running the specific lines of code written under "state.Do()" for the state that was assigned to this game object. SelectState() changes which State the game object is in, according to its current situation. This is just simple IF statements. If you're in the air, you're in the aerial state. If you're attacking, you're in an attack state, etc. It figures out which state the object should be in, and puts it in that state. Then, in future Update()'s (that are happening all the time as the game is running), the behavior will change according to the new state. On the line level, it's just something like this: Update() -> the line of codes under "Update()" run, calling the "state.Do()" function state.Do() -> the lines of code under state.Do() run, they come from the specific "state" we assigned to our character earlier. Update()-> now that state.Do() finished, Update() continues to its next line of code, which is calling SelectState() SelectState() -> the lines of code under "SelectState()" run.
@@AdamCYounis I think it's a valid point. You showed a tree structure at the beginning which was confusing, because state machine you shown later, in this particular video, is not hierarchical. It's state A to State B to State C to State A, basically.
@@AdamCYounis On that note, is your behavior tree actually connected to any code/logic or is it just a visual guide? Your implementation in Insignia is closer to a behavior tree than a state machine, technically speaking. LlamAcademy has a few videos on how those two differ from each other. So, is your behavior tree connected to any logic? (i.e. the one in the graph view. And did you code the graph view yourself?)
@@captainawesome2226 I coded the graph view myself. It's "connected" in that it visualises the current state, and I can force the character into a state by clicking it. But the graph is designed primarily to reflect the structure inherent in the code, it's a generated visualisation for debug purposes.
"switch" implies that you have to pick one or the other. My long term game is a Unity game and can't be ported to another engine. For smaller games I produce for jams, Godot is an engine I've begun to use, but it's far from a replacement for Unity at this stage.
Where did you set isComplete =false in component state machine I write all the code as yours but do function and the if statement with isComplete in update did not work 😢
It's simple: I see a state machine video... I like and subscribe.
i have watch your video of state machine and more.... That Was Nice..
As someone who just started out, would it be worth it to ask for an updated state machine video from you?
The best part about this video for me was the refactoring, too often you see state machine lessons jump into the component-based implementation without an explanation as to why it's being made that way. Going from a messy script, to a longer but cleaner enum-based system, to the compact and extensible component-based system is an ESSENTIAL part of the learning process because if you don't know why you're doing what you're doing, you haven't really learned. You've made my past mistake of copying code you can't read.
This is by far THE best state machine tutorial... I've already started applying some of this stuff and it's super useful
Already subscribed to you on Twitch... but I can't thank you enough for being part of my journey into tech/programming/and game development.
Thank you!
I've been very interested in how you handle your state machine while watching your stream, so thank you for taking the time to explain it so in depth.
For those how feel overwhelm by the logic behind the state machine pattern, re watch the video a few times and take notes of everything about what each script/function does, that way you will learn about the state machine rather than just memorizing the whole thing. this pattern it s one of the best things to learn in game dev . Thanks Adam for being a great teacher and an lovely person, and congrats on the founding of Insignia
This state machine tutorial is fantastic! Your detailed explanation of state transitions and the logic behind it really clicked for me. The way you handle state machines is intriguing and makes coding feel less daunting. Looking forward to more in-depth tutorials. Thanks for shedding light on this topic! I have always wondered how to go about implementing this. Thank you Adam
I was experiencing the Enum downfall and started watching videos on how to implement something like this. Pretty overwhelming for me initially, then I stumbled upon your video. I've been a long time subscriber but only knew about your pixel art related content. I'm super grateful for this and your explanations, thank you. Looking forward to the follow up!!
One little addition I might throw in here is the concept of finite state transitions. Something along the lines of "You can do an attack while Idle but not while walking". As the developer it is crucial to really think about the behaviour of the thing you are trying to create and use a logic that represents this as closely as possible. Overriding states through user input is only one of the many ways one can achieve that. A similar logic would be something like keeping a list of states your state can transition to or even implementing this in the states themselves if they are very closely tied together, like an aerial attack that can always only happen out of an aerial state
This is definitely a topic we'll cover in the follow-up video. Transition pairs were actually one of the first things I added to insignia's state system and then never used because of the tree structure I'll be showing next.
Necroposting, but I wanted to add that doing it like this is also nice because you can plan this very intuitively & abstractly in the design phase - for example, you can draw a graph with your states as the edges, the transitions as directed edges, and the conditions for a given transition as a label.
So, in practice, you can have edges like
"airborne →(hits ground)→ grounded"
and
"airborne →(is close to ledge & presses "grab")→ ledgehang"
With transition conditions in parentheses. This way, you get to design your movement pretty freely without having to worry about code at all yet, and it'll still translate pretty much 1:1 in the coding phase. Of course, the hard part is in checking those conditions now.
Also, specifically for aerial attacks, implementing it as something like a "sub-state" or even a nested state machine might be worthwhile?
Cause both "airborne - idle" and "airborne - attacking" are definitely different states, but you also definitely want both of them to end as soon as you hit the ground, so you don't get weird edge cases like "you can fall through the ground if you hit it during an aerial attack animation" cause you forgot to copy some transition, which can't happen if they're both substates of an airborne state that has that transition no matter what
You're awesome, I love how thorough you are! You always cover all the bases and I know you take the time to organize your thoughts before presenting them to us. Thank you, for being an excellent teacher.
I think you explained State Machines so well .This video made me think how different aprouches can be when coding . I'd love to watch a video from you about creating a new editor window or an animator. I love any content you share. Thanks a lot
Excellent timing. I have just been researching different types and approaches for state machines and look forward to the next video!
This is so efficiently explained it's amazing
Great video! Really happy to see more coding content from you, especially these more intermediate ones.
About to start my C# game Dev Journey, Love your video , I needed that , Explained in clear way , thank you very much
I love this series. I’m just starting making my own game and this has been super helpful
EDIT: You change the code base to not need it starting at 32:11
I do not know if you did this just so it is easier for people to understand, but instead of checking "if (state.isComplete)" on update you could instead have a event on the sate that the state Machine Handler subscribes to, which would make it run faster.
I think it's better to make what state decide to change to other state instead of checking if (state.isComplete)
@@ciutoivoi Ya I think having it check state.iscomplete is not the fastest way to do it, but it is not too slow. Just barely slower.
More State Machine tutorials :) especially on a boss will be appreciated Adam
hyped for the next state machine video! will you explore the enemy's AI machine in the future video?
Hey Adam, just wanted to say thank you so much for this video.
I’d got to the point where I’d implemented running, jumping, sliding, crouching, attacking; and i was becoming more and more uncomfortable with the code. I started researching state machines and watched a bunch of videos, but nothing resonated with me.
I was envisioning something concise, readable, re-usable and scaleable but I was struggling to implement it.
This video perfectly encapsulates it. I wish i was able to define it so clearly like you. But thank you so much, once I’ve watched this a few more times I think I will be able to implement what i’ve dreamed of beautifully. I’m especially excited about the follow up hierarchical state machine.
I’ve been building in Godot and for the most part prefer it to Unity, yet I do prefer the type system with C#. I hope I can type this sufficiently in gd script.
Thanks also for the little nuggets, that mapper that makes sure the jump animation is timed perfectly: genius. I would never have thought of that.
Amazing stuff. I’m so proud to be a patron: your content is sublime.
Good day!
Thank you for these awesome tutorials, they have really helped me improve my knowledge and thought processes while developing my game.
Hi Adam, I have no words to express how much I enjoy your work, the quality of your pixel-art and how easy and clear your manage to explain your code.
I become a gamedev this year and the 2 softwares I need/must improve are Unity and Aseprite, I am doing some Udemy courses, but nothing is so polished as your work, so I must ask, do you have any complete class that tackles Aseprite + Unity? if so, please send me the link! Sorry for the big post, and thank you for such quality videos ❤
THANK YOU for possibly being the first person on RUclips to correctly use the Animator for Pixel Art, so many authors go thru a weird loop of creating bools and animator bools, then setting up animation entry and exit, then having to turn off all the blending options for each new animation, then changing said bools from the code to have the animation change... While it's simply a matter of using play().
But I do think you could potentially use this Animator state machine to control game logic, right? As far as I understand you can actually attach a script to each animation. So you could in theory, if you feel like using this animator as a state machine, by connecting things and whatnot, potentially use it as a state machine in itself. And this is something I would love to see explored!
And they look like they have enough functionality to make a pretty full fledged state machine.
OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
best state machine tutorial out there I LOVED IT
It's videos like this that make me feel like I can create my own AAA game. Then I load up the IDE and have no clue what I'm doing. XD Your videos are the things that give me hope
I'm making a platformer so it was cool to see how you set up stuff. I'm not using state machines, but may need to in the future.
Thanks for these tutorials! I start making pixel art last year and I learned a lot from your channel!
Excellent video, thank you! I’ve been doing my state-machines a bit differently with the base state not inheriting from MonoBehaviour, but I really like your approach. It addresses a lot of things that felt were a bit awkward with my own approach.
I’m very much looking forward to the future videos, especially the hierarchical state-machines, something that would have been so useful for my current project.
I was literally just looking on your page to see if there were any new videos! crazy coincidence
I really enjoyed this and can't wait for the next one. Typically what I like to do is create a Character class that essentially operates as a store for everything a living creature will need, and then you override that with the Player class or BasicEnemyAI. It seems like there's a lot of overhead setup with making new game objects and setting state to them and configuring props in those components and dragging their references onto the actual character, and then passing in those references to the individual states every time. Wouldn't it be easier to do something like the Character class where you can pass that into the state so it can hold a single loose reference for things like animators, rigidbodies, health components, etc?
That's right! I'll be showing a more advanced example next video doing exactly that.
There are many ways and variations to create a state machine. Use this video as a starting point in your journey. It’s quite an advanced topic at pro level.
Thank you so much for all game tutorials!
I went with a component state machine too because I felt it allows me to leverage existing unity functionality, so I just used the monobehaviour's Update / OnEnable / OnDisable, instead of custom functions and I enable/disable my components.
It's still reassuring to see someone more experienced use the component based approach. Very nice format, with introducing the enum based version and walking through the refactoring.
One thing I missed is at least a mention of how your behaviour tree visualisation is made. Is it an asset? Is it a custom editor window you made?
Looking forward to the next instalment!
tutorial is great, the video is actually not long enough!😄
Not sure if i may have missed something, but using your state machine and going from air state to idle state after being grounded doesn't play my idle animation rather just the first frame of idle. Running to idle is working correctly, but I cannot find any reason why it wouldn't do the same for air and idle
Edit: So it seems my only solution is to fix the animator.speed in idle state on enter to 1, as the speed is being set to 0 by air state. For some reason when I would enter walk state after being in a 0 anim speed idle, it would set it back to 1, so I'm not quite sure what was causing an issue as it should work both ways as it does in your video, but I'll still throw the solution out there for those that may run into the same issue as me
This is the tutorial on controlling the movement, animations, and a State Machine pattern of a 2D character, that I have been looking for for so long. Thank you, Adam!
What is "override void Exit()" used for? You mentioned Enter() would be the initial startup of the state, then Do() plays in Update(), but I might have missed when you commented on Exit().
he calls it at the end of the video when checking if the new state is different from the old state to allow the old state to do whatever it needs to when it's interrupted.
The correct term at the time stamp 20:19 is expression bodied members
Saw your intro animation and subbed. Hope your content is good 😁
That was the best tutorial!! Thank You❤
Ohhh Man I am getting mad right now !!!
Brought new Top down engine asset && wanted to have some sort of tweaking to add it to my new game but I can't able to get the way they had written the code ....
it's some what readable but tweaking is a lot difficult
spend over 5 full days to find such a great tut !!!
Thanks
Dude !!😇
Hey Adam, I’ve been watching your videos pretty much since I began as a pixel artist, and they’ve helped me tremendously, especially over the last few weeks since a lot of the topics you cover are issues I have with my own art lol.
I’m not sure if you’ll see this comment, but would you ever consider doing a video of a “pixel art review”? Not of a viewer’s, but rather character sprites from other games, and how you’d personally improve or change them?
I’ve seen a lot of games be shown on this channel as examples, and rather than obvious ones like Metal Slug or other well-known games with good pixel art that would be hard to say much about than what’s already known, I’d actually think it’d be really cool if you did more obscure or lesser known pixel art styles/sprite work, like the Megaman Zero or ZX series’ sprites, since they both use the same character base. The pixel art in those games are probably the least covered online since everyone mainly focuses on the Classic Megaman games or the X series, so it’d be really cool to see from you. Again, love your content and have a great day if you’re reading this!
Good explanation. But gets more involved in isometric games with several directions, especially if your system has to deal with both 2d sprites and the 3d models. May also want to break some animation mid play, while transitioning smoothly to the new sequence. Some animations could be conditional (i.e. a monster with low health will be stumbling on walk). And then higher level scripting for cutscenes could be reusing the pathfinder and setting the ai states manually, while also interacting with a physics system. Would love to see a survey of different approaches and their trade offs.
Amazing tutorials!
THANK YOU SO MUCH FOR THE VIDEO! I have a problem where my raycast code from my enemy (not run by a state machine) is sometimes not detecting the collision with my player (is run by a state machine). I was wondering if you knew if the fixed update method in the state machine could be slowing down other aspects of my game, resulting in missed collisions? Thanks!
Thanks so much for making this video! I just found your channel today randomly- and I can see this is solving things that I am struggling with in my own game (yeah i have a huge movement script of tons of 'if' statements). As a beginning C# user it's so hard for me to understand when something isn't working right! This will help so much!
I went through a 4 week stint where for some reason none of my animations were playing (past frame1) I couldn't figure it out! But then found that anything messing with the (animator.speed) was what was stopping the animations from playing. I'm guessing cause it's making the speed be zero. I want to use that animator speed idea but ...hmmmm its a puzzle.
i want to know your opinion on the blendtree,isn´t more code clean just put one blend tree called "xmove" with idle and run in it and set a code like this:
animation.SetFloat("xmove", Mathf.Abs(xInput));
with coding is more easy to control if something is bad but is a lot more complicated i supose,i am just in the start of coding so i dont know which one is better
Great Video :) Ive got one little question regarding the aseprite importer. I always avoided it since it seems to be messing up my animations when I add or remove frames from the file. When I for example add 2 Frames to an animation tagged "Walk", every other animation behind that will be shifted by two frames in the Unity animation clip. The workflow itself seems nice but issues like these really bother me, is there any way to savely export the animationclips in a way that the old ones just get replaced. I need to use the exported Animator Controller and exported animation clips since its important that the animations also scale the characters slightly, making it impossible to use the pre defined read only ones :/
When I tested it before filming, I was able to add frames to a tag in Asperite after the initial import and had no issues seeing the Unity animations update accordingly.
This is the first time trying it in earnest, since I've got my own systems that I've been using for a long time. It surprised me with how simple it is for basic animations like this, so I might use it in future game jams.
Of course, there are limitations that don't make it very extensible. Eventually you typically need to build your own thing, but that's what these tutorials are for :)
@@AdamCYounis Thanks for the answer
Ola adam, você pode criar um tutorial de animação do cycle correndo em topdown?
Just started watching but wanted to point out you can use C# in godot as well. =)
What an amazing video
Thank you for this! Do you mind sharing how you would use this for Attack inputs? Unlike ground/air states which should be interrupted immediately based on whether we're on the ground, attacks should last the entire duration of the attack animation before resetting to another state. With the last modification you made in the video that Sets state on every Update() based on some logic, the state machine no longer relies on state.IsComplete so I'm not sure how to incorporate this behaviour of waiting for the state to finish. Any advice would be appreciated. Thank you!
This would be dependent on how much control you want to have. In Insignia, I have properties that live on the player called "canMove" and "canAttack", which I check before cancelling into states. It's then the responsibility of the action states to set these to true. A better approach could be to have these booleans as a property of the states themselves, and so you'd be checking if the current "state.canMove" is true before branching into any kind of movement interruption, etc.
It would be really game-dependent, as there are even different conditions for different kinds of attacks in my game. e.g. Air attacks are interrupted when landing, while ground attacks are interrupted when falling.
What did you use to make the flow chart? It is so clean!
Hey Adam, I hope everything is good. I was fascinated with the helper function used in the video. It got me intrigued that you used math to solve the animation problem. So, it got me thinking, what do you recommend for learning math for game development. Are there any resources that you recommend, or I should go back and study math from the beginning?
I would encourage you to be project oriented in your learning. If the project you're making needs specific math, you'll encounter it while trying to solve the associated challenges. Otherwise you'll just be learning for learning's sake (nothing wrong with that, either!)
Great video. Thank you so much!
Everybody gets this wrong, the states are not finite. That doesn't mean anything. The machine is finite, or in other words there is a FINITE NUMBER of states.
hey adam, do you know of a way to have a game do attack animations with different weapon models without copy and pasting the animation and changing every frame?
how can i make something like a attack or dash behavior? I can't get it. I made it in my own way, with spaghetti code, but i can't understand how to make the thing i created work within system in the video.
What colour pallet do you use plz give me the link 😢😢😢
If I want to add attack and attack animation in the first method how do I approach?
Hi Adam, I really like your videos, they teach me a lot, but I'm having a hard time understanding the running animation for a 64 pixel hero, I know you already have a running tutorial, but the hero there is 32 pixels, ideally I would like to see a tutorial on creating Armin's run from Insignia if possible, or a running tutorial for a 64 pixel hero, thanks for your attention.
is there a reason you made each state a script that was attached to a game object and not just a static class that any object can reference or say a scriptable object system? Seems like more work making each state a sub game object.
They are components primarily to allow for instance data to be set in the inspector, at the game object level.
A static class would not allow for this, and scriptable objects are designed as data objects, not really intended for runtime logic.
@@AdamCYounis I mainly meant to hold the data for what the state does and have a script that swaps between the states and takes the data from a different source than having say 200 sub game objects holding 200 scripts under the player in the hierarchy which seems less performant to me. So A manager script that references the Data for each state. Since states aren't changing the data on the fly then why would it need to be modified at runtime?
@@St4rQu3st Yep, that's the better way to do it.
Who is Neil and why do we want to add him as a state?
Note that if you have knowledge of UI toolkit, making a simple node based UI for the selected state machine would be a big plus performance wise for more complex entities.
Using monobehaviour over pure class does have a slight computational drawback, and it pollutes the entity's hierarchy with, not only the components themselves, but also with unused transforms. Imagine having 50 states for a complex boss, all packed up in the prefab of that boss 😱.
Also, although I guess it's going to be talked about in the next video, using a state machine controller can help decouple a lot of the boiler plate code for handling the switching of states. Otherwise, the state machine usually ends up being an ugly spaghetti code blob, switching from one state to the next with ifs and elses.
Last thing: note that using Unity's "animator" state machine is perfectly fine for any state machine if your game can handle the, again, computational drawback from the parts of the system you don't use (like blended, as specified in the video). With a bit of work, you can make a pretty generic and solid StateMachineBehaviour.cs based system.
Interesting, i have made my own state machine system from scratch, i have made videos about how i did it, it's generic so you can use it for multi different NPCs and not designed for only one object
Love this it's so helpful
LOOK OUT! THAT FERRET'S GOT A KNIFE!
Thanks for the video!
StateTree Tutorial!? :O
Man, i still don't get your approach to state machines. I think where I struggle is how the code executes, particularly the do, enter, fixedDo etc take place. Been trying to understand this for months. Maybe it's just one of those things im never going to get.
24:38 - The update function of the "state machine" class (PlayerMovement for the sake of this tutorial) calls state.Do(), as well as SelectState() which handles Enter() and Exit().
@@AdamCYounis I have no idea what state Do, enter or exit actually do. I understand them conceptually; do, enter, exit something. I just really struggle with how they run logically; how they run line by line. The state object is, i believe, just a framework you can use over and over, and code within it can be trailered for things common across states etc. I just struggle how they are interpreted by Unity and order of code execution. This probably sounds complete jibbirish but I'm not used to creating objects in programming, and how to use them. im more of a functional programmer, and used to keeping things on one page.
@@cyberblitzTBH I'm not super familiar with Unity or with Adam's exact system, but maybe that'll help me explain this stuff to you in a more agnostic programming perspective.
Basically, every frame, Unity calls Update() on all the active game objects
Objects with a state machine will now call state.Do() and SelectState(), because that's what they were told to do in their Update() function.
state.Do() is just a function, the same as functions in the paradigm you already know. It's going to do something. Maybe it tells the enemy AI to approach the player, as an example. Maybe it spits out "Hello, World." It doesn't matter. It is just running the specific lines of code written under "state.Do()" for the state that was assigned to this game object.
SelectState() changes which State the game object is in, according to its current situation. This is just simple IF statements. If you're in the air, you're in the aerial state. If you're attacking, you're in an attack state, etc. It figures out which state the object should be in, and puts it in that state. Then, in future Update()'s (that are happening all the time as the game is running), the behavior will change according to the new state.
On the line level, it's just something like this:
Update() -> the line of codes under "Update()" run, calling the "state.Do()" function
state.Do() -> the lines of code under state.Do() run, they come from the specific "state" we assigned to our character earlier.
Update()-> now that state.Do() finished, Update() continues to its next line of code, which is calling SelectState()
SelectState() -> the lines of code under "SelectState()" run.
You're using a tree to display a state machine that's so confusing. why not using state machine nomenclature?
Because my state machine data structures are hierarchical, they are literally trees.
@@AdamCYounis I think it's a valid point. You showed a tree structure at the beginning which was confusing, because state machine you shown later, in this particular video, is not hierarchical. It's state A to State B to State C to State A, basically.
@@AdamCYounis On that note, is your behavior tree actually connected to any code/logic or is it just a visual guide?
Your implementation in Insignia is closer to a behavior tree than a state machine, technically speaking. LlamAcademy has a few videos on how those two differ from each other.
So, is your behavior tree connected to any logic? (i.e. the one in the graph view. And did you code the graph view yourself?)
@@captainawesome2226 I coded the graph view myself. It's "connected" in that it visualises the current state, and I can force the character into a state by clicking it. But the graph is designed primarily to reflect the structure inherent in the code, it's a generated visualisation for debug purposes.
this video is goated
wonderful!
Awesome tutorial i REALLLY wish it was in godot though. I thought you switched to godot?
"switch" implies that you have to pick one or the other. My long term game is a Unity game and can't be ported to another engine. For smaller games I produce for jams, Godot is an engine I've begun to use, but it's far from a replacement for Unity at this stage.
Hey Pal
👍
4 the algorithm
😎👌🤔❤
too bad this isn't a godot tutorial :(
с этой стейт машиной один геморой, проще скрипты включать и выключать
Ew Unity
Where did you set isComplete =false in component state machine
I write all the code as yours but do function and the if statement with isComplete in update did not work 😢
isComplete belongs to the State class, and I set it false in an Initialise() function from 31:55
Thank you