Playing animation from a specific keyframe
-
func update_gun(): var trigger_cock_anim = anim_player.get_animation(trigger_cock) var tg_track = trigger_cock_anim.find_track("AnimationPlayer:NlaTrack_005", 8) print(tg_track)
I'll be honest, I don't actually understand the difference between animation and animation track, but I'm programming a revolver and I want to play backward a trigger cock animation, (when you are in the middle of it but the release the left mouse button then it plays backward from the keyframe you were when the mouse button was released) and I think I can do it with
animation_track_set_key_animation
But for this, I need the track index of my animation which when I try to get with .find_track always returns -1 (when running the function on the first code block) and according to the docs, it means the track was not found.
Am I trying to do what's in the title in the right way? If not, then what should I try? If yes, how can I get it to work?
I know that the problem in my code is probably on the track path, which I don't know how to get (as I said before I don't even understand the difference between animation and animation track), but I feel like there's another way to do what I want to do.
I just wrote a random path based on documentation I saw for find_track at posts about this method on forums, but they are probably from Godot 3, as they don't even have the Track_Type second argument in their find_track methods.
-
Alright so let's start with, Animations:
- Animations are the actual animation data - the keyframes, curves, and properties that change over time.
- They contain the information about how an object's properties (position, scale, rotation, etc) change over the duration of the animation.
Animation Tracks:
- Animation tracks are containers that hold individual animations.
- Though, an animation track can contain multiple animations that are played sequentially.
- Animation tracks allow you to organize your animations and control things like blending between animations.
- A single AnimationPlayer node can have multiple animation tracks.
What?!
- Animations contain the actual animation data - the changing properties over time.
- Animation tracks are containers that organize your animations and allow you to blend between them.
- AnimationPlayer nodes play animations and animation tracks. They control how the animations are executed.
Here is how I would approach playing an animation backwards in Godot:
- First, get a reference to the animation player node that is playing your trigger animation.
var anim_player = get_node("AnimationPlayer")
- Get a reference to the trigger animation. You can use get_animation() and pass the animation name.
var trigger_anim = anim_player.get_animation("trigger")
- Set the animation to play backwards using the speed property. A negative speed will play the animation backwards.
trigger_anim.speed = -1.0
- Call play() on the animation player to start playing the animation backwards.
anim_player.play("trigger")
- When the mouse button is released, set the speed back to a positive value to play the animation forwards again.
trigger_anim.speed = 1.0
So in summary, the key is to simply set the animation speed to a negative value to play it backwards, and a positive value to play it forwards. You do not need to deal with animation tracks for a simple backwards playback.
-
when I try to get with .find_track always returns -1 (when running the function on the first code block)
Does that mean it doesn't return -1 if you run it later down the blocks? You can't do anything on something that not found.
-
Sorry, for the late answer, so, Now I understand what are the tracks, but about the speed part, at first I didn't understand but when I realized and tried to apply it:
func update_gun(): if Input.is_action_just_pressed("fire") and anim_player.is_playing() == false and cocked == true: shoot() cocked = false elif Input.is_action_just_pressed("fire") and anim_player.is_playing() == false: anim_player.get_animation(trigger_cock).speed = 1.0 anim_player.play(trigger_cock) anim_player.connect("animation_finished", func on_anim_finish(anim_name): if anim_name == trigger_cock: shoot() ) elif Input.is_action_pressed("fire") == false and anim_player.current_animation == "trigger_cock": anim_player.get_animation(trigger_cock).speed = -1.0 func _process(_delta): update_gun() #other stuff
I'm getting this error:
Invalid set index 'speed' (on base: 'Animation') with value of type 'float'.
I'm my code it's line 69 but in this block, it's 6. (also trigger_cock variable stands for a string: "NlaTrack_005""
-
@altria said in Playing animation from a specific keyframe:
Does that mean it doesn't return -1 if you run it later down the blocks?
It returns -1 in any place
Update on my post that's being analyzed: I found out about AnimationPlayer.speed_scale searching on google now everything is working just fine! Thank you!
new code:
func update_gun(): if Input.is_action_just_pressed("fire") and anim_player.is_playing() == false and cocked == true: shoot() cocked = false elif Input.is_action_just_pressed("fire") and anim_player.is_playing() == false: hammer_debug = true anim_player.speed_scale = 1.0 anim_player.play(trigger_cock) anim_player.connect("animation_finished", func on_anim_finish(anim_name): if anim_name == trigger_cock and hammer_debug == true: shoot() ) if Input.is_action_just_released("fire") and anim_player.current_animation == trigger_cock: hammer_debug = false anim_player.speed_scale = -1.0 func _process(_delta): update_gun()
Just added a little debounce so the animation ending while going backwards don't call the shoot function.
-