-
-
Save fire/078a2c4a558fdd3e48febe0a61f06ac2 to your computer and use it in GitHub Desktop.
State recorder using AnimationPlayer in Godot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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