{"id":114,"date":"2021-03-12T23:57:35","date_gmt":"2021-03-12T23:57:35","guid":{"rendered":"https:\/\/wshop.fi\/eng\/?p=114"},"modified":"2021-03-12T23:57:37","modified_gmt":"2021-03-12T23:57:37","slug":"coding-with-unity-state-machine-using-inheritance","status":"publish","type":"post","link":"https:\/\/wshop.fi\/eng\/coding-with-unity-state-machine-using-inheritance\/","title":{"rendered":"Coding With Unity State Machine Using Inheritance"},"content":{"rendered":"\n<p>In this post I want to show you how I like to go about creating a state machine. A state machine is usually used (or at least, I use it) for things like the game states (<em>pause, playing, gameover,ecc<\/em>) or <a href=\"https:\/\/medium.com\/@noahlandonpaige\/how-to-create-smarter-npcs-in-games-10e384295f35\">AI for NPCs<\/a>, like different enemy states (<em>patrolling, chasing, shooting&#8230;<\/em>).<\/p>\n\n\n\n<p>This is a fairly standard method and we can achieve the same thing using interfaces. If you want to know how you can use interfaces to do this, I suggest you to take a look at this tutorial&nbsp;found on the Unity official website.<\/p>\n\n\n\n<p>In this example I will show you some code of an hypothetical game controller which can run 3 states: playing, pause and gameover.<\/p>\n\n\n\n<p><strong>First thing, the <em>State<\/em>class:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">publicabstractclassState {\nprotectedstring stateName;\npublicabstractvoid OnStateEnter ();\npublicabstractvoid UpdateState ();\npublicabstractvoid OnStateExit ();\npublicstring getStateName()\n{\nreturn stateName;\n}\n}<\/pre>\n\n\n\n<p>The State class is an abstract class, which means we will not be able to create instances of it. This is because all the states we are going to write are going to be derived from this base class, which is only intended to be\u00a0used as\u00a0a parent and we will not need objects of its type.<\/p>\n\n\n\n<p>The <em>string<\/em>variable <em>stateName<\/em>is simply used to identify the state we are in in the console.<\/p>\n\n\n\n<p>The 3 main methods used are also abstract methods. This implies that the classes which derive from this class MUST implement the methods body, which, in more complex projects, will most definitely behave in different ways.<\/p>\n\n\n\n<p>Now that we have the base class ready, we can go on and write the 3 classes for our 3 states.<\/p>\n\n\n\n<p><strong>The pause state:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">publicclassGameController_PauseState : State {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameObject obj;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> public GameController_PauseState(GameObject g,string name)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; stateName = name;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; obj = g;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateEnter ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" enetered \" + stateName); <\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp;}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateExit()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" exited \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid UpdateState ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" is running \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">}<\/pre>\n\n\n\n<p><strong>The playing state:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">publicclassGameController_PlayingState : State {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/GameObject.html\"> GameObject<\/a> obj;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> public GameController_PlayingState(GameObject g,string name)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; stateName = name;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; obj = g;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateEnter ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" enetered \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp;}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateExit()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" exited \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid UpdateState ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" is running \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">}<\/pre>\n\n\n\n<p>The game over state:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">publicclassGameController_GameOverState : State {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameObject obj;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> public GameController_GameOverState(GameObject g,string name)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; stateName = name;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; obj = g;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateEnter ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" enetered \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid OnStateExit()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" exited \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicoverridevoid UpdateState ()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; Debug.Log (obj.name + \" is running \" + stateName);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">}<\/pre>\n\n\n\n<p>You will notice that these three classes very much look alike, and that is because for this simple example these three states don&#8217;t do much more than displaying the name of the state that is acutally running. In a real game development environment you will want these classes to perform specific actions: for example, in the<\/p>\n\n\n\n<p><em>OnStateEnter()<\/em><\/p>\n\n\n\n<p>of the<\/p>\n\n\n\n<p><em>GameController_PlayingState<\/em><\/p>\n\n\n\n<p>class you will want to enable all the movement and input detection, whereas in the<\/p>\n\n\n\n<p><em>GameController_GameOverState<\/em><\/p>\n\n\n\n<p>you will do the exact opposite.<\/p>\n\n\n\n<p>For each state I declared a <em><a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/GameObject.html\">GameObject<\/a><\/em> variable, which is a reference to the game object which all these states are going to be part of. In our case, a <em>GameController<\/em>object. I could have very well put that variable in the <em>State<\/em>class.<\/p>\n\n\n\n<p>The constructor is the same for each class, which simply gets passed the state name and the object reference.<\/p>\n\n\n\n<p>Then, the three abstract methods are overridden. It is important to use the <em>override<\/em> keyword, and that is because an abstract method is implicitly a virtual method. If you omit the <em>override<\/em> keyword the compiler will start screaming at you.<\/p>\n\n\n\n<p>Now the three state classes are written we can create the actual monobehaviour object script, which I called <em>GameController.<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">publicclassGameController : MonoBehaviour {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> State currentState = null;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_PauseState pauseState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_GameOverState gameoverState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_PlayingState playingState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> void Start () {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; pauseState = new GameController_PauseState(this.gameObject,\"Pause State\");<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; gameoverState = new GameController_GameOverState(this.gameObject,\"GameOver State\");<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; playingState = new GameController_PlayingState(this.gameObject,\"Playing State\");<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; setState (playingState);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp;} <\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> void Update () { <\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; currentState.UpdateState (); <\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp;}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> publicvoid setState(State newState)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; if(currentState!=null)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp;&nbsp; currentState.OnStateExit();<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; currentState = newState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; currentState.OnStateEnter ();<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_GameOverState getGameOverState()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; return gameoverState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_PauseState getPauseState()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; return pauseState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> GameController_PlayingState getPlayingState()<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> {<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; return playingState;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">}<\/pre>\n\n\n\n<p>Here we can see the beauty of inheritance and polymorphism.<\/p>\n\n\n\n<p>We create a <em>State<\/em>type variable and we set it to <em>null. <\/em>Remember, we cannot instanciate objects of type <em>State<\/em>, but we can create variables of that type.<\/p>\n\n\n\n<p>Then I create the 3 members of three different state types and, in the <em>Start()<\/em>method, I initialize them calling their respective constructor.<\/p>\n\n\n\n<p>Next, the <em>setState(&#8230;)<\/em>method: this method accepts a <em>State<\/em>type variable which represents the states we wish to transit to. In its body, we first ensure the current state variable is not null, which is definitely going to be when the game starts as it has only been initialized to <em>null.<\/em><\/p>\n\n\n\n<p>Otherwise, if we are transiting from another state, the <em>OnStateExit()<\/em>of that particular state will be called.<br>After that, we simply assign the new state to the current state variable and call the <em>OnStateEnter().<\/em><br>In the <em>Update()<\/em>, we simply call the <em>UpdateState() <\/em>method, which will run for which ever state object is contained in the <em>currentState<\/em> member.<\/p>\n\n\n\n<p>This method is of course a public method so it can be called by other game objects in order to change the game state: for example, imagine your player being killed by an enemy while in the playing state. At this point you want to switch to the <em>GameOver<\/em>state and display a game over screen. From the player script you can call <em>setState(&#8230;)<\/em> and pass it in its own variable <em>gameoverState <\/em>using the <em>getGameOverState()<\/em> method.<\/p>\n\n\n\n<p>This is a pretty decent and organized way to create a state machine, which can be used for different purposes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post I want to show you how I like to go about creating a state machine. A state machine is usually used (or at least, I use it) for things like the game states (pause, playing, gameover,ecc) or AI for NPCs, like different enemy states (patrolling, chasing, shooting&#8230;). This is a fairly standard [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":116,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,15,19],"tags":[],"class_list":{"0":"post-114","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-coding","8":"category-technologies","9":"category-wordpress"},"_links":{"self":[{"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/posts\/114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/comments?post=114"}],"version-history":[{"count":2,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/posts\/114\/revisions"}],"predecessor-version":[{"id":117,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/posts\/114\/revisions\/117"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/media\/116"}],"wp:attachment":[{"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/media?parent=114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/categories?post=114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wshop.fi\/eng\/wp-json\/wp\/v2\/tags?post=114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}