godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.05k stars 65 forks source link

Update AnimationPlayer in real-time when keyframe properties change #9686

Open dnllowe opened 1 week ago

dnllowe commented 1 week ago

Describe the project you are working on

I'm working on a 2D idle / auto rpg battler. There are different animations, weapons, and equipment, and updating various collision boxes in sync with the animations and equipped items is necessary.

Describe the problem or limitation you are having in your project

When animating properties, the AnimationPlayer does not reflect the changes immediately. This leads to guesswork and a tedious back and forth of editing a property, clicking the timeline to see what it looks like, and repeating until it's correct.

Example:

https://github.com/godotengine/godot-proposals/assets/18432482/8f5c469f-7648-4257-b037-c9fe34b91525

I have seen this issue brought up, but no resolution / implementation for it:

https://github.com/godotengine/godot/issues/76606 https://github.com/godotengine/godot/pull/76785 https://github.com/godotengine/godot/issues/91476

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I would like the AnimationPlayer to update in real-time when properties of the selected form change in value. This provides immediate feedback and speeds up the workflow and syncing and adjusting various properties to a sprite's animation.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

  1. When a property of type value is changed in AnimationTrackKeyEdit::_set, I will seek to the current animation position to update the visual representation in the editor in real-time:
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
player->seek(player->get_current_animation_position(), true, true);
  1. When changing keyframes by clicking on the keyframe in the timeline from AnimationTrackEdit::_try_select_at_ui_pos, the timeline will move to that position to immediately show how the state of the animation looks at that keyframe. I know it's possible to move the track from above, but a more natural workflow is to click on the keyframe I want to edit, and then I will want to see how everything looks at that moment in time:
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
player->seek(moving_selection_pivot, true, true);
emit_signal(SNAME("timeline_changed"), moving_selection_pivot, false);

The resulting behavior is now:

https://github.com/godotengine/godot-proposals/assets/18432482/8fee45a0-df7c-4b49-9e1f-80c0e6b37cec

I have a branch with the changes ready here: https://github.com/godotengine/godot/compare/master...dnllowe:godot:realtime-animation-player-property-updates?expand=1

If this enhancement will not be used often, can it be worked around with a few lines of script?

I think this will be used commonly by anyone using the AnimationPlayer

Is there a reason why this should be core and not an add-on in the asset library?

The AnimationPlayer and its behavior is core to the engine.

Calinou commented 1 week ago

This makes a lot of sense. I've been wanting this for a while, but wasn't sure if there were some use cases where this would be counterproductive – I can't think of any right now.

dnllowe commented 1 week ago

This makes a lot of sense. I've been wanting this for a while, but wasn't sure if there were some use cases where this would be counterproductive – I can't think of any right now.

I wondered if there could have been a negative performance impact, but I didn't notice any. Otherwise, having worked with other engines and similar features in video and audio software, it felt very natural to have this behavior by default.