I have had trouble getting 3d models from blender (.glb) to offset within a gridmap cell.
As in roof tiles aligned to the top of a cell, floor tiles aligned to the bottom of a cell, or anything inbetween.
Changing the origin in blender does not seem to affect this.
I did uncheck the "Center Y" option in the Cell property of the Gridmap node.
Also dragging models into a scene, selecting them all and clicking Scene -> Convert to... -> Meshlibrary... does not always seem to work that well.
I imported the models (made in Blender and exported with a .glb extension) and created a new inherited scene from it.
This new inherited scene I then saved in a folder called Assets.
My solution was to make a simple script that would generate the meshlibrary for me, and change offset if needed.
A new scene (MeshLibraryMaker.tscn) is made with only a spatial node, to which this script (MeshLibraryMaker.gd) is attached.
It succesfully adds the models to a meshlibrary.
The offset also works, but makes the texture dissapear. (texture was added in Blender and came with the exported model)
If you run this scene (MeshLibraryMaker.tscn) a few times in a row it bugs out and rearranges items in the meshlibrary randomly, and sometimes swaps models, or copies one model to use for all items, or makes items dissapear.
If this happens restart Godot and it should work again.
With my limited knowledge of both Godot and programming this is where i am now, and cant get any further.
Can you identify where the script goes wrong? Or have any tips on how to refactor this script?
extends Spatial
var lib = MeshLibrary.new()
func _ready():
#Manually add items for the meshLibrary here
addToMeshLib("res://Assets/FloorTile03.tscn", 0.5)
addToMeshLib("res://Assets/PedestalTile02.tscn")
ResourceSaver.save("res://Tools/newMeshLib.meshlib", lib)
func addToMeshLib(path, offsetY := 0.0):
var ID = lib.get_last_unused_item_id()
lib.create_item(ID)
var mesh = extractMesh(path)
if offsetY != 0:
mesh = applyOffsetY(mesh, offsetY)
lib.set_item_mesh(ID, mesh)
var name = extractName(path)
lib.set_item_name(ID, name)
func extractMesh(path) -> Mesh:
var mesh
var source = load(path)
var instance = source.instance()
var arr = instance.get_children()
for n in arr:
if n.get_class() == "MeshInstance":
mesh = n.mesh
break
return mesh
func extractName(path: String) -> String:
var name = path
if name.ends_with(".tscn"):
name.erase(name.length() - 5, 5)
name.erase(0, name.find_last("/") + 1)
return name
func applyOffsetY(mesh, offset):
var newArrayMesh = ArrayMesh.new()
newArrayMesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, mesh.surface_get_arrays(0))
var mdt = MeshDataTool.new()
mdt.create_from_surface(newArrayMesh, 0)
for i in range(mdt.get_vertex_count()):
var vertex = mdt.get_vertex(i)
vertex = vertex + Vector3(0,offset,0)
mdt.set_vertex(i, vertex)
var vertex2 = mdt.get_vertex_normal(i)
vertex2 = vertex2 + Vector3(0,offset,0)
mdt.set_vertex_normal(i, vertex2)
newArrayMesh.surface_remove(0)
mdt.commit_to_surface(newArrayMesh)
return newArrayMesh