Instancing only selected node from scene

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By b2przemo

I instantiate mesh instances from different *.res file under a scene node that contains spatial, rig, skeleton, and a few mesh nodes.
This is how the structure looks locally and remotely.

I used two different versions of instancing but not of them work as expected. I remove one node using ‘RemoveChild’ and try to replace it with meshInstance from another scene.
After preloading and instancing in the usual way meshes are displayed correctly but the whole structure (spatial node, other meshInstacing nodes) is displayed as well (what I don’t need). If I GetNode from the instanced scene and add as AddChild via Duplicate node is attached to correct location (under skeleton) but it’s not displayed. All transform, material, the skin are there, but the mesh is not visible.

I kinda stuck with it. Should I try to go with the first option and try to remove the parent spatial (Hero_hairs), or maybe the second version only needs some method forcing the scene tree to update the visibility of instanced mesh?

but the whole structure (spatial node, other meshInstacing nodes) is displayed as well (what I don’t need)

How it was supposed to hide ? Do You menage its visibility by code ?
What is the final effect of what You want to achieve ?

Inces | 2022-08-18 14:32

Well, I just need one meshInstance from the instanced scene (Hero_hairs). Exactly how is in the bottom image on the right - this meshInstance is attached by code and has the correct location in the hierarchy (directly under Skeleton Node). What actually works is instancing the whole *.tres scene - this is what I do not need (bottom image at left). I try separate each mesh component of the character and create all variants for each part in separate scenes. Don’t want to load the scene with hundreds of meshInstances for one element like a sword for example. I do need only one meshInstance out of hundreds of meshes stored in the scene (like an asset repository).
Adding Child node by calling callDefered work but the mesh is not displayed in viewport, although it has all parameters in the editor after instancing. The same situation occurs where instead of removing the first meshInstance, I do an instance of the scene, get the required mesh parameter from it (meshInstance from tres file), and replace the mesh parameter (in the first mesh) with the script. The first (original mesh) vanishes, in the editor the Mesh is displayed correctly, you see that geometry is changed, but in the viewport, the mesh is not displayed. All parameters like materials, transforms, visibility etc. are correct.

b2przemo | 2022-08-18 15:03

I struggle to understand it :slight_smile:
You just want to isolate one single object from whole asset scene full of objects ?
If this is so, then getting direct reference and duplicating it is a good way to go and it should work. There is no reason for mesh not to be displayed. However You might have unconsequent armature binding for all objects in the asset scene, and it misinteprets its position within the skeleton. Try to check global position of your duplicated mesh, or try to find it with moving camera.

Inces | 2022-08-18 19:19

You just want to isolate one single object from whole asset scene full of objects ?

:slight_smile: Yeah, kind of. The idea is that the main character (rigged model) should be customizable at runtime. So what I’ve try to achieve is to remove some part of meshInstances that exists under the skeleton node (not by toggle visibility - just using RemoveChild) and under the same skeleton instantiate a new mesh that exists in the other scene (*.tres file). This new mesh already has a vertex weightPaint for rig, correct position and correct material attached. And on some level I was able to do it, the meshInstance appears in the outliner in remote view so, it is there, and when I click to select it, all parameters visible at editor exist (material, correct mesh preview -meshArray; correct size, skin) but for some reason is not visible in the viewport.

Sorry for my overcomplicated description, english is not my native :).
need to check my code on the more simple scene without armature and maybe change the code language to GDScript, of course, I will check all these points that You mention, anyway…Thank You for taking Your time.

b2przemo | 2022-08-18 19:49

I was making a very similar project, inventory system that only replaces one meshinstances into other with duplicating parts of global asset scene. It worked perfectly, but I was using direct bone parenting, not weight paint. I remember using bone property, when adding child to a skeleton, I had to specify it back then. Perhaps there is something with the way mesh/skeleton stores weighted points arrays. Still, locating real position of duplicated mesh instance should answer this question.

Inces | 2022-08-18 20:54

OK, I will check this as well. The last thing that I want to do is reconstruct the whole meshArray from the scratch ;( It’s kind of weird that for instancing regular meshInstance under a Spatial Node it works just fine. Only the skeletal meshes behave in that way.
At least now I have some clue where the problem may be.

b2przemo | 2022-08-18 21:10

I was able to figure out what causes the problem. Everything is now working as expected. Basically, if You need to attach meshInstance under the rigged model dynamically You need to have the exact same hierarchical structure under the skeleton in the file where all meshes are and additionally You need to have AnimationPlayer. You may store only one keyframe (in my file its a T-Pose for example). The fetched mesh from the file attached dynamically under the skeleton will play all animations perfectly.

b2przemo | 2022-08-21 19:16

Ok, good job.
What do You mean You can store only one keyframe ? You can import all animations from blender, but You need to “push down” to NonlinearAnimationEditor before export in blender

Inces | 2022-08-22 14:41

yeah, You need to use NLA, without storing one keyframe You won’t be able to get AnimationPlayer node after opening glb in the Godot.
What I did already: I separated models from animations, and from assets that I want to dynamically change.
Basically what I’ve got now is a Hero model (with TPose only as the tscn file), all animations in a separate *.anim file (without meshes - they look exactly like mockup bhv file - You only see animated bones), and swappable meshInstances for each part of the hero model. These instances use a separate *.res file as well. In the bottom image, You should be able to get it more clearly

Now I will be able to separate tasks somehow. Modeling from animations etc… Changing animations and adding new assets also should be easier.

b2przemo | 2022-08-22 15:40