From 904db4d09383b9aa7aa72663ee7500c21bb2d2a5 Mon Sep 17 00:00:00 2001 From: Lorenzo Cerqua Date: Fri, 21 Feb 2020 06:26:03 +0100 Subject: [PATCH] Add an "invert condition" property to AnimationNodeStateMachineTransition. When true, it will advance when its condition evaluates to false. Co-Authored-By: Hugo Locurcio --- .../AnimationNodeStateMachineTransition.xml | 3 +++ .../animation_state_machine_editor.cpp | 14 ++++++++--- .../plugins/animation_state_machine_editor.h | 1 + .../animation_node_state_machine.cpp | 23 +++++++++++++++++-- .../animation/animation_node_state_machine.h | 4 ++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/doc/classes/AnimationNodeStateMachineTransition.xml b/doc/classes/AnimationNodeStateMachineTransition.xml index 2f0ebd7de63e..4987a1d86bcb 100644 --- a/doc/classes/AnimationNodeStateMachineTransition.xml +++ b/doc/classes/AnimationNodeStateMachineTransition.xml @@ -27,6 +27,9 @@ Don't use this transition during [method AnimationNodeStateMachinePlayback.travel] or [member auto_advance]. + + If [code]true[/code], instead of turning on auto advance when the [member advance_condition] is met (i.e. evaluates to [code]true[/code]), auto advance will be turned on when the [member advance_condition] is [i]not[/i] met (i.e. evaluates to [code]false[/code]). + Lower priority transitions are preferred when travelling through the tree via [method AnimationNodeStateMachinePlayback.travel] or [member auto_advance]. diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index c6d2faf849ba..6386df94bfdf 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -684,6 +684,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref tr = state_machine->get_transition(i); tl.disabled = tr->is_disabled(); tl.auto_advance = tr->has_auto_advance(); + tl.invert_condition = tr->get_invert_condition(); tl.advance_condition_name = tr->get_advance_condition_name(); tl.advance_condition_state = false; tl.mode = tr->get_switch_mode(); @@ -727,9 +728,16 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { bool auto_advance = tl.auto_advance; StringName fullpath = AnimationTreeEditor::get_singleton()->get_base_path() + String(tl.advance_condition_name); - if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(fullpath))) { - tl.advance_condition_state = true; - auto_advance = true; + if (tl.advance_condition_name != StringName()) { + if (bool(AnimationTreeEditor::get_singleton()->get_tree()->get(fullpath))) { + tl.advance_condition_state = true; + auto_advance = true; + } + + if (tl.invert_condition) { + tl.advance_condition_state = !tl.advance_condition_state; + auto_advance = !auto_advance; + } } _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, selected, travel, auto_advance); diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index a969ddd26bdf..4f5ca62de0e4 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -126,6 +126,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { Vector2 to; AnimationNodeStateMachineTransition::SwitchMode mode; StringName advance_condition_name; + bool invert_condition; bool advance_condition_state = false; bool disabled = false; bool auto_advance = false; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index ef9f531f0449..41b6602c9500 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -68,6 +68,14 @@ StringName AnimationNodeStateMachineTransition::get_advance_condition_name() con return advance_condition_name; } +void AnimationNodeStateMachineTransition::set_invert_condition(bool p_enable) { + invert_condition = p_enable; +} + +bool AnimationNodeStateMachineTransition::get_invert_condition() const { + return invert_condition; +} + void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) { ERR_FAIL_COND(p_xfade < 0); xfade = p_xfade; @@ -106,6 +114,9 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ClassDB::bind_method(D_METHOD("set_advance_condition", "name"), &AnimationNodeStateMachineTransition::set_advance_condition); ClassDB::bind_method(D_METHOD("get_advance_condition"), &AnimationNodeStateMachineTransition::get_advance_condition); + ClassDB::bind_method(D_METHOD("set_invert_condition", "invert"), &AnimationNodeStateMachineTransition::set_invert_condition); + ClassDB::bind_method(D_METHOD("get_invert_condition"), &AnimationNodeStateMachineTransition::get_invert_condition); + ClassDB::bind_method(D_METHOD("set_xfade_time", "secs"), &AnimationNodeStateMachineTransition::set_xfade_time); ClassDB::bind_method(D_METHOD("get_xfade_time"), &AnimationNodeStateMachineTransition::get_xfade_time); @@ -118,6 +129,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "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::BOOL, "invert_condition"), "set_invert_condition", "get_invert_condition"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); @@ -132,6 +144,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() { AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() { switch_mode = SWITCH_MODE_IMMEDIATE; auto_advance = false; + invert_condition = false; xfade = 0; disabled = false; priority = 1; @@ -418,8 +431,14 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st auto_advance = true; } StringName advance_condition_name = p_state_machine->transitions[i].transition->get_advance_condition_name(); - if (advance_condition_name != StringName() && bool(p_state_machine->get_parameter(advance_condition_name))) { - auto_advance = true; + if (advance_condition_name != StringName()) { + if (bool(p_state_machine->get_parameter(advance_condition_name))) { + auto_advance = true; + } + + if (p_state_machine->transitions[i].transition->get_invert_condition()) { + auto_advance = !auto_advance; + } } if (p_state_machine->transitions[i].from == current && auto_advance) { diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index daeb2fabaa32..81937804c3ed 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -48,6 +48,7 @@ class AnimationNodeStateMachineTransition : public Resource { bool auto_advance; StringName advance_condition; StringName advance_condition_name; + bool invert_condition; float xfade; bool disabled; int priority; @@ -67,6 +68,9 @@ class AnimationNodeStateMachineTransition : public Resource { StringName get_advance_condition_name() const; + void set_invert_condition(bool p_enable); + bool get_invert_condition() const; + void set_xfade_time(float p_xfade); float get_xfade_time() const;