Deriving SyncedAnimationGraph from Node instead of Mixer for easier prototyping.
This commit is contained in:
parent
15bcc60da9
commit
9a9adfbfb4
@ -5,152 +5,76 @@
|
|||||||
void SyncedAnimationGraph::_bind_methods() {
|
void SyncedAnimationGraph::_bind_methods() {
|
||||||
print_line(vformat("binding methods"));
|
print_line(vformat("binding methods"));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_tree_root", "animation_node"), &SyncedAnimationGraph::set_root_animation_node);
|
ClassDB::bind_method(D_METHOD("set_animation_tree", "animation_tree"), &SyncedAnimationGraph::set_animation_tree);
|
||||||
ClassDB::bind_method(D_METHOD("get_tree_root"), &SyncedAnimationGraph::get_root_animation_node);
|
ClassDB::bind_method(D_METHOD("get_animation_tree"), &SyncedAnimationGraph::get_animation_tree);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_tree", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_tree", "get_animation_tree");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_animation_player", "path"), &SyncedAnimationGraph::set_animation_player);
|
ADD_SIGNAL(MethodInfo(SNAME("animation_tree_changed")));
|
||||||
ClassDB::bind_method(D_METHOD("get_animation_player"), &SyncedAnimationGraph::get_animation_player);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
|
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo(SNAME("animation_player_changed")));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncedAnimationGraph::_set_active(bool p_active) {
|
|
||||||
_set_process(p_active);
|
|
||||||
started = p_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncedAnimationGraph::_process_animation(double p_delta, bool p_update_only) {
|
|
||||||
print_line(vformat("updating blend tree! %f", p_delta));
|
|
||||||
if (!root_animation_node.is_valid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<AnimationNodeBlendTree> blend_tree = root_animation_node;
|
|
||||||
if (!blend_tree.is_valid()) {
|
|
||||||
print_line("Cannot process animation graph: root not AnimationNodeBlendTree");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalVector<StringName> node_names = blend_tree->get_node_list();
|
|
||||||
for (StringName node_name : node_names) {
|
|
||||||
print_line(vformat(" %s", node_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncedAnimationGraph::SyncedAnimationGraph() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncedAnimationGraph::_update_properties() const {
|
|
||||||
if (!properties_dirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties_dirty = false;
|
|
||||||
|
|
||||||
const_cast<SyncedAnimationGraph *>(this)->notify_property_list_changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncedAnimationGraph::set_root_animation_node(const Ref<AnimationRootNode> &p_animation_node) {
|
|
||||||
if (root_animation_node.is_valid()) {
|
|
||||||
root_animation_node->disconnect(SNAME("tree_changed"), callable_mp(this, &SyncedAnimationGraph::_tree_changed));
|
|
||||||
// root_animation_node->disconnect(SNAME("animation_node_renamed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_renamed));
|
|
||||||
// root_animation_node->disconnect(SNAME("animation_node_removed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_removed));
|
|
||||||
}
|
|
||||||
|
|
||||||
root_animation_node = p_animation_node;
|
|
||||||
|
|
||||||
if (root_animation_node.is_valid()) {
|
|
||||||
root_animation_node->connect(SNAME("tree_changed"), callable_mp(this, &SyncedAnimationGraph::_tree_changed));
|
|
||||||
// root_animation_node->connect(SNAME("animation_node_renamed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_renamed));
|
|
||||||
// root_animation_node->connect(SNAME("animation_node_removed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_removed));
|
|
||||||
}
|
|
||||||
|
|
||||||
properties_dirty = true;
|
|
||||||
|
|
||||||
update_configuration_warnings();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<AnimationRootNode> SyncedAnimationGraph::get_root_animation_node() const {
|
|
||||||
return root_animation_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncedAnimationGraph::_notification(int p_what) {
|
void SyncedAnimationGraph::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_READY: {
|
||||||
_setup_animation_player();
|
_set_process(true);
|
||||||
if (active) {
|
} break;
|
||||||
_set_process(true);
|
|
||||||
}
|
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||||
|
_process_animation(get_process_delta_time());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
_process_animation(get_physics_process_delta_time());
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncedAnimationGraph::_tree_changed() {
|
void SyncedAnimationGraph::set_animation_tree(const NodePath &p_path) {
|
||||||
if (properties_dirty) {
|
animation_tree = p_path;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callable_mp(this, &SyncedAnimationGraph::_update_properties).call_deferred();
|
|
||||||
properties_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncedAnimationGraph::set_animation_player(const NodePath &p_path) {
|
|
||||||
animation_player = p_path;
|
|
||||||
if (p_path.is_empty()) {
|
if (p_path.is_empty()) {
|
||||||
set_root_node(SceneStringName(path_pp));
|
// set_root_node(SceneStringName(path_pp));
|
||||||
while (animation_libraries.size()) {
|
// while (animation_libraries.size()) {
|
||||||
remove_animation_library(animation_libraries[0].name);
|
// remove_animation_library(animation_libraries[0].name);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
emit_signal(SNAME("animation_player_changed")); // Needs to unpin AnimationPlayerEditor.
|
emit_signal(SNAME("animation_tree_changed")); // Needs to unpin AnimationPlayerEditor.
|
||||||
_setup_animation_player();
|
|
||||||
notify_property_list_changed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodePath SyncedAnimationGraph::get_animation_player() const {
|
NodePath SyncedAnimationGraph::get_animation_tree() const {
|
||||||
return animation_player;
|
return animation_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncedAnimationGraph::_setup_animation_player() {
|
void SyncedAnimationGraph::_ready(const NodePath &p_path) {
|
||||||
if (!is_inside_tree()) {
|
print_line(vformat("synced animation graph ready!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyncedAnimationGraph::_process_animation(double p_delta, bool p_update_only) {
|
||||||
|
print_line(vformat("updating blend tree! %f", p_delta));
|
||||||
|
// if (!root_animation_node.is_valid()) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Ref<AnimationNodeBlendTree> blend_tree = root_animation_node;
|
||||||
|
// if (!blend_tree.is_valid()) {
|
||||||
|
// print_line("Cannot process animation graph: root not AnimationNodeBlendTree");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// LocalVector<StringName> node_names = blend_tree->get_node_list();
|
||||||
|
// for (StringName node_name : node_names) {
|
||||||
|
// print_line(vformat(" %s", node_name));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyncedAnimationGraph::_set_process(bool p_process, bool p_force) {
|
||||||
|
if (processing == p_process && !p_force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_valid = false;
|
set_physics_process_internal(false);
|
||||||
|
set_process_internal(true);
|
||||||
|
|
||||||
if (animation_player.is_empty()) {
|
processing = p_process;
|
||||||
clear_caches();
|
}
|
||||||
return;
|
|
||||||
}
|
SyncedAnimationGraph::SyncedAnimationGraph() {
|
||||||
|
|
||||||
// Using AnimationPlayer here is for compatibility. Changing to AnimationMixer needs extra work like error handling.
|
|
||||||
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node_or_null(animation_player));
|
|
||||||
if (player) {
|
|
||||||
if (!player->is_connected(SNAME("caches_cleared"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player))) {
|
|
||||||
player->connect(SNAME("caches_cleared"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player), CONNECT_DEFERRED);
|
|
||||||
}
|
|
||||||
if (!player->is_connected(SNAME("animation_list_changed"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player))) {
|
|
||||||
player->connect(SNAME("animation_list_changed"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player), CONNECT_DEFERRED);
|
|
||||||
}
|
|
||||||
Node *root = player->get_node_or_null(player->get_root_node());
|
|
||||||
if (root) {
|
|
||||||
set_root_node(get_path_to(root, true));
|
|
||||||
}
|
|
||||||
while (animation_libraries.size()) {
|
|
||||||
remove_animation_library(animation_libraries[0].name);
|
|
||||||
}
|
|
||||||
List<StringName> list;
|
|
||||||
player->get_animation_library_list(&list);
|
|
||||||
for (const StringName &E : list) {
|
|
||||||
Ref<AnimationLibrary> lib = player->get_animation_library(E);
|
|
||||||
if (lib.is_valid()) {
|
|
||||||
add_animation_library(E, lib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_caches();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,41 +3,26 @@
|
|||||||
#include "scene/animation/animation_blend_tree.h"
|
#include "scene/animation/animation_blend_tree.h"
|
||||||
#include "scene/animation/animation_tree.h"
|
#include "scene/animation/animation_tree.h"
|
||||||
|
|
||||||
class SyncedAnimationGraph : public AnimationMixer {
|
class SyncedAnimationGraph : public Node {
|
||||||
GDCLASS(SyncedAnimationGraph, AnimationMixer);
|
GDCLASS(SyncedAnimationGraph, Node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool started = true;
|
NodePath animation_tree;
|
||||||
|
bool processing = false;
|
||||||
|
|
||||||
friend class AnimationNode;
|
void set_animation_tree(const NodePath &p_path);
|
||||||
|
NodePath get_animation_tree() const;
|
||||||
Ref<AnimationRootNode> root_animation_node;
|
|
||||||
|
|
||||||
mutable bool properties_dirty = true;
|
|
||||||
|
|
||||||
void _update_properties() const;
|
|
||||||
|
|
||||||
NodePath animation_player;
|
|
||||||
void set_animation_player(const NodePath &p_path);
|
|
||||||
NodePath get_animation_player() const;
|
|
||||||
|
|
||||||
void set_root_animation_node(const Ref<AnimationRootNode> &p_animation_node);
|
|
||||||
Ref<AnimationRootNode> get_root_animation_node() const;
|
|
||||||
|
|
||||||
void _tree_changed();
|
|
||||||
|
|
||||||
void _setup_animation_player();
|
|
||||||
void _animation_player_changed();
|
|
||||||
|
|
||||||
void _notification(int p_what);
|
|
||||||
|
|
||||||
virtual void _set_active(bool p_active) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void _process_animation(double p_delta, bool p_update_only = false) override;
|
void _ready(const NodePath &p_path);
|
||||||
|
void _process_animation(double p_delta, bool p_update_only = false);
|
||||||
|
|
||||||
SyncedAnimationGraph();
|
SyncedAnimationGraph();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _set_process(bool p_process, bool p_force = false);
|
||||||
};
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user