Code Monkey home page Code Monkey logo

godot-finite-state-machine's Introduction

godot-finite-state-machine

Godot FSM (Finite State Machine)

This is a second FSM for Godot that is purely code-only (no editor plugin).

Examples

Configuration-based Setup

This first example is the "best" way to create an FSM instance, by passing a configuration dictionary to the StateMachineFactory.create() method.

Notice the states property is an array of dictionaries, and we pass IdleState and PatrolState. The state machine handles creating new instances of the states via this method.

const StateMachineFactory = preload("res://addons/fsm/StateMachineFactory.gd")
const IdleState = preload("IdleState.gd")
const PatrolState = preload("PatrolState.gd")

# Create new state machine factory
var smf = StateMachineFactory.new()

# Create state machine using a configuration dictionary
var sm = smf.create({
  "target": $Enemy,
  "current_state": "patrol",
  "states": [
    {"id": "idle", "state": IdleState},
    {"id": "patrol", "state": PatrolState}
  ],
  "transitions": [
    {"state_id": "idle", "to_states": ["patrol"]},
    {"state_id": "patrol", "to_states": ["idle"]}
  ]
})

Manual Setup

This method shows how to manually create and setup a FSM object.

const StateMachineFactory = preload("res://addons/fsm/StateMachineFactory.gd")
const IdleState = preload("IdleState.gd")
const PatrolState = preload("PatrolState.gd")

# Create state manually
var smf = StateMachineFactory.new()
var sm = smf.create()

# Create states
var idle_state = IdleState.new()
var patrol_state = PatrolState.new()

# Add the id, state machine, and target to the states (also handled by the state machine, just shown for completeness)
idle_state.id = "idle"
idle_state.state_machine = sm
idle_state.target = $Enemy

patrol_state.id = "patrol"
patrol_state.state_machine = sm
patrol_state.target = $Enemy

# Convenience method to set state machine on array of states
sm.set_state_machine([idle_state, patrol_state])

# Add state to state machine, which also adds the state machine to the state
sm.add_state("idle", idle_state)
sm.add_state("patrol", patrol_state)

# Set states method which accepts the same array of state dictionaries as the create factory method
sm.set_states([
  {"id": "idle", "state": IdleState},
  {"id": "patrol", "state": PatrolState}
])

# Add transitions. Must be done after adding states, as the state ids are validated
sm.add_transition("idle", ["patrol"])
sm.add_transition("patrol", ["idle"])

# Set transitions method which accepts the same array of transition dictionaries as the create factory method
sm.set_transitions([
  {"state_id": "idle", "to_states": ["patrol"]},
  {"state_id": "patrol", "to_states": ["idle"]}
])

# Add a single transition
sm.add_transition("idle", "patrol")
sm.add_transition("patrol", "idle")

# Add the target node/object to the state machine
sm.set_target(get_tree().get_root().get_node("enemy"))

# Set the initial state of the state machine
sm.set_current_state("patrol")

State Machine

State Machine Target

# Set the state machine's target (recursively sets on states)
sm.set_target($Player)
sm.target = $Player

# Get state machine's target object
var player = sm.target

State Machine Current State

# Set the state machine's current state. This really should be called internally by the state machine only.
sm.set_current_state("patrol")
sm.current_state = "patrol"

# Get the state machine's current state
var state = sm.get_state(sm.current_state)

State Machine Transition

The transition method of the state machine will validate that the id passed is a valid state. It will call the current state's _on_leave_state callback if implemented. It will then call the to state's _on_enter_state method.

# Transition to new state
sm.transition("patrol")

State Machine Callbacks

The state manager exposes callback methods for _process(delta), _physics_process(delta), and _input(event). Calls to these methods are proxied down to the current state's method if it has implemented them.

# State machine callbacks which are proxied down to the current state object
sm._physics_process(delta)
sm._process(delta)
sm._input(event)

State

State ID

Each state stores its own ID.

var smf = StateMachineFactory.new()
var sm = smf.create()

var state = IdleState.new()
state.sm = sm
state.id = "idle"

var state_id = state.id

State Target

The state and state machine have a target object, which is assumed to be where any extra required context is coded against.

var smf = StateMachineFactory.new()
var sm = smf.create()

var state = IdleState.new()
state.state_machine = sm
state.id = "idle"
state.target = $Player

var player = state.target

State Callbacks

A state class can implement callbacks for _process(delta), _physics_process(delta), _input(event), _on_enter_state(), and _on_leave_state().

extends "res://addons/fsm/StateMachine.gd".State

var memory = 0

func _init().():
	process_enabled = false
	input_enabled = false
	leave_state_enabled = false

func _physics_process(delta: float) -> void:
	scan_for_enemy(delta)
	move_to_random(delta)

func scan_for_enemy(delta: float) -> void:
  pass

func move_to_random(delta: float) -> void:
	# some logic to move to a random location
	...

	# Transition to idle state if we have reached our destination
	if arrived_at_location():
    state_machine.transition("idle")

func _on_enter_state() -> void:
  memory = 100

godot-finite-state-machine's People

Contributors

aaronfranke avatar brandonlamb avatar justin-calleja avatar justuspan avatar steelwalrus avatar tavurth 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.