mirror of
https://github.com/godotengine/godot.git
synced 2025-02-09 20:32:15 +00:00
Add node_notify signal for animation trees
This commit is contained in:
parent
eee39f004b
commit
2c7c814a60
@ -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>
|
||||
|
@ -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].">
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -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('/'));
|
||||
|
||||
@ -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"));
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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));
|
||||
@ -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.
|
||||
@ -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() {
|
||||
|
@ -411,6 +411,7 @@ class AnimationNodeBlendTree : public AnimationRootNode {
|
||||
};
|
||||
|
||||
AHashMap<StringName, Node> nodes;
|
||||
AHashMap<AnimationNode *, StringName> node_to_name;
|
||||
|
||||
Vector2 graph_offset;
|
||||
|
||||
|
@ -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>();
|
||||
@ -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) {
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
@ -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() {
|
||||
|
@ -54,6 +54,11 @@ public:
|
||||
FILTER_BLEND
|
||||
};
|
||||
|
||||
enum NotifyReason {
|
||||
NOTIFY_STARTED,
|
||||
NOTIFY_FINISHED
|
||||
};
|
||||
|
||||
struct Input {
|
||||
String name;
|
||||
};
|
||||
@ -181,6 +186,8 @@ protected:
|
||||
|
||||
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)
|
||||
@ -243,6 +250,7 @@ public:
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(AnimationNode::FilterAction)
|
||||
VARIANT_ENUM_CAST(AnimationNode::NotifyReason)
|
||||
|
||||
// Root node does not allow inputs.
|
||||
class AnimationRootNode : public AnimationNode {
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user