Skip to content

Instantly share code, notes, and snippets.

@AndreaCatania
Last active July 12, 2021 14:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndreaCatania/afd01671e35e9d004d1d7a498fc0e2a3 to your computer and use it in GitHub Desktop.
Save AndreaCatania/afd01671e35e9d004d1d7a498fc0e2a3 to your computer and use it in GitHub Desktop.
Godot 4 automated material assigner
## License MIT
##
## This Post Import script automatically assign the
## material to the Mesh if it's found inside the
## `res://materials` directory.
##
## # How to use
## To you use it, you need to set this script as Post Import script
## on the file.fbx or file.glb.
##
## Your `materials` directory can look like:
## res://materials/iron_mat.material
## res://materials/glass_mat.tres
## res://materials/my_asset_kit_1/abc_mat.material
## res://materials/my_asset_kit_1/asd_mat.tres
@tool
extends EditorScenePostImport
func post_import(scene):
## Process the scene
apply_global_material(scene)
return scene
func apply_global_material(node):
if node == null:
return
if node is MeshInstance3D:
for i in range(node.mesh.get_surface_count()):
# Extract the material name
var material_name = node.mesh.get("surface_" + str(i + 1) + "/name")
var mat = search_material(material_name)
if mat != null:
node.mesh.surface_set_material(i, mat)
print("Global material set for: ", material_name, " ", mat)
for child in node.get_children():
apply_global_material(child)
var materials: Dictionary = {}
func search_material(material_name, base_dir = "res://materials") -> Material:
if materials.has(material_name):
return materials[material_name]
return _search_material(material_name)
func _search_material(material_name, base_dir = "res://materials") -> Material:
var dir = Directory.new()
if dir.open(base_dir) == OK:
# Search the file inside this directory
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir() == false:
if file_name == material_name + ".tres" or file_name == material_name + ".material":
var mat: Material = load(base_dir + "/" + file_name)
if mat != null:
# This material is valid, cache it since it's likely it's reused.
materials[material_name] = mat
print("Material found: ", material_name, " in path: ", base_dir + "/" + file_name)
return mat
else:
print("IMPORT ERROR: The material ", material_name, " is found, bu it's not valid material.")
file_name = dir.get_next()
dir.list_dir_end()
# Search inside sub dirs now
dir.list_dir_begin()
file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir() and file_name != "." and file_name != "..":
var mat = _search_material(material_name, base_dir + "/" + file_name)
if mat != null:
return mat
file_name = dir.get_next()
dir.list_dir_end()
# Nothing found
return null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment