Giter Club home page Giter Club logo

state-machine's Introduction

State Machine


State Machine is a library that enables developers to create AI or any state-based system.

State Machine includes:

  • A graphical tool used for managing and creating states and conditions within a state machine.
  • An API that allow developers to create a state machine of any Unity Component type.

* Available via the com.udomdev.statemachine package

About

This package is serves as a library to make state-based systems like AI, and dialogue systems.

Dependencies

This package requires the Unity UI Toolkit package to operate. Go to the package manager. On the top left corner, click on the plus or "+" icon, click on the "add package from git URL", type in com.unity.ui. Then install the package.

Installation

Go to the package manager. On the top left corner, click on the plus or "+" icon, click on the "add package from git URL", copy the git url address of this project and paste in it into the text field. Then install the package

State Machine components

A state machine is made up of 3 components:

  1. State: This represents a state or set of action within a system.
    (For example: fighting, searching and resting in RPGs)

  2. Condition: This represents a certain condition or a set of actions that must be completed to enter a state
    (For example: If an enemy see the player, the enemy procedes to pursue the player)

  3. Manager: This manages all the states and condition within the system.

How To Use

These are the major steps in order to use this package:

  1. Create a class for your State Manager
  2. Create a base class for your States (Optional)
  3. Create a base clase for your conditions (Optional)
  4. Create derived State classes
  5. Create derived Condition classes
  6. Create a state manager asset

Creating The Class for your State Manager

Create a class that derives from the generic StateManager class by

  • Using the namespace StateMachine
  • Deriving from the generic class StateManager<T> where T is a Unity Component type parameter
using System;
using System.Collections;
using System.Collections.Generic;
using StateMachine;
using UnityEngine;

[CreateAssetMenu(fileName = "State Machine/Transform Sample", menuName = "New Transform Sample")]
public class SampleTransformStateManager : StateManager<Transform>
{

    public override Type GetStateType()
    {
        return typeof(SampleTransformBaseState);
    }

    public override Type GetConditionType()
    {
        return typeof(SampleTransformBaseCondition);
    }
}

Creating The Base Class for your States

Create a abstract class from the generic State class by

  • Using the namespace StateMachine
  • Deriving from the generic class State<T> where T is a Unity Component type parameter
  • Make sure to use the same type parameter as above

(This is optional, but It is highly advised to do)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using StateMachine;

public abstract class SampleTransformBaseState : State<Transform>
{
    
}

Creating The Base Class for your Condition

Create an abstract class from the generic Condition class by

  • Using the namespace StateMachine
  • Deriving from the generic class Condition<T> where T is a Unity Component type parameter
  • Make sure to use the same type parameter as above
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using StateMachine;

public abstract class SampleTransformBaseCondition : Condition<Transform>
{ 
    
}

Create Derived State classes

Create State classes that derived from

  • The base State class created above or
  • The base generic State class of same type parameter(In this case "State<Transform>")
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveInCircles : SampleTransformBaseState
{
    public float length = 20;
    public List<Vector3> points;
    public int noOfPoints = 20;
    public float speed = 10;
    public int index;
    public bool rotatePoints;
    public float rotateAngularSpeed = 5;
    public override void OnEnd(Transform obj)
    {
        
    }

    public override void OnGizmos(Transform obj)
    {
        for(int i = 0; i < points.Count; i++)
        {
            var point = points[i];
            Gizmos.color = index == i ? Color.red : Color.green;
            Gizmos.DrawSphere(point, 0.5f);
            Gizmos.color = Color.white;
            Gizmos.DrawLine(point, points[(i + 1) % points.Count]);
        }

    }

    public override void OnStart(Transform obj)
    {
        points.Clear();
        index = 0;
        float radDiv = 360 / noOfPoints;
        Vector3 startPoint = new Vector3(-length/2, 0, 0);
        startPoint = Quaternion.Euler(0, 45f, 0) * startPoint;
        points.Add(startPoint);
        for(int i = 1; i < noOfPoints; i++)
        {
            Debug.Log(i - 1);
            points.Add(Quaternion.Euler(0, radDiv, 0) * points[i - 1]);
        }
      
    }

    public override void OnUpdate(Transform obj)
    {
        var dir = (points[index] - obj.transform.position).normalized;
        obj.transform.position += speed * Time.deltaTime * dir;
        obj.forward = Vector3.Lerp(obj.forward, dir, Time.deltaTime * 8f);
        if (Vector3.Distance(obj.transform.position, points[index]) < 1f)
        {
            index = ++index % points.Count;
        }

        if (rotatePoints)
        {
            for(int i = 0; i < points.Count; i++)
            {
                points[i] = Quaternion.Euler(0, rotateAngularSpeed * Time.deltaTime, 0) * points[i];
            }
        }
    }
}

Create Derived Condition classes

Create Condition classes that derived from

  • The base Condition class created above or
  • The base generic Condition class of same type parameter(In this case "Condition<Transform>")
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class SampleKeyCondition : SampleTransformBaseCondition
{
    float lastValue = 0;
    public bool useTimer = false;
    public KeyCode key;
    
    public override bool Check(Transform value)
    {
        if (useTimer)
        {
            var currentValue = (Time.time * 1000) % 10000;
            if (lastValue > currentValue)
            {
                lastValue = currentValue;
                return true;
            }
            Debug.Log(currentValue + " " + lastValue);
            lastValue = currentValue;
        }
       
        return Input.GetKeyDown(key);
        
        
    }
}

Create the asset

Create the scriptable object asset of the State Manager derived class.

Asset Selection

  • Double click on it to open the graph to use.

Graph Creation

  • Create a state node

State Creation

  • Create a condition node

Condition Creation

  • Make your connections

Graph Selection

Enjoy!!

state-machine's People

Contributors

udyohan avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.