Open GuilhermeGSousa opened 3 weeks ago
Are you working on this openly?
I am! I am starting to learn that the only way to do it on Godot's latest version is through a custom module, the GDExtension bindings aren't in a place where extending a AnimationRootNode
is doable (and probably won't be until structs are in the engine). The way I see it right now we either:
AnimationRootNode
s is supported by the engine.I'm curious to know what you think!
I've done this before with a different project. This is a practical way of implementing motion matching.
https://github.com/V-Sekai/godot/tree/vsk-motion-matching-4.3/modules/motion_matching
https://github.com/V-Sekai/motion_matching
Note the project is archived.
I use https://github.com/ingydotnet/git-subrepo to import a standalone git repo into a branch of godot engine.
This is perfect, making a submodule out of a directory of this repo is just what I need, I'll set that up. This repo has a working motion matching implementation, but I now think the correct way of doing it for a 1.0 version is to have motion matching queries run on animation nodes. The two big advantages of this approach imo:
I saw V-Sekai and Remi's motion matching implementation, I also had the chance to discuss this with him!
My dream for when we get the basic implementation is to also implement https://peizhuoli.github.io/walkthedog/index.html
You may have missed the branch for module https://github.com/V-Sekai/motion_matching/tree/module
Are you on discord? I exceeded my friend limit of 1000 so if we want to talk it'll have to be the V-Sekai discord here.
I am! I'll ping you on discord
Just joined the discord!
@fire
https://github.com/GuilhermeGSousa/godot-motion-matching/issues/41#issuecomment-2436441892 It is important to respect where the codes come from
https://github.com/V-Sekai/godot/tree/vsk-motion-matching-4.3/modules/motion_matching is basically copy from Remi without clearly acknowledging.
https://github.com/V-Sekai/motion_matching is simply clearly stating that it is a fork.
Both links provided come from one same source. One is a fork, One is copying without acknowledging.
In both cases, there are no evidence that the CI works.
This ethical in respecting others contribution is critical in Godot community project and the foundation of trust-worthiness collaboration.
The code vsk-motion-matching-4.3/modules/motion_matching/LICENSE clearly acknowledges Remi.
@fire
I appreciate your enthusiasm:
I want to trust your enthusiasm I know your strengths : Please make sure your codes are CI working before recommending merger.
When I work with Malcolm This is what I learned from him
The primary HEAD of development is https://github.com/GuilhermeGSousa/godot-motion-matching/tree/engine-module.
The cicd for the branch is failing https://github.com/GuilhermeGSousa/godot-motion-matching/pull/42
So that's what I'm working on.
@fire
Yes, please help this project to get the CI working in reliable way
I know you have a lot of experience in this area.
The community depends on you :-)
Notes from トカゲ
To explain the fundamental design, AnimationTree does not have a process for playing back animations; AnimationNodeAnimation does all the work for playback
AnimationNodeAnimation generates/stores a timeline from the length of each animation, manages the playback position, and passes it to the AnimationMixer.
So, if you do not want to write such playback position management from scratch, you should refer to AnimationNodeTransition or AnimationBlendSpace2D, which blend multiple AnimationNodeAnimation AnimationNode.
There you don't need to manage the playback position, just seek instructions and blend amount adjustments to the AnimationNodes connected as a result of the matching
I have marked all non motion-matching node discussions as offtopic.
https://github.com/GuilhermeGSousa/godot-motion-matching/issues/41#issuecomment-2436441892
This is the cause of triggering off topic ...do learn the truth will always prevail
トカゲ — Today at 18:22
There is no API to directly transition keyframes from AnimationA to AnimationB. Although you can pass weight information to the AnimationPlaybackInfo passed to AnimationMixer::make_animation_instance to blend the results of AnimationA and AnimationB by 0.5
make_animation_instance() is the essential playback API of AnimationMixer, which extracts the values at a given frame of a given animation resource and stacks them for blending.
In AnimationNodes, only AnimationNodeAnimation calls make_animation_instance() as blend_animation(), while upstream API such as AnimationNodeBlend2 only passes weight information to AnimationNodeAnimation. The weight information in the PlaybackInfo includes the overall animation weight weight and the track_weights per track, and the AnimationTree blend probably computes the track_weights mainly
The blend_animation() method exposed in GDScript lacks a way to specify track_weights and start/end parameters, which is why it is not available in GDScript anyway; The struct PlaybackInfo passed upstream has track_weights information that must be passed to blend_animation(), but due to a missing struct, track_weights can neither be retrieved nor passed in GDScript/GDExtention. Also, make_animation_instance() cannot be exposed now, because it requires a struct argument as well
In summary, AnimationNode::_process() has a p_playback_info argument that contains weight information, which can be passed to blend_animation() to play the animation.In other words, multiple calls to blend_animation() will blend multiple animations. However, there is no time information. Time information must be managed by each AnimationNode individually. In this situation, it is sufficient for an AnimationNode to have a single NodeTimeInfo. For this reason, in Godot's AnimationTree, one AnimationNodeAnimation calls only one blend_animation().
If you want to manage the time of multiple animations in one AnimationNode, it means you need multiple NodeTimeInfo, so you need to write a full-scratch struct or something to manage the time information. Therefore, I recommended having an internal AnimationNodeAnimation for each Animation like BlendSpace2D, and managing only its seek and weight in motion matching.
As the API for motion matching evolves, its becoming clear that motion matching should be implemented as an
AnimationRootNode
, that receives its query inputs as a parameter. As I see it, the advantages to this would be:There are some changes required at the engine level to be able to do this:
_process
method ofAnimationRootNode
is currently marked as deprecated, and a supported version of that might only be coming when structs are available in the engine (see this thread)