Fix finding AnimationPlayer in scene import

The scene importer always assumed that the AnimationPlayer is called
"AnimationPlayer".

This is not always true: for example the GLTF importer just creates an
AnimationPlayer with the default name, which may be "animation_player",
depending on the project settings.

This fix instead chooses the first node that is an AnimationPlayer, and
warns if there is more than one.
This commit is contained in:
Morris Tabor 2022-09-12 17:22:16 +02:00
parent bbd9578d18
commit ae51d5ad33
2 changed files with 27 additions and 16 deletions

View File

@ -629,15 +629,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, bool p_bake_all) {
if (!scene->has_node(String("AnimationPlayer"))) {
AnimationPlayer *anim = _find_animation_player(scene);
if (!anim) {
WARN_PRINT("Creating clips is enabled, but no animation player was found.");
return;
}
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
ERR_FAIL_COND(!anim);
if (!anim->has_animation("default")) {
ERR_FAIL_COND_MSG(p_clips.size() > 0, "To create clips, animations must be named \"default\".");
return;
@ -757,13 +754,10 @@ void ResourceImporterScene::_filter_anim_tracks(Ref<Animation> anim, Set<String>
}
void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
if (!scene->has_node(String("AnimationPlayer"))) {
AnimationPlayer *anim = _find_animation_player(scene);
if (!anim) {
return;
}
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
ERR_FAIL_COND(!anim);
Vector<String> strings = p_text.split("\n");
for (int i = 0; i < strings.size(); i++) {
@ -864,13 +858,10 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
}
void ResourceImporterScene::_optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle) {
if (!scene->has_node(String("AnimationPlayer"))) {
AnimationPlayer *anim = _find_animation_player(scene);
if (!anim) {
return;
}
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
ERR_FAIL_COND(!anim);
List<StringName> anim_names;
anim->get_animation_list(&anim_names);
@ -895,6 +886,24 @@ static String _make_extname(const String &p_str) {
return ext_name;
}
AnimationPlayer *ResourceImporterScene::_find_animation_player(Node *p_node) {
// Find a direct child that is an AnimationPlayer.
AnimationPlayer *ret = nullptr;
for (int i = 0; i < p_node->get_child_count(); i++) {
AnimationPlayer *child = Object::cast_to<AnimationPlayer>(p_node->get_child(i));
if (child) {
if (ret == nullptr) {
ret = child;
} else {
WARN_PRINT("More than one animation player: \"" + ret->get_name() + "\" and \"" + child->get_name() + "\".");
}
}
}
return ret;
}
void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes) {
MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);

View File

@ -32,6 +32,7 @@
#define RESOURCE_IMPORTER_SCENE_H
#include "core/io/resource_importer.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/mesh.h"
#include "scene/resources/shape.h"
@ -144,6 +145,7 @@ public:
virtual int get_import_order() const { return ResourceImporter::IMPORT_ORDER_SCENE; }
void _find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes);
AnimationPlayer *_find_animation_player(Node *p_node);
void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation>> &p_animations, Map<Ref<Material>, Ref<Material>> &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh>> &p_meshes);