Skip to content

Allow multithreading for AnimationPlayer #12759

Open
@jitspoe

Description

@jitspoe

Describe the project you are working on

Retro FPS with lots of enemies.

Describe the problem or limitation you are having in your project

Having 100+ enemies animated in a scene causes huge performance hits.

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

In order to reduce the framerate hit, I staggered the animation updates and manually called anim_player.advance(), but even just updating like 10 enemies per frame, I can see there's a good amount of time spent in AnimationPlayer::_process_animation and AnimationPlayer::_blend_process. These could potentially be optimized, but also seem like a good candidate for multithreading since each model is going to be independently animating.

I tried calling advance() from a thread, but got errors:
E 0:01:14:421 animation_system.gd:78 @ update_anim(): Caller thread can't call this function in this node (/root/MainScene/ContainingNode/Sewer1/@CharacterBody3D@242/MitemareMesh/AnimationPlayer). Use call_deferred() or call_thread_group() instead.
<C++ Error> Condition "!is_accessible_from_caller_thread()" is true. Returning: (nullptr)
<C++ Source> scene\main\node.cpp:1807 @ Node::get_node_or_null()
animation_system.gd:78 @ update_anim()
E 0:01:14:421 animation_system.gd:78 @ update_anim(): No animation in cache.
<C++ Error> Condition "!animation_track_num_to_track_cache.has(a)" is true. Continuing.
<C++ Source> scene\animation\animation_mixer.cpp:1147 @ AnimationMixer::_blend_calc_total_weight()
animation_system.gd:78 @ update_anim()

Using call_deferred() defeats the purpose, as that would just make the animation processing happen in the main thread, and I'm not sure what call_thread_group() is. Possibly a typo or removed function? Doesn't seem to exist anywhere.

I tried calling set_thread_safety_checks_enabled(false) on the threads, but that didn't seem to do anything.

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

Not too familiar with the threading stuff under the hood, but effectively what I'm suggested would be to disable the safety checks on certain nodes to allow multithreaded logic.

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

Can't even multithread the animation updates from script at all, as far as I can tell.

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

Animation is a core feature.

Related issues:
#4962 (Add threading support to Scene Nodes in general)
godotengine/godot#90943 (Poor animation performance)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions