This might be a good candidate for a blog post, but I will explain how I store variables at the moment. First off, I use a lot of coroutines. For example, this function does most of the work of attacking.
func _punch_think(delta):
$FlipMe/RunFX.emitting = false
$AnimationPlayer.play(_think_state.attack_anim)
while $AnimationPlayer.is_playing() or not is_on_floor():
vel.y = min(vel.y + grav * delta, -jump_speed)
if is_on_floor():
vel.x = sign(vel.x) * max(abs(vel.x) - walk_accel * 0.5 * delta, 0)
else:
vel.x = _calc_horizontal_navigation(delta, false)
vel = move_and_slide(vel, Vector2(0, -1))
delta = yield()
swap_think_to(Walk_State.new(self), delta)
So the first thing you notice is the answer to your question, where are the common variables stored. Common variables are just members of the script. State specific variables are just declared locally in the coroutine. For example, vel is a shared variable.
I have some local objects to help things out:
class Think_State:
#warning-ignore:unused_class_variable
var owner
var _think_func #function to call if no coroutine state
var _next_think = null #store coroutine state
# var _input_func #might be good in the future
func process(delta):
if _next_think:
_next_think = _next_think.resume(delta)
else:
_next_think = _think_func.call_func(delta)
func _cleanup():
pass
class Punch_State extends Think_State:
#warning-ignore:unused_class_variable
var str_repr = '[Punch_State %s]' % self
var attack_anim
func _init(owner, attack_anim):
self.owner = owner
self.attack_anim = attack_anim
self._think_func = funcref(owner, '_punch_think')
In this example, the constructor is over ridden to store a transition variable in attack_anim.
Then the other critical functions are my process and swap think functions:
func _physics_process(delta):
if cached_button_input:
cached_button_input['time'] -= delta
if cached_button_input['time'] < 0:
cached_button_input = {}
if not _think_state:
swap_think_to(Walk_State.new(self), delta)
_think_state.process(delta)
func swap_think_to(new_think_state, delta = 0):
if _think_state:
_think_state._cleanup()
_think_state = new_think_state
if delta > 0:
_think_state.process(delta)
Don't know if this helps....