derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
679 stars 33 forks source link

Give parameters to a state #85

Closed marcofriedmann closed 4 months ago

marcofriedmann commented 4 months ago

Is there a way to give parameters to a state? For example give the amount of degrees to a rotate state? What would be a good practice?

derkork commented 4 months ago

In general I think there is nothing special that would need to be done here. E.g. if you want to rotate to a certain angle while being in a state you could do it with a state_entered callback and a normal _process function, something like this:

# constants for what the angle should be in normal and rotated state
const TARGET_ROTATION_ROTATED_DEGREES = 90
const TARGET_ROTATION_NORMAL_DEGREES = 0
# rotation speed in degrees per second
const ROTATION_SPEED = 45

# the current target rotation
var _target_rotation_degrees:float = 0

# This runs in all states
func _process(delta:float):
   # correct our rotation such that we eventually reach target rotation
   rotation_degrees = move_toward(rotation_degrees, _target_rotation, delta * ROTATION_SPEED)

# called when entering normal state
func _on_normal_state_entered():
   _target_rotation_degrees = TARGET_ROTATION_NORMAL_DEGREES 

# called when entering rotated state
func _on_rotated_state_entered():
   _target_rotation_degrees = TARGET_ROTATION_ROTATED_DEGREES 

If you can give me some more information about your use case, I might be able to give a bit more targeted advice. Hope this helps in any case.

marcofriedmann commented 4 months ago

I would like to set the target rotation from outside of the state. For example as property in the transition node

derkork commented 4 months ago

You could use the transition's taken signal to react and set a certain property when a specific transition is taken, if that is what you want to do. Also all nodes have a metadata dictionary to which you can put arbitrary metadata which can be used when reacting on the transition, e.g.:

image

func _ready():
    %SomeTransition.taken.connect(_on_transition_taken.bind(%SomeTransition))
    %SomeOtherTransition.taken.connect(_on_transition_taken.bind(%SomeOtherTransition))

func _on_transition_taken(which:Transition):
   var rotation = which.get_meta("rotation", 0)
   # do something with rotation here..