Skip to content

Instantly share code, notes, and snippets.

@fire
Forked from Xrayez/StateRecorder.gd
Created February 14, 2020 06:55
Show Gist options
  • Save fire/078a2c4a558fdd3e48febe0a61f06ac2 to your computer and use it in GitHub Desktop.
Save fire/078a2c4a558fdd3e48febe0a61f06ac2 to your computer and use it in GitHub Desktop.
State recorder using AnimationPlayer in Godot
# This is a prototype of the state recorder that can be used in a replay system
extends AnimationPlayer
var nodes = []
var animations = {}
var properties = ["global_position", "global_rotation"]
func _init():
set_name("state_recorder")
func _ready():
# Fetch all nodes recursively inside the scene except for StateRecorder
# StateRecorder will record all nodes' properties of its parent
var to_visit = []
for node in get_parent().get_children():
to_visit.push_back(node)
nodes.push_back(node)
nodes.erase(self)
while not to_visit.empty():
var current = to_visit.pop_back()
for node in current.get_children():
to_visit.push_back(node)
nodes.push_back(node)
# Add properties to be recorded
for node in nodes:
if node is Node2D:
# Alas, can't play back multiple animations at once, but nonetheless ...
var animation = Animation.new()
# animation.set_step(get_physics_process_delta_time())
for idx in properties.size():
var property = properties[idx]
animation.add_track(Animation.TYPE_VALUE)
var node_name = str(get_parent().get_path_to(node))
animation.track_set_path(idx, node_name + ":" + property)
animations[node] = animation
add_animation(node_name.replacen('/','.'), animation)
func _physics_process(delta):
# Record states
var frame = get_tree().get_frame()
# Uncomment to record every second instead of every frame
# if frame % 60 == 0:
for node in nodes:
if node is Node2D:
for idx in properties.size():
var property = properties[idx]
var animation = animations[node]
animation.track_insert_key(idx, frame * delta, node.get(property))
func _notification(what):
# Save replay upon exit
match what:
MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
var dir = Directory.new()
dir.make_dir("res://replay")
var ps = PackedScene.new()
ps.pack(self)
ResourceSaver.save("res://replay/replay.tscn", ps, ResourceSaver.FLAG_COMPRESS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment