summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-02-01 07:24:05 +0100
committerRémi Verschelde <rverschelde@gmail.com>2023-02-01 07:24:05 +0100
commitd8e71dc51a54d0049cdbdee34d6b0237400f52ef (patch)
tree6519457d663342a6e5b9bc336548dfec7421ce87 /scene/animation
parent67ab9d85d4977da5936b6a22d4bb4ff3f35485be (diff)
parent4525181c2dc959609302d8977b5ed6b390f0cfc8 (diff)
Merge pull request #72450 from TokageItLab/optional-restart
Make restart in NodeStateMachine / NodeTransition optional
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/animation_blend_tree.cpp32
-rw-r--r--scene/animation/animation_blend_tree.h4
-rw-r--r--scene/animation/animation_node_state_machine.cpp15
-rw-r--r--scene/animation/animation_node_state_machine.h4
4 files changed, 45 insertions, 10 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 45f4f690b9..797999625b 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -800,6 +800,14 @@ Ref<Curve> AnimationNodeTransition::get_xfade_curve() const {
return xfade_curve;
}
+void AnimationNodeTransition::set_allow_transition_to_self(bool p_enable) {
+ allow_transition_to_self = p_enable;
+}
+
+bool AnimationNodeTransition::is_allow_transition_to_self() const {
+ return allow_transition_to_self;
+}
+
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_external_seeking) {
String cur_transition_request = get_parameter(transition_request);
int cur_current_index = get_parameter(current_index);
@@ -815,20 +823,22 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
int new_idx = find_input(cur_transition_request);
if (new_idx >= 0) {
if (cur_current_index == new_idx) {
- // Transition to same state.
- restart = input_data[cur_current_index].reset;
- cur_prev_xfading = 0;
- set_parameter(prev_xfading, 0);
- cur_prev_index = -1;
- set_parameter(prev_index, -1);
+ if (allow_transition_to_self) {
+ // Transition to same state.
+ restart = input_data[cur_current_index].reset;
+ cur_prev_xfading = 0;
+ set_parameter(prev_xfading, 0);
+ cur_prev_index = -1;
+ set_parameter(prev_index, -1);
+ }
} else {
switched = true;
cur_prev_index = cur_current_index;
set_parameter(prev_index, cur_current_index);
+ cur_current_index = new_idx;
+ set_parameter(current_index, cur_current_index);
+ set_parameter(current_state, cur_transition_request);
}
- cur_current_index = new_idx;
- set_parameter(current_index, cur_current_index);
- set_parameter(current_state, cur_transition_request);
} else {
ERR_PRINT("No such input: '" + cur_transition_request + "'");
}
@@ -932,8 +942,12 @@ void AnimationNodeTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_xfade_curve", "curve"), &AnimationNodeTransition::set_xfade_curve);
ClassDB::bind_method(D_METHOD("get_xfade_curve"), &AnimationNodeTransition::get_xfade_curve);
+ ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeTransition::set_allow_transition_to_self);
+ ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeTransition::is_allow_transition_to_self);
+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01,suffix:s"), "set_xfade_time", "get_xfade_time");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "xfade_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_xfade_curve", "get_xfade_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self");
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED, "Inputs,input_"), "set_input_count", "get_input_count");
}
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 3c27edbf70..20f8e9b190 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -294,6 +294,7 @@ class AnimationNodeTransition : public AnimationNodeSync {
double xfade_time = 0.0;
Ref<Curve> xfade_curve;
+ bool allow_transition_to_self = false;
protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
@@ -325,6 +326,9 @@ public:
void set_xfade_curve(const Ref<Curve> &p_curve);
Ref<Curve> get_xfade_curve() const;
+ void set_allow_transition_to_self(bool p_enable);
+ bool is_allow_transition_to_self() const;
+
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
AnimationNodeTransition();
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 7fb831b3b2..ec28a5cca1 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -252,7 +252,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
path.clear(); //a new one will be needed
if (current == p_travel) {
- return false; // Will teleport oneself (restart).
+ return !p_state_machine->is_allow_transition_to_self();
}
Vector2 current_pos = p_state_machine->states[current].position;
@@ -813,6 +813,14 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED);
}
+void AnimationNodeStateMachine::set_allow_transition_to_self(bool p_enable) {
+ allow_transition_to_self = p_enable;
+}
+
+bool AnimationNodeStateMachine::is_allow_transition_to_self() const {
+ return allow_transition_to_self;
+}
+
bool AnimationNodeStateMachine::can_edit_node(const StringName &p_name) const {
if (states.has(p_name)) {
return !(states[p_name].node->is_class("AnimationNodeStartState") || states[p_name].node->is_class("AnimationNodeEndState"));
@@ -1383,6 +1391,11 @@ void AnimationNodeStateMachine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset);
+
+ ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeStateMachine::set_allow_transition_to_self);
+ ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeStateMachine::is_allow_transition_to_self);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self");
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index cf4d850aa6..5c2a4d6264 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -188,6 +188,7 @@ private:
};
HashMap<StringName, State> states;
+ bool allow_transition_to_self = false;
struct Transition {
StringName from;
@@ -254,6 +255,9 @@ public:
void remove_transition_by_index(const int p_transition);
void remove_transition(const StringName &p_from, const StringName &p_to);
+ void set_allow_transition_to_self(bool p_enable);
+ bool is_allow_transition_to_self() const;
+
bool can_edit_node(const StringName &p_name) const;
AnimationNodeStateMachine *get_prev_state_machine() const;