Merge pull request #79774 from aaronfranke/scene-import-root-type-name

Improve overriding the root type or root name in the scene importer
This commit is contained in:
Rémi Verschelde 2023-08-02 12:19:34 +02:00
commit f5b2d7d393
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 35 additions and 31 deletions

View File

@ -48,16 +48,16 @@
[b]Note:[/b] Only effective if [member meshes/light_baking] is set to [b]Static Lightmaps[/b].
</member>
<member name="nodes/apply_root_scale" type="bool" setter="" getter="" default="true">
If [code]true[/code], [member nodes/root_scale] will be applied on the meshes and animations directly, while keeping the root node's scale to the default [code](1, 1, 1)[/code]. This means that if you add a child node later on within the imported scene, it won't be scaled. If disabled, [member nodes/root_scale] will multiply the scale of the root node instead.
If [code]true[/code], [member nodes/root_scale] will be applied to the descendant nodes, meshes, animations, bones, etc. This means that if you add a child node later on within the imported scene, it won't be scaled. If [code]false[/code], [member nodes/root_scale] will multiply the scale of the root node instead.
</member>
<member name="nodes/root_name" type="String" setter="" getter="" default="&quot;Scene Root&quot;">
The name of the root node in the imported scene. This is generally not noticeable when instancing the scene in the editor (or drag-and-dropping from the FileSystem dock), as the root node is renamed to match the filename in this case.
<member name="nodes/root_name" type="String" setter="" getter="" default="&quot;&quot;">
Override for the root node name. If empty, the root node will use what the scene specifies, or the file name if the scene does not specify a root name.
</member>
<member name="nodes/root_scale" type="float" setter="" getter="" default="1.0">
The scale of meshes and animations (if [member nodes/apply_root_scale] is [code]true[/code]), or the scale of the root node in the imported scene (if [member nodes/apply_root_scale] is [code]false[/code]).
The uniform scale to use for the scene root. The default value of [code]1.0[/code] will not perform any rescaling. See [member nodes/apply_root_scale] for details of how this scale is applied.
</member>
<member name="nodes/root_type" type="String" setter="" getter="" default="&quot;Node3D&quot;">
The node type to use as a root node. Using node types that inherit from [Node3D] is recommended. Otherwise, you'll lose the ability to position the node directly in the 3D editor.
<member name="nodes/root_type" type="String" setter="" getter="" default="&quot;&quot;">
Override for the root node type. If empty, the root node will use what the scene specifies, or [Node3D] if the scene does not specify a root type. Using a node type that inherits from [Node3D] is recommended. Otherwise, you'll lose the ability to position the node directly in the 3D editor.
</member>
<member name="skins/use_named_skins" type="bool" setter="" getter="" default="true">
If checked, use named [Skin]s for animation. The [MeshInstance3D] node contains 3 properties of relevance here: a skeleton [NodePath] pointing to the [Skeleton3D] node (usually [code]..[/code]), a mesh, and a skin:

View File

@ -1869,8 +1869,8 @@ bool ResourceImporterScene::get_internal_option_update_view_required(InternalImp
}
void ResourceImporterScene::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Node3D"));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "Scene Root"));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), ""));
List<String> script_extentions;
ResourceLoader::get_recognized_extensions_for_type("Script", &script_extentions);
@ -2438,32 +2438,36 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
_post_fix_animations(scene, scene, node_data, animation_data, fps);
String root_type = p_options["nodes/root_type"];
root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class.
Ref<Script> root_script = nullptr;
if (ScriptServer::is_global_class(root_type)) {
root_script = ResourceLoader::load(ScriptServer::get_global_class_path(root_type));
root_type = ScriptServer::get_global_class_base(root_type);
}
if (root_type != "Node3D") {
Node *base_node = Object::cast_to<Node>(ClassDB::instantiate(root_type));
if (base_node) {
scene->replace_by(base_node);
scene->set_owner(nullptr);
memdelete(scene);
scene = base_node;
if (!root_type.is_empty()) {
root_type = root_type.split(" ")[0]; // Full root_type is "ClassName (filename.gd)" for a script global class.
Ref<Script> root_script = nullptr;
if (ScriptServer::is_global_class(root_type)) {
root_script = ResourceLoader::load(ScriptServer::get_global_class_path(root_type));
root_type = ScriptServer::get_global_class_base(root_type);
}
if (scene->get_class_name() != root_type) {
// If the user specified a Godot node type that does not match
// what the scene import gave us, replace the root node.
Node *base_node = Object::cast_to<Node>(ClassDB::instantiate(root_type));
if (base_node) {
scene->replace_by(base_node);
scene->set_owner(nullptr);
memdelete(scene);
scene = base_node;
}
}
if (root_script.is_valid()) {
scene->set_script(Variant(root_script));
}
}
if (root_script.is_valid()) {
scene->set_script(Variant(root_script));
}
if (p_options["nodes/root_name"] != "Scene Root") {
scene->set_name(p_options["nodes/root_name"]);
} else {
String root_name = p_options["nodes/root_name"];
if (!root_name.is_empty() && root_name != "Scene Root") {
// TODO: Remove `&& root_name != "Scene Root"` for Godot 5.0.
// For backwards compatibility with existing .import files,
// treat "Scene Root" as having no root name override.
scene->set_name(root_name);
} else if (String(scene->get_name()).is_empty()) {
scene->set_name(p_save_path.get_file().get_basename());
}