derkork / godot-statecharts

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

C# StateChart wrapper not exposing inherited functions (like CallDeferred) #101

Closed bitegw closed 3 months ago

bitegw commented 3 months ago

I ran into an issue where I tried to set an expression in _Ready when the StateChart wasn't initialized, this gave me an error that told me to use call_deferred to set the expression instead, but StateChart does not expose it. A workaround is to call it on the (not yet converted to StateChart) Node, but the called function is a StateChart function so I find it a little weird to have to do this.

Also some suggestions: 1) I'm not sure if it's just my usecases, but I find I really often want to keep track of how long I've been in a state, or how long it's been since I left a state. It's a pain to manage this for every state so it would be good if states kept track of this automatically. These values could be used in code to control animation transitions, or to populate cooldown values in UI elements. 2) This might be something I missed but is there any way to get the active state (maybe entire state path) and check it? This also seems like a useful feature, but maybe I'm just misusing the state chart by doing this.

derkork commented 3 months ago

I have added a wrapper for CallDeferred and also a a MethodName class holding the proper method names of the StateChart class in GDScript land, so it's also safe to use from C# without having to type any strings.

Regarding the other two things:

  1. There is an example showing cooldowns for UI elements. The approach used there is to enter a cooldown state once you have executed an action that requires a cooldown. Once this cooldown state enters a delayed transition runs until the end of the cooldown. While this transition is pending, the transition_pending signal is emitted which contains original transition time and remaining transition time and can be used to drive an UI element. Would that work for your use case?
  2. The nature of a state chart is that more than one state can be simultaneously active. For example if you look at the platformer, we have 6 states being active at any given time, so there is no one "active state": image The recommended approach if you need to know whether a certain state is currently active, is to get a reference to that state and check its Active property, e.g.:
StateChartState _some_state;

void _Ready() {
     _some_state = StateChartState.Of(GetNode<Node>("%Airborne")); // using a scene unique name here
}

void SomeMethod() {
   if (_some_state.Active) {
      // do things.. 
   }
}