-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Unable to assign Skeleton with Import Script #95461
Comments
The FBX code should be changed instead to accept a missing Changing the way ConfigFile behaves would break compat. |
@lyuma Could look into this. |
impeded by godot bug godotengine/godot#95461
So there are two things going on here: One is that there's a stray null in the .import file. I have a PR which should fix this, but the null doesn't do anything and so this is a purely cosmetic fix: I don't think this issue is a release blocker. The second problem relates to the discussion from #95413, where I advised use of ConfigFile (typoed as ConfigMap) for modifying the .import file. The issue is that the config file likely will be overwritten after the import finishes, and hence it is not possible to modify the .import from within a PostImport script (or PostImportPlugin) in the way the MRP is doing. Unfortunately I'm not aware of a clean way to do what that MRP is trying to do. In my code, I run a script which modifies the .import files specifically when an import is not currently happening, then trigger a reimport after. There's definitely a big API gap here. I don't have a suggestion on how to fix the MRP to work correctly, but the closest thing I can think to suggest is run the code outside the import (perhaps in a call_deferred) and then run reimport_files on EditorFileSystem. Make sure to avoid an infinite loop, since the reimport_files will run the script again. |
Thank you Lyuma. yeah, ok....doing it outside of the import process kind of defeats the point. I was trying to automate all necessary configurations and modifications to an animation library during the import process because this stuff gets written to the res file in the .godot/import folder, the setting the bones up was the last piece of this particular puzzle to fully automate it. EDIT: Another thought, I wonder if I could run a tool script that will set the import script up prior to import? Then I could just trigger an import and the skeleton could already be in place before that happens. EDIT2: OK, that checks out ... I replicated that workflow manually by cutting the import script configuration item and the _subresources configuration with an external text editor, saving the file, then letting godot reimport and resetting those 2 settings back to default. Then, I pasted those lines back in to the file from the external text editor, saved the file, and triggered another import....Godot set the skeleton and ran the import script with intended results. Very kludgy, but it works for now, so thanks |
Yeah I agree the usecase of changing settings during import makes sense. I'll try and see if there's a way we can improve the APIs in 4.4 to account for this. Though either way, In my opinion, |
Hi Lyuma, Thanks, |
> This is something I hope to make possible in 4.4
Been fighting with stress and I haven't gotten anywhere near progressing on my ambitious priorities that I put down for 4.4 (I work on Godot as a volunteer).
If you want to increase the chance that I make this before the 4.4 feature freeze, could you propose some ideas for your dream API to change .import options during import? Like an extra function in post import plugin? Having some direction would help me focus.
|
Lyuma, sorry you are dealing with stress. That really sucks, thank you for what you are able to accomplish. Being the lead dev (whether in name or action) on a section of the engine I am sure has a cost to you. Really the most important thing to me is the ability to assign a skeleton from script. The way it is now, I have to manually import the asset (model or animation), assign the skeleton through the UI, reimport, and THEN assign the import script and reimport again. Best case be ability to import through script only BUT It would already be much better if I could simply assign the skeleton within the script so I don't have so many manual operations per asset (i.e. import, assign script, reimport (3 ops) vs. import, open, assign skeleton, reimport, assign script, reimport (6 ops). That alone would cut the work of importing thousands of assets in half. Thank you for all the hard work you do. |
From reading the Godot code, I did find out that you can actually call You do need to be careful of course when modifying such settings, and having the user go through this instead of having a convenient API will reduce the chance that someone does this unintentionally and makes a mistake, so I would be curious if this gets you unstuck. That said, I came here to see if I could improve Godot's APIs. So the two things I'm trying to decide between are:
I do worry there is more of a stylistic reason not to do this: it feels a bit late to modify import options, while the file is already in the process of being imported, particularly the global options since many of them take effect before even the
But if you want to set a setting like Anyway, maybe I'm just making an excuse to not work on this API for 4.4. But I am really curious if the EditorScenePostImportPlugin idea I had with _subresources works for you, since that would solve most of the problems: extends EditorScenePostImportPlugin
func _pre_process(scene: Node):
subresources = get_option_value("_subresources")
if not subresources.has("nodes"):
subresources["nodes"] = {}
var bone_map : BoneMap = load("res://explosive_bone_map.tres")
# Possibly do some recursive search on scene to determine the actual Skeleton3D node. Sometimes it is not inside Armature.
node_path = "Armature/Skeleton3D"
if not subresources["nodes"].has("PATH:" + node_path):
subresources["nodes"]["PATH:" + node_path] = {}
# Set it in the if statement to allow the user to override after the first import.
subresources["nodes"]["PATH:" + node_path]["retarget/bone_map"] = bone_map Ooh I think I see the problem... resource_importer_scene.cpp pre-caches the nodes dictionary and fails if it was not assigned to begin with... Dictionary subresources = p_options["_subresources"];
Dictionary node_data;
if (subresources.has("nodes")) {
node_data = subresources["nodes"];
}
Dictionary material_data;
if (subresources.has("materials")) {
material_data = subresources["materials"];
}
Dictionary animation_data;
if (subresources.has("animations")) {
animation_data = subresources["animations"];
}
Dictionary mesh_data;
if (subresources.has("meshes")) {
mesh_data = subresources["meshes"];
} I think we should simply move these if statements after the _pre_process function, and that's something I should be able to change for Godot 4.4 |
Hi Lyuma, I will look into the suggestions you made, I was kinda waiting to see what might happen first. Give me a little bit of time though, because I am working on a new workflow and I am still in Blender, and not yet to the Godot Import phase with this assets. Happy Holidays !!! |
Tested versions
System information
Godot v4.3.rc3.mono - Linux Mint 22 (Wilma) - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4060 Ti (nvidia; 535.183.01) - AMD Ryzen 7 5700X 8-Core Processor (16 Threads)
Issue description
The ConfigFile class set_value method erases key/value pair when value is set to null (this is per class docs for ConfigFile.set_value). However, some files such as .glb.import files have required keys stored with explicit values for some options.
There is already the method erase_section() and erase_section_key(), and we need the ability to write null values to key/value pairs.
Example for when we need to be able to write an explicit null:
If this value is not set, then the entire PATH:Armature/Skeleton3D node is over written by the engine on the next import.
Thus an entry to set skeleton ex. {"nodes" : {"PATH:Armature/Skeleton3D": {"retarget/bone_map": Resource("res://bone_map.tres")}}} will also be erased and unset.
To justification that a change is needed:
If one copies and pastes a correct but partial entry, the editor will erase the incomplete entry upon next import...example:
becomes:
_subresources={}
If one copies and pastes the complete correct node entry with the required null value, the editor is fine. example:
Therefore one must conclude that the Class used to read and write configuration files such as .import files, should be able to write key/value pairs that include explicit null values.
There is already the method erase_section() and erase_section_key(), and we need the ability to write null values to key/value pairs.
Steps to reproduce
Minimal reproduction project (MRP)
Animation Test.zip
EDIT: I said FBX by mistake up above, I corrected that to GLB....I am not sure if that's important or not...I would expect the import file behavior to be the same for either.
The text was updated successfully, but these errors were encountered: