前言
本文基于4.27版本
大概总结了一些最近工作中遇到的,很大几率记不住的,日后可能还需要的用到的一些用于编辑器下获取材质(UMaterial)
的某些属性的接口,适合做工具用
材质编辑器界面
上图中左侧三个节点是UMaterialExpression
类及其子类
右侧的比如BaseColor
叫做Material的属性,M_Basic_Floor
是材质的名字
一些相关方法
获取材质中的表达式
对于一个UMaterial,如果想在编辑器模式下在C++中获取所有的表达式,可以使用这个方法GetAllExpressionsInMaterialAndFunctionsOfType
:
1 2 3 UMaterial* Material; TArray<UMaterialExpression*> Expressions; Material->GetAllExpressionsInMaterialAndFunctionsOfType (Expressions);
GetAllExpressionsInMaterialAndFunctionsOfType
这个函数可以获取到当前的UMaterial中所有的指定类型的表达式,并且会获取使用到的UMaterialFunction(下文可能会简写成MF)中的对应类型的表达式。
上面的函数会获取到指定的Material中全部的表达式,因为定义的数组Expressions
的类型是UMaterialExpression
,是表达式的基类。
如果是下面这样:
1 2 TArray<UMaterialExpressionMaterialFunctionCall*> ExpressionMaterialFunctionCalls; Material->GetAllExpressionsInMaterialAndFunctionsOfType (ExpressionMaterialFunctionCalls);
获取到的将只有材质中的UMaterialExpressionMaterialFunctionCall
类型的表达式。
如果只想获取到当前的材质中的表达式,并不需要获取所使用的MF中的表达式,可以使用下面这个方法GetAllExpressionsOfType
:
1 2 TArray<const UMaterialExpression*> Expressions; Material->GetAllExpressionsOfType (Expressions);
获取输入到材质某一个属性的表达式节点
还是上面的那张图,如果需要获取到输入到BaseColor
这个材质属性的表达式,可以用下面的方法:
1 2 FExpressionInput* ExpressionInput = Material->GetExpressionInputForProperty (EMaterialProperty::MP_BaseColor); UMaterialExpression* MaterialExpression = ExpressionInput->Expression;
其中EMaterialProperty
是定义在Engine\Source\Runtime\Engine\Public\SceneTypes.h
中的枚举
获取材质中MF调用时的输入的表达式
如图,1Dto2DIndex
是一个UMaterialExpressionMaterialFunctionCall
,是UMaterialExpression的子类,定义在MaterialExpressionMaterialFunctionCall.h
中
如果我要获取它的某一个Input前面的表达式的话,可以用下面的方法:
1 2 3 4 5 6 UMaterialExpressionMaterialFunctionCall* MaterialExpressionMaterialFunctionCall; TArray<FExpressionInput*> Inputs = MaterialExpressionMaterialFunctionCall->GetInputs ();for (const FExpressionInput* Input : Inputs) { UMaterialExpression* Expression = Input->Expression; }
以上代码是可以获取到在当前材质的层级里,MF作为一个表达式的输入,获取到的是图上的两个0的Expression。
如果要获取这个MF在自己的UMaterialFunction中的对应的input节点的输入的表达式(如上图)的话,需要的是如下的方法:
1 2 3 4 5 6 7 8 9 10 TArray<FFunctionExpressionInput> FunctionInputs = MaterialExpressionMaterialFunctionCall->FunctionInputs;for (const FFunctionExpressionInput FunctionInput : FunctionInputs) { UMaterialExpressionFunctionInput* MaterialExpressionFunctionInput = FunctionInput.ExpressionInput; TArray<FExpressionInput*> Inputs = MaterialExpressionFunctionInput->GetInputs (); for (const FExpressionInput* Input : Inputs) { UMaterialExpression* Expression = Input->Expression; } }
可以获取到UMaterialFunction中对应的Input节点的输入表达式。
一些Tips
UMaterialExpression
位置:MaterialExpression.h
指的注意的是,通过UMaterialExpression是可以获取他属于的材质或者材质函数的
1 2 3 4 5 6 7 8 9 10 11 12 13 UPROPERTY ()class UMaterial * Material;UPROPERTY ()class UMaterialFunction * Function;
对于FExpressionInput这个类型,有成员变量Expression
可以获得UMaterialExpression*
,进一步可以通过UMaterialExpression获得表达式的Name等属性,但是在WITH_EDITOR里发现成员变量ExpressionName
是None
UMaterialExpressionMaterialFunctionCall
如果想要获取如图上红框内的这个名字,可以这样:
1 2 3 4 5 UMaterialExpressionMaterialFunctionCall* ExpressionMaterialFunctionCall;for (FFunctionExpressionInput FunctionInput : ExpressionMaterialFunctionCall->FunctionInputs) { const FString InputExpressionName = FunctionInput.Input.Expression->GetName (); }