Skip to content

Instantly share code, notes, and snippets.

@michagrandel
Created April 24, 2024 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michagrandel/673fb87e14062781e56db7dff42207df to your computer and use it in GitHub Desktop.
Save michagrandel/673fb87e14062781e56db7dff42207df to your computer and use it in GitHub Desktop.
Example on how to recursively check material expressions
""" Run recursively through material expressions in Unreal Engine """
import unreal
from typing import *
# ---- ENTER A VALID PACKAGE NAME HERE TO RUN THE SCRIPT
PACKAGE_NAME = "/Game/Developers/..."
if PACKAGE_NAME == "/Game/Developers/...":
unreal.log_error("Please change the package path to a valid material in the sample code!")
material = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem).load_asset(PACKAGE_NAME)
unreal.log("{material}:".format(material=material.get_name()))
unreal.log("{underline}:".format(underline=len(material.get_name())*"="))
def get_material_expressions(material : unreal.Material, material_expression : unreal.MaterialExpression) -> List[unreal.MaterialExpression]:
"""
Recursively get all material expressions connected to a given material expression
:param material: material
:param material expression: get all expressions connected to this expression
:return: list of material expressions
"""
if not material_expression:
return []
expressions = unreal.MaterialEditingLibrary.get_inputs_for_material_expression(material, material_expression)
if len(list(filter(lambda e: e, expressions))) == 0:
return expressions
result = []
for expression in expressions:
_result = get_material_expressions(material, expression)
if len(list(filter(lambda e: e != None, _result))) == 0:
continue
result.extend(_result)
expressions.extend(result)
return expressions
material_properties = {
"ambient_occlusion": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_AMBIENT_OCCLUSION),
"base_color": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_BASE_COLOR),
"emissive": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_EMISSIVE_COLOR),
"metallic": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_METALLIC),
"normal": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_NORMAL),
"opacity": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_OPACITY),
"opacity_mask": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_OPACITY_MASK),
"refraction": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_REFRACTION),
"roughness": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_ROUGHNESS),
"specular": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_SPECULAR),
"sss_color": unreal.MaterialEditingLibrary.get_material_property_input_node(material, unreal.MaterialProperty.MP_SUBSURFACE_COLOR)
}
all_material_expressions = [] # list to store all material expressions in a given material
for name, expression in material_properties.items():
if not expression:
# material propery is not connected to any material expression
continue
material_expressions = get_material_expressions(material, expression)
all_material_expressions.extend(material_expressions)
all_material_expressions.append(expression)
for expression in all_material_expressions:
# handle expression that directly connect to material properties
if isinstance(expression, unreal.MaterialExpressionMaterialFunctionCall):
print("{material} >> {expression} <Material Function Call>".format(material=material.get_name(), expression=expression.get_name()))
if isinstance(expression, unreal.MaterialExpressionNamedRerouteUsage):
print("{material} >> {expression} <Named Reroute Usage>".format(material=material.get_name(), expression=expression.get_name()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment