Last active
October 6, 2020 18:07
-
-
Save PranavSK/1cea39344bd830196b5372bf6be0cdfd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tool | |
extends EditorScript | |
const UE4_ASSETS_PATH: = "res://prefabs" | |
const UE4_ASSET_EXT: = "FBX" | |
const MATERIALS_STORE_PATH: = "res://materials" | |
const MATERIALS_STORE_EXT: = "tres" | |
const SCENE_STORE_PATH: = "res://prefabs" | |
const SCENE_STORE_EXT: = "tscn" | |
const STATIC_MESH_PREFIX: = "SM" | |
const SKELETAL_MESH_PREFIX: = "SK" | |
const COLLISION_MESH_PREFIX: = "UCX" | |
const DIR_ACCESS_ERROR: = "An error occurred when trying to access the path." | |
var _materials_db: = {} | |
func _run(): | |
_init_materials_db() | |
var dir = Directory.new() | |
if dir.open(UE4_ASSETS_PATH) != OK: | |
push_error(DIR_ACCESS_ERROR) | |
return | |
dir.list_dir_begin(true, false) | |
print("Processing UE4 assets in %s" % UE4_ASSETS_PATH) | |
_process_assets_dir(dir, UE4_ASSET_EXT, funcref(self, "_process_asset_path")) | |
func _init_materials_db() -> void: | |
print("Initializing Materials Database from %s" % MATERIALS_STORE_PATH) | |
var material_dir = Directory.new() | |
if material_dir.open(MATERIALS_STORE_PATH) != OK: | |
push_error(DIR_ACCESS_ERROR) | |
return | |
material_dir.list_dir_begin(true, false) | |
_process_assets_dir(material_dir, MATERIALS_STORE_EXT, funcref(self, "_init_material")) | |
func _init_material(path: String): | |
var mat = load(path) | |
if not mat and not mat is Material: | |
push_error("Expected Material at path %s" % path) | |
return | |
if not _materials_db.has(mat.resource_name): | |
print("Loaded material: %s" % path) | |
_materials_db[mat.resource_name] = mat | |
func _process_assets_dir(dir: Directory, asset_ext: String, process_func: FuncRef) -> void: | |
var file_name = dir.get_next() | |
while (file_name != ""): | |
var path = dir.get_current_dir() + "/" + file_name | |
if dir.current_is_dir(): | |
var subDir = Directory.new() | |
if subDir.open(path) != OK: | |
push_error(DIR_ACCESS_ERROR) | |
return | |
subDir.list_dir_begin(true, false) | |
print("Processing sub dir: %s" % path) | |
_process_assets_dir(subDir, asset_ext, process_func) | |
elif path.get_extension() == asset_ext: | |
print("Found file: %s" % path) | |
process_func.call_func(path) | |
# else: | |
# print("File %s is disregarded" % path) | |
file_name = dir.get_next() | |
func _process_asset_path(path: String) ->void: | |
var asset = load(path).instance() | |
var updated_asset = _ue4_to_godot(asset) | |
var packed_asset = PackedScene.new() | |
packed_asset.pack(updated_asset) | |
var scene_save_path = path.get_basename().replace(UE4_ASSETS_PATH, SCENE_STORE_PATH) + "." + SCENE_STORE_EXT | |
var dir_path = path.get_base_dir() | |
var dir = Directory.new() | |
if not dir.dir_exists(dir_path): | |
dir.make_dir_recursive(dir_path) | |
print("Saving Scene: %s" % scene_save_path) | |
ResourceSaver.save(scene_save_path, packed_asset) | |
func _ue4_to_godot(scene: Spatial) -> Spatial: | |
match scene.name.rsplit("_", 1)[0]: | |
STATIC_MESH_PREFIX: | |
return _fix_static_root(scene) | |
SKELETAL_MESH_PREFIX: | |
return _fix_skeletal_root(scene) | |
_: | |
return scene | |
func _fix_static_root(node: Spatial) -> Spatial: | |
var is_root_static_body = false | |
for child in node.get_children(): | |
if child.name.rsplit("_", 1)[0] == COLLISION_MESH_PREFIX: | |
node.remove_child(child) | |
var new_child = CollisionShape.new() | |
new_child.shape = child.mesh.create_convex_shape() | |
new_child.transform = child.transform | |
new_child.visible = child.visible | |
node.add_child(new_child) | |
new_child.set_owner(node) | |
child = new_child | |
is_root_static_body = true | |
if child is MeshInstance: | |
child.skeleton = "" | |
_update_mesh_material(child) | |
child.rotate_x(deg2rad(-90)) | |
if is_root_static_body: | |
var body = StaticBody.new() | |
body.name = node.name | |
body.transform = node.transform | |
body.visible = node.visible | |
for child in node.get_children(): | |
node.remove_child(child) | |
body.add_child(child) | |
child.set_owner(body) | |
return body | |
return node | |
func _fix_skeletal_root(node: Spatial) -> Spatial: | |
var skel = node.get_child(0) | |
for child in skel.get_children(): | |
if child is MeshInstance: | |
_update_mesh_material(child) | |
child.rotate_x(deg2rad(-90)) | |
return node | |
func _update_mesh_material(node: MeshInstance) -> void: | |
for i in node.get_surface_material_count(): | |
if node.get_surface_material(i): | |
var material_name = node.get_surface_material(i).resource_name | |
if not _materials_db.has(material_name): | |
_update_material_db(node.get_surface_material(i).duplicate(true)) | |
node.set_surface_material(i, _materials_db[material_name]) | |
if node.mesh.surface_get_material(i): | |
var material_name = node.mesh.surface_get_material(i).resource_name | |
if not _materials_db.has(material_name): | |
_update_material_db(node.mesh.surface_get_material(i).duplicate(true)) | |
node.mesh.surface_set_material(i, _materials_db[material_name]) | |
func _update_material_db(material: Material): | |
var mat_save_path = MATERIALS_STORE_PATH + "/" + material.resource_name + "." + MATERIALS_STORE_EXT | |
var dir_path = mat_save_path.get_base_dir() | |
var dir = Directory.new() | |
if not dir.dir_exists(dir_path): | |
dir.make_dir_recursive(dir_path) | |
print("Saving Material: %s" % mat_save_path) | |
ResourceSaver.save(mat_save_path, material) | |
_materials_db[material.resource_name] = load(mat_save_path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment