Skip to content

Instantly share code, notes, and snippets.

@unwave
Created May 27, 2021 12:08
Show Gist options
  • Save unwave/e5250cba73c43bd1f6da51b5e35fdb25 to your computer and use it in GitHub Desktop.
Save unwave/e5250cba73c43bd1f6da51b5e35fdb25 to your computer and use it in GitHub Desktop.
import unreal # type: ignore
import os
import json
import datetime
def get_desktop():
try:
import winreg
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders") as key:
return winreg.QueryValueEx(key, "Desktop")[0]
except:
return os.path.expanduser("~/Desktop")
def get_unique_key(dict, key, sentinel = object()):
index = 2
initial_key = key
while dict.get(key, sentinel) is not sentinel:
key = initial_key + f'_{index}'
index += 1
return key
def find_key_by_value(dict, value_to_find, default = None):
for key, value in dict.items():
if value == value_to_find:
return key
return None
def map_unique(dict, traget_name, value):
key = find_key_by_value(dict, value)
if not key:
key = get_unique_key(dict, traget_name)
dict[key] = value
return key
def get_fbx_export_option():
options = unreal.FbxExportOption()
options.collision = False
options.level_of_detail = False
options.vertex_color = True
return options
def get_export_task(filename, object, options = None):
task = unreal.AssetExportTask()
task.automated = True
task.replace_identical = True
task.filename = filename
task.object = object
if options:
task.options = options
return task
def get_textures(material):
type = material.__class__.__name__
if type == 'StaticMaterial':
material = material.material_interface
type = material.__class__.__name__
if type == 'MaterialInstanceConstant':
textures = []
for parameter_name in unreal.MaterialEditingLibrary.get_texture_parameter_names(material.get_base_material()):
textures.append(unreal.MaterialEditingLibrary.get_material_instance_texture_parameter_value(material, parameter_name))
return textures
elif type == 'Material':
return unreal.MaterialEditingLibrary.get_used_textures(material)
else:
raise BaseException(f"Material '{material.get_name()}' has unsupported type '{type}'.")
class Textures(dict):
def append(self, texture):
return map_unique(self, texture.get_name(), texture)
def get_export_tasks(self, dir_path):
tasks = unreal.Array(unreal.AssetExportTask)
for name, texture in self.items():
file_name = os.path.join(dir_path, name + '.tga')
tasks.append(get_export_task(file_name, texture))
return tasks
class Materials(dict):
def __init__(self, textures):
self.textures = textures
def append(self, material):
textures = {self.textures.append(texture) for texture in get_textures(material)}
return map_unique(self, material.get_name(), textures)
def get_dict(self):
dict = {}
for name, textures in self.items():
dict[name] = [texture + '.tga' for texture in textures]
return dict
class Models(dict):
def __init__(self, materials):
self.materials = materials
def append(self, model):
materials = [self.materials.append(material.material_interface) for material in model.static_materials]
return map_unique(self, model.get_name(), (model, materials))
def get_export_tasks(self, dir_path, options = get_fbx_export_option()):
tasks = unreal.Array(unreal.AssetExportTask)
for name, (model, materials) in self.items():
file_name = os.path.join(dir_path, name + '.fbx')
tasks.append(get_export_task(file_name, model, options))
return tasks
def get_dict(self):
return {name + '.fbx': materials for name, (model, materials) in self.items()}
def export(assets, dir_path):
textures = Textures()
materials = Materials(textures)
models = Models(materials)
for asset in assets:
type = asset.__class__.__name__
if type == 'StaticMesh':
models.append(asset)
elif type in ('Material', 'MaterialInstanceConstant'):
materials.append(asset)
elif type in ('Texture2D', 'Texture'):
textures.append(asset)
else:
print(f"Asset '{asset.get_name()}' has unsupported type '{type}'.")
if not any((textures, materials, models)):
return
os.makedirs(dir_path, exist_ok = True)
if any((materials, models)):
info = { "models": models.get_dict(), "materials": materials.get_dict()}
info_path = os.path.join(dir_path, "__unreal_assets__.json")
with open(info_path, 'w') as info_file:
json.dump(info, info_file, indent = 4, ensure_ascii = False)
unreal.TextureExporterTGA.run_asset_export_tasks(textures.get_export_tasks(dir_path))
unreal.Exporter.run_asset_export_tasks(models.get_export_tasks(dir_path))
utility_base = unreal.GlobalEditorUtilityBase.get_default_object()
assets = list(utility_base.get_selected_assets())
time_stamp = datetime.datetime.now().strftime('%y%m%d_%H%M%S')
dir_path = os.path.join(get_desktop(), "unreal_assets_" + time_stamp)
export(assets, dir_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment