Open artvel opened 6 months ago
Just found another case that requires this feature.
If you have an AnimationTree that blends the same animation fully(while standing) and partially(while walking). You can't have a transition if you want to blend between fully and partially as you can't provide the start time.
So in other words, when you executed the animation fully while standing and while the animation is playing you started walking. You would want to take the current play time from fully and start playing partially from the same position.
Hey @jmarceno thanks for bringing up ideas. I just had a look at it and so far I don't see how to actually solve it. Maybe I am missing something.
This is how it looks:
I would handle the transition through code as I have a movement state machine in gdscript.
So what I would do is when A
started while in Standing
state. I would check in the start of any moving state like Walking
, Jumping
or Falling
if A
is running. In case of true, I would call something like:
var current_play_time:float = lowerBody.get_current_play_position()
animation_tree.set("parameters/BlendCasts/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)
upperBody.travel("A", true, current_play_time)
If there is a better way of handling this, I'd love to here it.
Okay, thanks. I'll look into that.
About your point on the global TimeScale. I think, there are enough ways to handle the scale globally already. For example here:
I have a different issue where I want to force play an animation node from the start, when traveling to the same node as the current node.
But that's relevant to this issue because it raises the question of whether start_position=0
should be considered like "keeping current state" (current behavior, so retrocompatible) or "force restart from zero" (what I need).
Real-world case: if hero damages enemy, enemy plays Hurt animation. Hurt animation automatically reverts to Idle at the end. But if hero damages enemy again right on the last frame of Hurt animation, AnimationTree Hurt animation will
Indeed, currently, if current playback node is A, and I travel
to A, nothing happens. Unlike AnimationPlayer I cannot force play from 0 by calling stop
first: AnimationNodeStateMachinePlayback.stop
has a different meaning and will simply stop running the Animation Tree state machine, keeping the last state (last animation on its last frame) instead of reverting it to the first frame and acknowledging the next travel
as a brand new animation to play. It seems that the very nature of travel makes it hard to tell it to replay the same node twice.
Inspired by AnimationPlayer play(&"RESET") + advance(0)
hack (https://github.com/godotengine/godot-proposals/issues/6417), I tried other hacks such as:
state_machine.travel(&"Idle")
state_machine.next()
state_machine.travel(animation_name)
state_machine.next()
to no avail.
The only call that actually forced node change was start
:
var last_animation := state_machine.get_current_node()
if last_animation == animation_name:
# When already playing the same animation
# (including when chaining from last frame)
# we need to force restart (travel would not restart the animation
# and unlike AnimationPlayer, stop only pauses so travel would
# not work after stop either)
state_machine.start(animation_name)
else:
state_machine.travel(animation_name)
It's not that bad, but it needs an extra check on last animation (state_machine.get_current_node()
) while a from_start
flag would be explicit on what I want, and start_position=0
would also work, but when using a float there is no way to indicate that we want to preserve the last state (unless we encode start_position=-1
but I find it less intuitive).
Should I make a different issue to suggest either a parameter or different method restart
to force play the same node from the start, then?
Describe the problem or limitation you are having in your project
I am having an animation that is visualizing a magical cast. The animation is 5s+ looping in a casting position type and after that it is visualizing the execution of the cast.
I would like to take the execution time(5.26) and run the animation like:
I don't see how I could solve this in a smarter way right now besides cutting the animations perfectly so it fits to every ability cast time. That would be a lot of initial and maintenance work.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Having the start position parameter enables us to have some animation types and just match the start position without creating the same kind of animation multiple times with different timings.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
If this enhancement will not be used often, can it be worked around with a few lines of script?
No
Is there a reason why this should be core and not an add-on in the asset library?
NA