0 votes

Hello, thank you for your time.

I seek help with AnimationTree. I can't figure out, how to reset an animation, after OneShot node has finished.

Minimal example:
example

Having 2 animations connected to OneShot node
[in=idle]
[shot=action]
I can run 'action' animation with:

$AnimationTree.set("parameters/OneShot/active", 1);

Problem is when action is finished, then it continues with idle animation from the point where it stopped.
How can I set it up, so that after action is completed, it will start idle from the beginning?

Godot version 3.3
in Engine by (213 points)

1 Answer

+1 vote
Best answer

Ok finally tried again figured at least some solution:

Placing a SeekNode after 'idle' animation and adding a method call at the end of 'action' animation (in AnimationPlayer's track).

Inside called method I can reset idle via that SeekNode

tree.set("parameters/Seek/seek_position", 0);
by (213 points)

I've just been having the same problem, however, it wasn't that the animation returned to the last frame during idle, but that it returned to the idle animation and didn't update until a new frame: for context my idle was just 2 frames, one every 1.5 seconds. So after doing a one shot attack animation, it could stay 'stuck' on the oneshot's last frame for a 1.5 seconds before idle kicked back in.

At first i thought I could just populate the idle animation with many redundant(repeated) frames so there was very little delay when switching back, but obviously that's no ideal.

Speaking of not ideal, the solution for me was to create 2 new functions to be called by my oneshots:

func cache_current_animation_frame():
cached_anim_frame = $Sprite.frame

func set_animation_frame_to_cache():
$Sprite.frame = cached_anim_frame

to work, i needed it to happen before the first frame change so my attack animation had to be delayed by 0.01 seconds, so i could first call the cache function. Finally the last frame of the animation calls the set function and it all works.
animation_player timeline with solution shown
Not sure this is any better than OP's solution, but it saved me not having to mess around with seek nodes etc.

update:
While my method worked in the use case, when i added another oneshot animation it was possible to accidentally cache the frame from there instead of the preceding idle. In the end I simplified my solution because now I just use a function that resets the frame to 0 (my idle frame 1) without having to cache anything.

update2: converted to comment, as I think the way to do this is preferably with seek.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.