Godot状态机实例

Image

一、 StateMachine

extends Node
class_name StateMachine

@export var initial_state : NodePath
@export var auto_start = true

var current_state : StateBase = null

@onready var states = get_children()
func _ready() -> void:
	if auto_start:
		launch()


func launch():
		assert(initial_state != null,"错误")
		current_state = get_node(initial_state)
		current_state.enter()


func _physics_process(delta: float) -> void:
	current_state.physics_update(delta)


func _process(delta: float) -> void:
	current_state.update(delta)


func has_state(state_name):
	for s in states:
		if "state_name" in s and s.state_name == state_name:
			return true
	return false


func get_state(state_name):
	for s in states:
		if "state_name" in s and s.state_name == state_name:
			return s
	return null


func transition_to(state_name : String,msg : Dictionary = {}):
	if has_state(state_name):
		var state = get_state(state_name)
		if state:
			current_state = state
			current_state.enter(msg)

二、 StateBase

extends Node
class_name StateBase
var state_name = "StateBase"
func enter(_msg : Dictionary = {}):
	pass
	
func exit():
	pass
	
func update(_delta : float):
	pass

func physics_update(_delta : float):
	pass

三、player脚本

extends CharacterBody2D
class_name Player
@export var player : Player
var current_direction = "down"

四、角色空闲脚本

extends StateBase
@export var player: Player
@export var animatedsprite2d: AnimatedSprite2D
@export var statemachine: StateMachine
func _ready():
	state_name = "idle"
		
func enter(_msg : Dictionary = {}):
	pass
	
func update(_delta : float):
	animatedsprite2d.play(player.current_direction + "_idle")
	if Input.get_vector("left","right","up","down"):
		statemachine.transition_to("move")

func physics_update(_delta : float):
	pass
	
func exit():
	animatedsprite2d.stop()

五、角色移动脚本

extends StateBase
@export var player: Player
@export var animatedsprite2d: AnimatedSprite2D
@export var statemachine: StateMachine
@export var SPEED = 100
func _ready():
	state_name = "move"

func enter(_msg : Dictionary = {}):
	pass
	
func update(_delta : float):
	animatedsprite2d.play(player.current_direction + "_move")
	if !Input.get_vector("left","right","up","down"):
		statemachine.transition_to("idle")

func physics_update(_delta : float):
	var input = Input.get_vector("left", "right", "up", "down")
	if input != Vector2.ZERO:
		if abs(input.x) > abs(input.y):
			player.current_direction = "right" if input.x > 0 else "left"
		else:
			player.current_direction = "down" if input.y > 0 else "up"
		player.velocity = input.normalized() * SPEED
		player.move_and_slide()

func exit():
	animatedsprite2d.stop()

状态机能够很好的对角色的状态进行调整,使制作者能够迅速有效的制作多状态的角色。