Created
May 27, 2021 12:08
-
-
Save unwave/e5250cba73c43bd1f6da51b5e35fdb25 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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