Godot: Add ability to duplicate track in AnimationPlayer

Created on 25 Dec 2017  路  12Comments  路  Source: godotengine/godot

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.

enhancement junior job editor usability

Most helpful comment

I'm going to try to fix this.

All 12 comments

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.

track-cp-issue

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.

  1. duplicate a track in the AnimationPlayer which is added in 3.1
  2. duplicate a track in the AnimationPlayer to a path which my above code does
  3. (Code) duplicate a track from one AnimationPlayer to another AnimationPlayer which should be possible in gdscript since the function takes an animation reference
  4. (UI) duplicate a track from one AnimationPlayer to another AnimationPlayer. This requires a UI dialog that lets you select an animation player and then name the nodepath to duplicate the track.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  105Comments

reduz picture reduz  路  111Comments

willnationsdev picture willnationsdev  路  93Comments

RyanBram picture RyanBram  路  101Comments

ghost picture ghost  路  117Comments