I'd like to request the ability to duplicate a track in the AnimationPlayer pane. Often times, I want to have the same animation track play on multiple nodes, so being able to duplicate the entire track, then just adjust the node path would be a huge boon to my productivity. As it is, it's quite tedious to do this.
Its been a few months, is this currently possible? I don't see an option for it.
Not that I know of, but it should be easy to implement.
For now you can just duplicate the animation and set the new animation to operate on the new node. Then call both animations to play simultaneously.
Edit: Actually this doesn't work. AnimationPlayer can only play one at a time, so you have to manually recreate the tracks.
I really needed when dealing with rendering order problems, where you need to reparent some of your Sprites from to a new node and you also wanna animate this new node exactly as the old parent node. Especially tracks with numerous keyframes.
In the meantime, you can use the Duplicate Transposed function. Here's a thread on it if you're having problem: https://github.com/godotengine/godot/issues/15815
Can't this currently easily be done via copy_tracks and paste_tracks?
Hi all, first post on Github :).
I'm thinking about opening another issue about that, because yes, copy_tracks and paste_tracky is possible in the 3.1 editor, not in 3.0.6 as far I could tell, however even in 3.1 it is impossible to paste onto a different tracktree (like a for a different Sprite node) than the one the copy was made from, rendering it completely useless --well, for me at last. Unfortunately my whole project stands of falls with the ability to have one AnimationPlayer animate multiple Sprite nodes.

I'm going to try to fix this.
The code looks something like this.
Some of the animation-> calls can be replaced by this and thus omitted.
int32_t _copy_track(Ref<Animation> animation, int32_t src_track, NodePath new_path) {
ERR_FAIL_COND_V(animation.is_null(), -1);
ERR_FAIL_INDEX_V(src_track, animation->get_track_count(), -1);
ERR_FAIL_COND_V(animation->find_track(new_path) != -1, -1);
int dst_track = animation->get_track_count();
int32_t r_new_track = animation->add_track(animation->track_get_type(src_track));
animation->track_set_path(dst_track, new_path);
animation->track_set_imported(dst_track, animation->track_is_imported(src_track));
animation->track_set_enabled(dst_track, animation->track_is_enabled(src_track));
animation->track_set_interpolation_type(dst_track, animation->track_get_interpolation_type(src_track));
animation->track_set_interpolation_loop_wrap(dst_track, animation->track_get_interpolation_loop_wrap(src_track));
for (int i = 0; i < animation->track_get_key_count(src_track); i++) {
animation->track_insert_key(dst_track, animation->track_get_key_time(src_track, i), animation->track_get_key_value(src_track, i), animation->track_get_key_transition(src_track, i));
}
return r_new_track;
}
Edited. I'll make a version that is suitable for adding to the Animation class.
This will need the gdscript bindings / ui added, but it should work.
int32_t Animation::copy_track_to_path(Ref<Animation> &p_animation, const int32_t p_src_track, const NodePath p_new_path) {
ERR_FAIL_COND_V(p_animation.is_null(), -1);
ERR_FAIL_INDEX_V(p_src_track, p_animation->get_track_count(), -1);
ERR_FAIL_COND_V(find_track(p_new_path) != -1, -1);
int32_t dst_track = get_track_count();
const int32_t r_new_track = p_animation->add_track(track_get_type(p_src_track));
p_animation->track_set_path(dst_track, p_new_path);
p_animation->track_set_imported(dst_track, track_is_imported(p_src_track));
p_animation->track_set_enabled(dst_track, track_is_enabled(p_src_track));
p_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_src_track));
p_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_src_track));
for (size_t i = 0; i < track_get_key_count(p_src_track); i++) {
p_animation->track_insert_key(dst_track, track_get_key_time(p_src_track, i), track_get_key_value(p_src_track, i), track_get_key_transition(p_src_track, i));
}
return r_new_track;
}
Edited types and const.
There are four problems.
Hope that clears up the confusion.
Is it not closed because #24210 hasn't passed the review request?
@kimjiy9607 Indeed, the pull request needs to be merged first before this issue can be closed.
Most helpful comment
I'm going to try to fix this.