summaryrefslogtreecommitdiff
path: root/scene/animation/animation_node_state_machine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_node_state_machine.cpp')
-rw-r--r--scene/animation/animation_node_state_machine.cpp111
1 files changed, 57 insertions, 54 deletions
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 17ce05f130..81ecb50ea0 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ void AnimationNodeStateMachineTransition::set_advance_condition(const StringName
} else {
advance_condition_name = StringName();
}
- emit_signal("advance_condition_changed");
+ emit_signal(SNAME("advance_condition_changed"));
}
StringName AnimationNodeStateMachineTransition::get_advance_condition() const {
@@ -115,7 +115,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_priority", "priority"), &AnimationNodeStateMachineTransition::set_priority);
ClassDB::bind_method(D_METHOD("get_priority"), &AnimationNodeStateMachineTransition::get_priority);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,At End"), "set_switch_mode", "get_switch_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time");
@@ -130,11 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
}
AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
- switch_mode = SWITCH_MODE_IMMEDIATE;
- auto_advance = false;
- xfade = 0;
- disabled = false;
- priority = 1;
}
////////////////////////////////////////////////////////
@@ -286,12 +281,12 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
at = cost_map[at].prev;
}
- path.invert();
+ path.reverse();
return true;
}
-float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek) {
+double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek) {
//if not playing and it can restart, then restart
if (!playing && start_request == StringName()) {
if (!stop_request && p_state_machine->start_node) {
@@ -322,7 +317,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
// stopped, invalid state
String node_name = start_request;
start_request = StringName(); //clear start request
- ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing.");
+ ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing. Maybe you need to enable Autoplay on Load for one of the nodes in your state machine or call .start() first?");
}
} else {
if (!_travel(p_state_machine, start_request)) {
@@ -334,11 +329,17 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
}
} else {
// teleport to start
- path.clear();
- current = start_request;
- playing = true;
- play_start = true;
- start_request = StringName(); //clear start request
+ if (p_state_machine->states.has(start_request)) {
+ path.clear();
+ current = start_request;
+ playing = true;
+ play_start = true;
+ start_request = StringName(); //clear start request
+ } else {
+ StringName node = start_request;
+ start_request = StringName(); //clear start request
+ ERR_FAIL_V_MSG(0, "No such node: '" + node + "'");
+ }
}
}
@@ -398,7 +399,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//find next
StringName next;
- float next_xfade = 0;
+ float next_xfade = 0.0;
AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE;
if (path.size()) {
@@ -495,21 +496,13 @@ void AnimationNodeStateMachinePlayback::_bind_methods() {
ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachinePlayback::is_playing);
ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachinePlayback::get_current_node);
+ ClassDB::bind_method(D_METHOD("get_current_play_position"), &AnimationNodeStateMachinePlayback::get_current_play_pos);
+ ClassDB::bind_method(D_METHOD("get_current_length"), &AnimationNodeStateMachinePlayback::get_current_length);
ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path);
}
AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() {
- set_local_to_scene(true); //only one per instanced scene
-
- playing = false;
- len_current = 0;
- fading_time = 0;
- stop_request = false;
- len_total = 0.0;
- pos_current = 0.0;
- loops_current = 0;
- fading_pos = 0.0;
- start_request_travel = false;
+ set_local_to_scene(true); //only one per instantiated scene
}
///////////////////////////////////////////////////////
@@ -525,15 +518,15 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c
}
advance_conditions.sort_custom<StringName::AlphCompare>();
- for (List<StringName>::Element *E = advance_conditions.front(); E; E = E->next()) {
- r_list->push_back(PropertyInfo(Variant::BOOL, E->get()));
+ for (const StringName &E : advance_conditions) {
+ r_list->push_back(PropertyInfo(Variant::BOOL, E));
}
}
Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == playback) {
Ref<AnimationNodeStateMachinePlayback> p;
- p.instance();
+ p.instantiate();
return p;
} else {
return false; //advance condition
@@ -552,7 +545,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
states[p_name] = state;
emit_changed();
- emit_signal("tree_changed");
+ emit_signal(SNAME("tree_changed"));
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
@@ -565,16 +558,16 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
{
Ref<AnimationNode> node = states[p_name].node;
if (node.is_valid()) {
- node->disconnect_compat("tree_changed", this, "_tree_changed");
+ node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
}
}
states[p_name].node = p_node;
emit_changed();
- emit_signal("tree_changed");
+ emit_signal(SNAME("tree_changed"));
- p_node->connect_compat("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
@@ -584,9 +577,9 @@ Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name)
}
StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const {
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- if (E->get().node == p_node) {
- return E->key();
+ for (const KeyValue<StringName, State> &E : states) {
+ if (E.value.node == p_node) {
+ return E.key;
}
}
@@ -596,8 +589,8 @@ StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_
void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes) {
Vector<StringName> nodes;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- nodes.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ nodes.push_back(E.key);
}
nodes.sort_custom<StringName::AlphCompare>();
@@ -649,7 +642,7 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
}*/
emit_changed();
- emit_signal("tree_changed");
+ emit_signal(SNAME("tree_changed"));
}
void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) {
@@ -682,18 +675,18 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri
}*/
//path.clear(); //clear path
- emit_signal("tree_changed");
+ emit_signal(SNAME("tree_changed"));
}
void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
List<StringName> nodes;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- nodes.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ nodes.push_back(E.key);
}
nodes.sort_custom<StringName::AlphCompare>();
- for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
- r_nodes->push_back(E->get());
+ for (const StringName &E : nodes) {
+ r_nodes->push_back(E);
}
}
@@ -803,7 +796,7 @@ Vector2 AnimationNodeStateMachine::get_graph_offset() const {
return graph_offset;
}
-float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
+double AnimationNodeStateMachine::process(double p_time, bool p_seek) {
Ref<AnimationNodeStateMachinePlayback> playback = get_parameter(this->playback);
ERR_FAIL_COND_V(playback.is_null(), 0.0);
@@ -910,13 +903,12 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- names.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ names.push_back(E.key);
}
names.sort_custom<StringName::AlphCompare>();
- for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- String name = E->get();
+ for (const StringName &name : names) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "states/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "states/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
@@ -927,6 +919,18 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c
p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
+void AnimationNodeStateMachine::reset_state() {
+ states.clear();
+ transitions.clear();
+ playback = "playback";
+ start_node = StringName();
+ end_node = StringName();
+ graph_offset = Vector2();
+
+ emit_changed();
+ emit_signal(SNAME("tree_changed"));
+}
+
void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) {
ERR_FAIL_COND(!states.has(p_name));
states[p_name].position = p_position;
@@ -938,7 +942,7 @@ Vector2 AnimationNodeStateMachine::get_node_position(const StringName &p_name) c
}
void AnimationNodeStateMachine::_tree_changed() {
- emit_signal("tree_changed");
+ emit_signal(SNAME("tree_changed"));
}
void AnimationNodeStateMachine::_bind_methods() {
@@ -973,5 +977,4 @@ void AnimationNodeStateMachine::_bind_methods() {
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
- playback = "playback";
}