hello, I’m trying to save a node branch as scene from a running game. I have node acting as a hexagonal tile map. this node has children nodes which are the tiles. the tiles contain a staticbody3d and a mesh that are scaled on the y axis in relation to simplex noise values through script when the game is ran. My issue is when I try to save the map node instance, the tiles loose their y scaling and all revert to 1. previously I was scaling the tile node directly (and not the staticbody3D and mesh) and was able to have the scaling persist, although it introduced horrible issues in other places. Is there any way to save the map node and have the children retain their individual scaling?
save branch as scene and Child Scaling
- Edited
hymansha95 The engine doesn't like physics bodies scaling or non-uniform scaling of colliders. Instead, directly adjust the size of collision shape resource. You'll need to make this resource local to scene if you have multiple instances of the scene.
Thank you for responding! I think I get what you’re saying. I need to modify the recourses directly, instead of using set_scale() on children once the node is instantiated? Do you have any pointers on how to modify a local to scene resource at runtime?
hymansha95 Let's see your hex scene hierarchy
MapNode contains tons of tiles (4 unique), which are instantiated characterbody3d's, you can see some have walls as children, but the generator takes care of those
there are a total of 4 different tiles, but they are all basically the same, just with a different color. the mesh and shape have both been set local to scene
correct
when i try to save as branch
- Edited
hymansha95 Not sure I understand your setup. What are all those static body scenes and what's inside them? Why your gltf scene has a collider that's not parented do a pyhsics body? Where are the actual colliders you want to scale? Let's also see the scaling code.
- Edited
Sorry about that. Inside my scene there is a node called “MapNode” that is scripted to instantiate hexagonal scenes on _ready()
. These hexagonal scenes are the tiles. They themselves are StaticBody3ds and contain 2 children, a mesh instance (the hexagon shape) and a collisionshape3d that was a single convex collision sibling to the mesh. When the script starts it makes a height map and goes through and instantiates the appropriate tile based on the height, it then scales the mesh and the collisionshape3d of the tile for height effect .
doesn't the gltf scene become a physics-body itself if you change nodetype into staticbody3d?
thank you so much, I hope that makes some sort of sense
`
var children = instantiated_tile.get_children()
for child in children:
var c := child as Node3D
c.set_scale(Vector3(1,
quanitized_noise * smoothing_factor + 1 ,
1))
`
the scale is being applied at runtime by the generator script in the MapNode, when it instantiates a tile scene it scales the children of the scene. i would like to keep the scaling that is applied the the tiles when i save the map from the editor.
hymansha95 Are you saving from the remote tree in the editor at runtime?
xyz yes
hymansha95 What happens if you only scale the mesh instance node?
hymansha95 For each node you're scaling, try to set its owner
property to top node you're saving. Beware though that this will break the apparent instantiation dependency and nodes that changed owner will no longer be "wrapped inside" instantiated scenes.
- Edited
xyz
setting owner worked, thank you!! okay the objects scale is persisting after saving.
However, if i run the saved scene, each tile node has 2 meshes and 2 collision objects.
im not sure what to do about the original mesh and collision object, perhaps instead of instantiating premade tile scenes. i need to build a new one at runtime and just attach premade rescources to it in script.
- Edited
hymansha95 You can make it work if you do set_editable_instance(hex, true)
for each hex scene before you change the scaling of its children. In this case don't touch owner
property at all.
With this you can even make the whole thing work like a tool script fully within the editor.
when i try to do that i get an error
if it helps, here is a github link to the script in question, everything of interest happens around line 96
https://github.com/Cheysha/godot3dtestFixed/blob/main/Scripts/MapGen.gd
- Edited
hymansha95 Add the tile to the scene tree before calling set_editable_instance()
. Best to do it immediately after instantiating so:
- instantiate
- add as child
- set_editable_instance()
- scale children
PERFECT, I would have never have gotten that on my own, its working exactly how I expected, thank you so much, you guys are awesome
hymansha95 Just remember that you still don't want to non-proportionally scale that CollisionShape3D. Try to do in manually in the editor and see what the warning message says.
It gets mad and throws a yellow triangle. It suggest changing the size of the shape resource itself or scaling uniformly. But the shape resource is taken directly from the mesh and If I scale uniformly in all directions the tile will be to big. I only needed to elongate along the y axis so it made sense to me to just scale along y. Is there a better way to do it that I may be missing?
hymansha95 What type of shape it is? Convex Mesh? If it's a hexagonal prism, you can import an elongated one and just move it upwards.
okay, so I think all is good, no more yellow triangles, and scales are good.
I ended up just scaling the mesh and then ran make_convex_from_siblings() on the collisionshape3d. this seems to have worked