---
description: Steps to create a new state by code. ... Finishing up
---

# Creating a new State

## Overview

To create a new state from scratch you need to create a script that inherits from the State class

{% embed url="https://streamable.com/bxws0m" %}

* This class needs to be on the **`MalbersAnimations.Controller`** namespace
* Implement the StateName Property. This Holds the Menu Display name when you add a new State on the Animal Controller.&#x20;

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2F3R4tk7UPaXASkVjD4zTv%2Fimage.png?alt=media&#x26;token=65d2c30f-2537-4dee-9d91-734ec666abf9" alt=""><figcaption></figcaption></figure>

Once you create the new script you will need to create a new State ID to Identify your new State. On your project window. Use the Create menu to add a new state:

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FmnP5J67k1y8j4A8vuLeH%2Fimage.png?alt=media&#x26;token=eed6fbf5-1224-4112-908b-da07ae57dd36" alt=""><figcaption></figcaption></figure>

Or you can simply duplicate any StateID already created, rename it, and change the ID value:

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FVx9AeUL4auM99CslcvzD%2FUnity_nuAs83Ee49.gif?alt=media&#x26;token=55687482-45b6-42e7-a209-9dea44c20121" alt=""><figcaption></figcaption></figure>

## Example State

```csharp
using UnityEngine;

namespace MalbersAnimations.Controller
{
     
    [CreateAssetMenu(menuName = "Malbers Animations/TemplateState", fileName = "TemplateState", order = 4000)]
    public class TemplateState : State
    {
        // Define state name and ID
        public override string StateName => "TemplateState";
        public override string StateIDName => "TemplateState";

        // Internal variables
        private bool yourChecker; // Check if a condition is met
        private int exitStatusNumber; // Track exit status


        // Method called when state transition is triggered by input
        public override void StatebyInput()
        {
            yourChecker = false; // Reset checker
            if (InputValue) // Check for input condition
            {
                Activate(); // Activate the state
            }
        }

        // This method is like use for automatic states, or states that require external conditions for Activation
        // If this method returns true, the New State will be activated.
        // For example, in the Fall State, I use this method to cast the Pink Ray to find the ground beneath the animal.
        // If I don't find the ground or I find a slope too deep, I return true and the state will be activated.
        // Not all states need to implement this method. States like Fly and Death can be activated by Player Input or by calling directly the Activate() method.
        public override bool TryActivate()
        {
            return yourChecker;
        }



        // Method called right after the TryActivate(), or if an Input activated the State
        // or by simply calling State_Activate(int ID) on the Animal.
        // Here all the Animator Parameters are updated.
        // That way, in the next frame, the animations are properly executed.
        // In this method, it is mandatory to keep the base.Activate(); reference.
        public override void Activate()
        {// Start function

            CheckFunction(); // Check condition
            if (yourChecker) // If condition is met
            {
                base.Activate(); // Mandatory call
               // Additional logic for updating animator parameters
            }
        }

        // Method called when entering core animation. The core animation must have the Core Tag in the Animator Controller
        public override void EnterCoreAnimation()
        {
            // This method is called when the first frame of the Core animation of the state is played.
            // E.g. when the glide state Animation with the "Glide" tag plays.
            // Example: This method could be used to initialize specific actions when entering core animation.
        }

        // Method called when entering animation tagged with specific tags
        public override void EnterTagAnimation()
        {
            // This method is called every time the state enters any Animation Tagged.
            // E.g. Locomotion has custom tags like 'Land', 'StartLocomotion', 'Locomotion'.
            // This method is called every time a new Custom Tag is playing.
        }

        // Custom check function. Some States require external verifications and conditions to be activated.
        //E.g. The Climb State requires a Wall with an Specific Layer and a Collider
        //A raycast will be cast to verify is a wall in front of the characcter is valid to be climbed
        private void CheckFunction()
        {
            yourChecker = true; // Set checker to true
        }

        // State logic update method.
        // This method handles all the state-specific logic. It's where you implement custom movements and behaviors for the state.
        // E.g. the Fall State, it manages air control to move the character and applies gravitational forces.
        // Example: ApplyGravity(); ApplyAirControl();
        public override void OnStateMove(float deltaTime)
        {
            if (InCoreAnimation)
            {
                // Core update functions

                AllowExit();
            }
        }


        // Method called when state exit is triggered by input
        public override void StateExitByInput()
        {
            // Example: SetExitStatus(exitStatusNumber);
        }

        // Reset state-specific variables
        public override void ResetStateValues()
        {
            // Here, you need to restore all the internal variables of your state,
            // so the next time is activated again, all the local variables are clean/reset.
            // Example: Reset all your state-specific variables
        }

        // Restore animal variables upon state exit
        public override void RestoreAnimalOnExit()
        {
            // Here, you need to restore the animal variables you changed only for this state.
            // Example: Reset all animal variables
        }
    }
}

```

## Methods and Properties

To Create a new custom state you will need to implement some of the methods used to Activate, try to activate, move the Animal while is in the state, and Exit the state.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FIMUBPyFm5mq4T7ZRbIDj%2Fimage.png?alt=media&#x26;token=171be20c-1957-491e-8e4f-4609b76f2185" alt=""><figcaption></figcaption></figure>

### bool TryActivate()

This method is like the Automatic Method Activation for the states... If this method returns true... the New State will be activated. For example, in the Fall State, I use this method to cast the Pink Ray, to find the ground beneath the animal... if I don't find the ground or I find a slope too deep I return true and the state will be activated.&#x20;

Not all states need to implement this method. States like **Fly** and **Death** can be activated by Player Input or by calling directly the Activate() method.



### void Activate()&#x20;

This method is called right after the TryActivate(), or if an Input activated the State. or by simply calling State\_Activate(int ID) on the Animal.

&#x20;Here all the Animator Parameters are updated. That way, in the next frame, the animations are properly executed.

In this method, is mandatory to keep the **`base.Activate();`** reference.&#x20;

This is an example of the Fall State:

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2F8Fn3LLRonWHEoM0vD7wo%2Fimage.png?alt=media&#x26;token=48f07b4b-ae36-429f-b35f-a1a65ae3b802" alt=""><figcaption><p>Always add &#x3C;base.> logic on methods that have code in the parent State class.</p></figcaption></figure>

### **void EnterCoreAnimation()**&#x20;

This method is called when the first frame of the Core animation of the state is played. E.g. when the glide state Animation with the "Glide" tag plays

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FG6L6tAxVVICuhyxBFLEY%2Funknown.png?alt=media&#x26;token=c4f932b6-a9f5-4cb8-a20b-77506d5feb26" alt=""><figcaption></figcaption></figure>

This method does not require you the use of \<base.> logic on methods.



### void EnterTagAnimation()

This method is called everytime the state enters any Animation Tagged.&#x20;

E.g. Lomotion has custom tags like Land, StartLocomotion, Locomotion. This method is called every time a new Custom Tag is playing



### **void OnStateMove(float** DeltaTim&#x65;**)**&#x20;

This is the Update of the State... all the logic of the state is here. All the state custom movement you want to do, it is done here.

E.g. the Fall State adds Air Control to move the character and applies gravity.



### void TryExitState(float DeltaTime)

The logic for exiting the state is here. Add all the conditions you need to allow your state to exit.

if the State allows conditions are true. Call the AllowExit() method.

E.g. on the Glide and Fall State; if the character is near the ground, I call  AllowExit() here... which will allow other states to try to activate themselves.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2Fj4QVfkP35f5OZbBTyLuK%2Fimage.png?alt=media&#x26;token=4b9f72b9-79b8-41d7-bdcc-aa267cb95c5c" alt=""><figcaption><p>Glide TryExit method</p></figcaption></figure>

### **void ResetStateValues()**&#x20;

In this method you need to restore all the internal variables of your state.... so the next time is activated again ...all the local variables are clean/reset.

### **void RestoreAnimalOnExit()**

Here... you need to restore the animal variables you changed only for this state... (E.g. With Glide, I enable the Animal AlwaysForward parameter and I disable it when Glide is finished)

















...KEEP.. Going 😅😫
