Skip to content

Commit

Permalink
Add node_notify signal for animation trees
Browse files Browse the repository at this point in the history
  • Loading branch information
a-johnston committed Feb 4, 2025
1 parent eee39f0 commit 2c7c814
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 7 deletions.
6 changes: 6 additions & 0 deletions doc/classes/AnimationNode.xml
Original file line number Diff line number Diff line change
Expand Up @@ -244,5 +244,11 @@
<constant name="FILTER_BLEND" value="3" enum="FilterAction">
Paths matching the filter will be blended (by the blend value).
</constant>
<constant name="NOTIFY_STARTED" value="0" enum="NotifyReason">
The node has started playback.
</constant>
<constant name="NOTIFY_FINISHED" value="1" enum="NotifyReason">
The node has finished playback.
</constant>
</constants>
</class>
7 changes: 7 additions & 0 deletions doc/classes/AnimationTree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
Emitted when the [member anim_player] is changed.
</description>
</signal>
<signal name="node_notify">
<param index="0" name="node" type="StringName" />
<param index="1" name="reason" type="int" />
<description>
Emitted when the [param node] state changes during processing or playback.
</description>
</signal>
</signals>
<constants>
<constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback" deprecated="See [constant AnimationMixer.ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS].">
Expand Down
20 changes: 13 additions & 7 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,10 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
set_parameter(fade_in_remaining, cur_fade_in_remaining);
set_parameter(fade_out_remaining, cur_fade_out_remaining);

if (cur_active != (bool)get_parameter(active)) {
_notify_tree(cur_active ? NOTIFY_FINISHED : NOTIFY_STARTED);
}

return cur_internal_active ? os_nti : main_nti;
}

Expand Down Expand Up @@ -1451,6 +1455,7 @@ AnimationNodeOutput::AnimationNodeOutput() {
void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(node_to_name.has(*p_node));
ERR_FAIL_COND(p_name == SceneStringName(output));
ERR_FAIL_COND(String(p_name).contains_char('/'));

Expand All @@ -1459,6 +1464,7 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
n.position = p_position;
n.connections.resize(n.node->get_input_count());
nodes[p_name] = n;
node_to_name[*p_node] = p_name;

emit_changed();
emit_signal(SNAME("tree_changed"));
Expand All @@ -1476,12 +1482,10 @@ Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) co
}

StringName AnimationNodeBlendTree::get_node_name(const Ref<AnimationNode> &p_node) const {
for (const KeyValue<StringName, Node> &E : nodes) {
if (E.value.node == p_node) {
return E.key;
}
AHashMap<AnimationNode *, StringName>::ConstIterator E = node_to_name.find(*p_node);
if (E) {
return E->value;
}

ERR_FAIL_V(StringName());
}

Expand Down Expand Up @@ -1525,6 +1529,7 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {

{
Ref<AnimationNode> node = nodes[p_name].node;
node_to_name.erase(*node);
node->disconnect(SNAME("tree_changed"), callable_mp(this, &AnimationNodeBlendTree::_tree_changed));
node->disconnect(SNAME("animation_node_renamed"), callable_mp(this, &AnimationNodeBlendTree::_animation_node_renamed));
node->disconnect(SNAME("animation_node_removed"), callable_mp(this, &AnimationNodeBlendTree::_animation_node_removed));
Expand Down Expand Up @@ -1554,8 +1559,8 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
ERR_FAIL_COND(p_new_name == SceneStringName(output));

nodes[p_name].node->disconnect_changed(callable_mp(this, &AnimationNodeBlendTree::_node_changed));

nodes[p_new_name] = nodes[p_name];
node_to_name[*(nodes[p_new_name].node)] = p_new_name;
nodes.erase(p_name);

// Rename connections.
Expand Down Expand Up @@ -1853,7 +1858,8 @@ void AnimationNodeBlendTree::_initialize_node_tree() {
n.node = output;
n.position = Vector2(300, 150);
n.connections.resize(1);
nodes["output"] = n;
nodes[SceneStringName(output)] = n;
node_to_name[*n.node] = SceneStringName(output);
}

AnimationNodeBlendTree::AnimationNodeBlendTree() {
Expand Down
1 change: 1 addition & 0 deletions scene/animation/animation_blend_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ class AnimationNodeBlendTree : public AnimationRootNode {
};

AHashMap<StringName, Node> nodes;
AHashMap<AnimationNode *, StringName> node_to_name;

Vector2 graph_offset;

Expand Down
9 changes: 9 additions & 0 deletions scene/animation/animation_node_state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {

void AnimationNodeStateMachinePlayback::_set_current(AnimationNodeStateMachine *p_state_machine, const StringName &p_state) {
current = p_state;

if (current == StringName()) {
group_start_transition = Ref<AnimationNodeStateMachineTransition>();
group_end_transition = Ref<AnimationNodeStateMachineTransition>();
Expand Down Expand Up @@ -490,6 +491,7 @@ void AnimationNodeStateMachinePlayback::_start(AnimationNodeStateMachine *p_stat
teleport_request = true;
stop_request = false;
start_request = StringName();
p_state_machine->_notify_tree(AnimationNode::NOTIFY_STARTED);
}

bool AnimationNodeStateMachinePlayback::_travel(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, bool p_test_only) {
Expand Down Expand Up @@ -719,6 +721,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
travel_request = StringName();
path.clear();
playing = false;
p_state_machine->_notify_tree(AnimationNode::NOTIFY_FINISHED);
return AnimationNode::NodeTimeInfo();
}

Expand Down Expand Up @@ -883,8 +886,14 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
if (will_end || ((p_state_machine->get_state_machine_type() == AnimationNodeStateMachine::STATE_MACHINE_TYPE_NESTED) && !p_state_machine->has_transition_from(current))) {
// There is no next transition.
if (fading_from != StringName()) {
if (MAX(current_nti.get_remain(), fadeing_from_nti.get_remain()) <= 0) {
p_state_machine->_notify_tree(AnimationNode::NOTIFY_FINISHED);
}
return Animation::is_greater_approx(current_nti.get_remain(), fadeing_from_nti.get_remain()) ? current_nti : fadeing_from_nti;
}
if (current_nti.get_remain() <= 0) {
p_state_machine->_notify_tree(AnimationNode::NOTIFY_FINISHED);
}
return current_nti;
}

Expand Down
14 changes: 14 additions & 0 deletions scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,19 @@ void AnimationNode::_bind_methods() {
BIND_ENUM_CONSTANT(FILTER_PASS);
BIND_ENUM_CONSTANT(FILTER_STOP);
BIND_ENUM_CONSTANT(FILTER_BLEND);

BIND_ENUM_CONSTANT(NOTIFY_STARTED);
BIND_ENUM_CONSTANT(NOTIFY_FINISHED);
}

void AnimationNode::_notify_tree(AnimationNode::NotifyReason p_reason) {
AnimationNodeBlendTree *blend_tree = Object::cast_to<AnimationNodeBlendTree>(node_state.parent);
if (blend_tree) {
StringName node_name = blend_tree->get_node_name(this);
if (!node_name.is_empty()) {
process_state->tree->emit_signal(SceneStringName(node_notify), node_name, p_reason);
}
}
}

AnimationNode::AnimationNode() {
Expand Down Expand Up @@ -991,6 +1004,7 @@ void AnimationTree::_bind_methods() {
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")));
ADD_SIGNAL(MethodInfo(SceneStringName(node_notify), PropertyInfo(Variant::STRING_NAME, "node"), PropertyInfo(Variant::INT, "reason")));
}

AnimationTree::AnimationTree() {
Expand Down
8 changes: 8 additions & 0 deletions scene/animation/animation_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class AnimationNode : public Resource {
FILTER_BLEND
};

enum NotifyReason {
NOTIFY_STARTED,
NOTIFY_FINISHED
};

struct Input {
String name;
};
Expand Down Expand Up @@ -181,6 +186,8 @@ class AnimationNode : public Resource {

void _validate_property(PropertyInfo &p_property) const;

void _notify_tree(AnimationNode::NotifyReason p_reason);

GDVIRTUAL0RC(Dictionary, _get_child_nodes)
GDVIRTUAL0RC(Array, _get_parameter_list)
GDVIRTUAL1RC(Ref<AnimationNode>, _get_child_by_name, StringName)
Expand Down Expand Up @@ -243,6 +250,7 @@ class AnimationNode : public Resource {
};

VARIANT_ENUM_CAST(AnimationNode::FilterAction)
VARIANT_ENUM_CAST(AnimationNode::NotifyReason)

// Root node does not allow inputs.
class AnimationRootNode : public AnimationNode {
Expand Down
1 change: 1 addition & 0 deletions scene/scene_string_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class SceneStringNames {
const StringName sort_children = StaticCString::create("sort_children");

const StringName finished = StaticCString::create("finished");
const StringName node_notify = StaticCString::create("node_notify");
const StringName animation_finished = StaticCString::create("animation_finished");
const StringName animation_changed = StaticCString::create("animation_changed");
const StringName animation_started = StaticCString::create("animation_started");
Expand Down

0 comments on commit 2c7c814

Please sign in to comment.