-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add node_notify signal for animation trees #102165
base: master
Are you sure you want to change the base?
Conversation
See also:
As I have pointed out in the past with those, it should be implemented so that the ancestor StateMachine returns the nested paths when in Grouped mode (https://godotengine.org/article/migrating-animations-from-godot-4-0-to-4-3/#grouped). In other words, it must be implemented in such a way that the signal is propagated to the ancestor State as special case for the Grouped mode. |
Thanks for the links, I hadn't seen those PRs. Do you think it would be worth adding
I'll work on adding this. Just to be sure I understand correctly, the changes I'll make would change the example root sm
Also regarding a comment you left on another PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the links, I hadn't seen those PRs. Do you think it would be worth adding fading_from_state_changed to this pr?
I think so.
As for the StateMachinePlayback
object, it should be a unique resource for each AnimationTree, so there should be no problem to fire a signal there.
However, if you want to fire a signal in the AnimationNode, signals should not be registered with AnimationNode as explained in the review below.
The simplest implementation would be to fire signal from the AnimationTree with its own BlendTree path. In this case, you can refer to AnimationTree::set_parameter()
to get the path. At this point, it may be better to separate the method for obtaining its own path from it and make it reusable.
But then, my concern is that each time we have more signals that we want to fire in the AnimationNode, we need to register all of them in the AnimationTree.
So, instead of adding a signal called oneshot_finished()
to the AnimationTree, we should add a generic abstract signal such as node_notified(animation_node_path, signal_name, signal_variants)
.
However, that PR should be a separate PR from the StateMachinePlayback
signal addition.
06a3c9d
to
89dbc1c
Compare
I've updated the pr to have Edit: One thing I'd like feedback on with the current code is if the signal emission should be put behind a call_deferred in all cases? I noticed it was like that for animation_started/animation_finished but wasn't sure if it should also be the case for the new signals. Easy change, just unsure what the preferred behavior would be. |
89dbc1c
to
4b9850a
Compare
This pr is currently sitting at +124 -11 which imo is a good size but if you'd prefer I can break this up into two PRs (maybe a third to rename |
doc/classes/AnimationTree.xml
Outdated
<signal name="node_finished"> | ||
<param index="0" name="node" type="StringName" /> | ||
<description> | ||
Emitted when the [param node] finishes playback. Only emitted for OneShot and StateMachine nodes. | ||
</description> | ||
</signal> | ||
<signal name="node_started"> | ||
<param index="0" name="node" type="StringName" /> | ||
<description> | ||
Emitted when the [param node] starts playback. Only emitted for OneShot and StateMachine nodes. | ||
</description> | ||
</signal> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest that it should be a generic signal as explained above.
So, instead of adding a signal called oneshot_finished() to the AnimationTree, we should add a generic abstract signal such as node_notified(animation_node_path, signal_name, signal_variants).
For example, what happens with NodeTransition? Don't we want a signal when BlendSpace is in DC mode and the values switch discretely? What should we use when firing a signal from a custom AnimationNode? I suppose it is not good way to add a new signal to the AnimationTree for them every time.
Also I think it is better to distinguish between signals in StateMachinePlayback and AnimationNode (so signals add to both StateMachinePlayback and AnimationTree) than to mix them up. In case of mix-ups all into AnimationTree, the StateMachine should be named to avoid confusion.
For example, if you follow the description, it must be MyStateMachine/Outer/Inner/Attack1
not Outer/Inner/Attack1
since we can't distinguish between two StateMachines that have the same configuration if they are placed same level of the blend tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, the concern remains that generic signals use strings as signal identifiers. Another idea is to pass some kind of Callable object from the AnimationNode to the AnimationTree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What sort of callable do you imagine, and would it make more sense to use an enum rather than bare strings? Also are there other examples of notification style multipurpose callbacks?
I'll think about it more but from my perspective a lot of these node notify events would be directly caused by user code, such as requesting a transition or changing the blendspace mode, and could be handled by an animation controller script. In comparison, I think node_started
and node_finished
would be harder to implement without extra coupling or polling of the tree's state. That said, it probably won't get to the point where the generic signal gets too expensive from unnecessary connections, so the question of which things should be node notified emits or not doesn't really matter. It's also the case that this doesn't need to be decided without some future use case in mind - the state machine signal addresses the proposal use case (and my use case) on its own.
Either way I'll give the generic signal a shot and also break off the state machine changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I think it is better to distinguish between signals in StateMachinePlayback and AnimationNode (so signals add to both StateMachinePlayback and AnimationTree) than to mix them up. In case of mix-ups all into AnimationTree, the StateMachine should be named to avoid confusion.
Sorry if the example is unclear but the indented lines are from signals on the state machine playback and the un-indented lines are from signals on the blend tree. They'll be more distinct in a bit since the tree will just have node_notify
. Or am I misreading this and you would prefer the playback's internal node events be bubbled up to a root tree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this has been updated to use a generic signal node_notify
and the other class was split into its own pr #102398
4b9850a
to
e09355a
Compare
e09355a
to
2c7c814
Compare
Closes godotengine/godot-proposals#10253.
Related to #102398
This adds
node_notify(StringName, NotifyReason)
toAnimationTree
as a generic signal used for node state changes during processing/playback. CurrentlyNotifyReason
can be eitherNOTIFY_STARTED
orNOTIFY_FINISHED
and is implemented for one shot and state machine nodes. For example in the following blend tree:The new signal fires with the following values: