Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement AnimationMixer as a base class of AnimationPlayer and AnimationTree #80813

Merged
merged 1 commit into from
Sep 29, 2023

Conversation

TokageItLab
Copy link
Member

@TokageItLab TokageItLab commented Aug 20, 2023

Implement godotengine/godot-proposals#5972.

Currently AnimationPlayer and AnimationTree have separate duplicate implementations of playback and blending, so implement the base class to unify them.

Internally, this is a major change, but most compatibility will be kept.

However, Changes to conflicting method and property names between AnimationPlayer and AnimationTree are unavoidable, since retaining only one of them will destroy compatibility with the other.

  • AnimationPlayer.playback_active
  • AnimationTree.active
    • -> AnimationMixer.active (but not change the setter/getter method since AnimationPlayer has already have the AnimationPlayer.set_active() as setter of AnimationPlayer.playback_active)
  • AnimationPlayer.playback_process_mode
  • AnimationTree.process_callback
    • -> AnimationMixer.callback_mode_process
  • AnimationPlayer.method_call_mode
    • -> AnimationMixer.callback_mode_method (to follow above change to make group in the inspector)

Note: Old methods and property names will be kept for compatibility.

image

This change allows AnimationTree to have an AnimationLibrary. Also, when an AnimationTree is selected, a dummy AnimationPlayer is added to the editor internally.

image

If the AnimationTree specifies an AnimationPlayer, the dummy AnimationPlayer's resources will be referenced specified AnimationPlayer (make them read-only in AnimationTree).

image

Todo:


@TokageItLab TokageItLab added this to the 4.x milestone Aug 20, 2023
@TokageItLab TokageItLab changed the title Implement AnimationManager as base class of AnimationPlayer and AnimationTree Implement AnimationManager as a base class of AnimationPlayer and AnimationTree Aug 20, 2023
@TokageItLab TokageItLab force-pushed the rework-animation-manager branch 3 times, most recently from 009814c to ad35ee2 Compare August 20, 2023 11:16
@TokageItLab
Copy link
Member Author

TokageItLab commented Aug 20, 2023

For compatibility, the old setters and getters have been added. It means that some internal properties will have two property names, setters and getters.

@reduz has rejected this and suggested implementing separate property names, setters and getters for AnimationPlayer and AnimationTree, but I disagree strongly with that.

It makes the result in missing properties during interconversion between AnimationPlayer and AnimationTree. This causes problems with the "Change type" option of the SceneTreeDock and the creation of the DummyPlayer (these use set(prop.name, prop.value) iteratively). So we must have at least one shared property name.

For that, @reduz suggested putting an option in AnimationPlayerEditor, but honestly it's confusing and there is no need to ignore SceneTreeDock.

Having two property names, setters and getters is certainly redundant, but I argue that redundancy is far better than going the inconvenient way and having a method that only those who have read the manuals can understand.

Edited:
On Rocket chat we agreed on redundancy for this case.

@YuriSizov
Copy link
Contributor

YuriSizov commented Sep 5, 2023

Just to be clear, this is still a breaking compatibility change because the inheritance chain is modified. This may or may not be an issue for 3rd party language bindings. And we may or may not accept it as allowed.

@RandomShaper
Copy link
Member

Unless it changed after I implemented it, reset-on-save would only work in AnimationPlayers having a reset animation. Without such an animation, the feature is no-op.

The problem with onion skinning is that it works like this:

  • Save all current values for every track and the current position (time).
  • For every step, seek to the relevant time, render and take screenshot.
  • Seek back to the original position and restore the backup.

It didn't require a reset animation, nor it it fitting for this purpose the way I envisioned it, because the current values in the animated properties may not even be the ones in the animation. For instance, say you have a Node2D animated such as its X position moves from 0 to 100 in some track. The current animation at the current time sets position to 50. The user drags the node manually to 15 and then enables onion skinning. After all the process involved (done on every frame), the user wants to still see the position is 15. The fact that seeking the AnimationPlayer is being used under the hood to capture the onion layers is kept hidden and unnoticed to the user.

With the reset animation there are a couple of downsides:

  1. Well, you need to have a proper reset animation involving all the values that you want to behave correctly in the onion layers.
  2. The onion skinning internal machinery is no longer hidden, since, the second you enable it, properties the user may have modified manually will be reset to the values mandated by the animation.

Neither is the end of the world, and I think that is good enough to bring onion skinning back to life. However, as I said, I'd like it to work as transparently (no pun intended) as it used to do in a future iteration.

@TokageItLab TokageItLab deleted the rework-animation-manager branch February 14, 2024 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment