[UE4][Material]使用蓝图和C++动态创建材质并设置材质参数属性(Parameter)
keywords: UE4, Material Parameter, 蓝图和C++动态创建材质, 设置材质参数属性
蓝图
步骤
使用StarterContent中的椅子作为演示示例的模型:
1,创建一个空的Actor蓝图,命名为RandomChair:
2,打开蓝图
并将椅子的StaticMesh拖放的到根节点内:
3,在该蓝图内创建一个box,命名为Box1,用于检测碰撞时使用:
4,将这个蓝图拖放到场景中:
5,添加蓝图脚本
现在构造函数中创建一个材质示例,并命名为DynamicMetarial
然后再添加Box1的碰撞事件函数
全部逻辑为:
每当靠近这个椅子时,椅子的颜色就会随机变化一次。
其中的参数名:ColorSeats,是在Chair的材质中定义的可编辑参数:
C++方式
动态创建材质并设置Parameter
加载材质、创建动态材质、并为 Image 控制设置材质资源
UMaterial* Mat = LoadObject<UMaterial>(nullptr, TEXT("Material'/Game/Asset/Materials/HUD/ProgressCircleRotate/M_ProgressCircleRot.M_ProgressCircleRot'"));
if (Mat && Img)
{
if (UMaterialInstanceDynamic* MatInstance = UMaterialInstanceDynamic::Create(Mat, this))
{
Img->SetBrushFromMaterial(MatInstance);
}
}
设置动态参数
if (Img)
{
if (UMaterialInstanceDynamic* MatInsDyna= Cast<UMaterialInstanceDynamic>(Img->Brush.GetResourceObject()))
{
MatInsDyna->SetScalarParameterValue("Alpha", 0.8);
}
}
基于已有静态材质创建动态材质:
if (USkeletalMeshComponent* MeshComp = Character->GetMesh())
{
if (UMaterialInterface* Mat = MeshComp->GetMaterial(0))
{
if (!Mat->IsA(UMaterialInstanceDynamic::StaticClass()))
{
if (UMaterialInstanceDynamic* MatInstance = UMaterialInstanceDynamic::Create(Mat, MeshComp))
{
MeshComp->SetMaterial(0, MatInstance);
Mat = MatInstance;
}
}
if (UMaterialInstanceDynamic* DynaMat = Cast<UMaterialInstanceDynamic>(Mat))
{
DynaMat->SetTextureParameterValue(TEXT("ColorTex"), HairIndex == 0 ? HairMesh.HairTex01 : HairMesh.HairTex02);
}
}
}
获取静态材质(预编译、无法动态修改参数)
使用SkeletalMesh上已有的Material来设置动态参数
if (USkeletalMeshComponent* SKMesh = GetSkeletalMeshComponent())
{
int32 Index = SKMesh->GetMaterialIndex(FName("logo"));
if (UMaterialInterface* MatInterface = SKMesh->GetMaterial(Index))
{
if (UMaterialInstanceConstant* MatCons = Cast<UMaterialInstanceConstant>(MatInterface))
{
}
}
}
UMaterialInstanceConstant
没有SetVectorParameterValue
等接口,无法动态修改参数。
Misc
设置动态参数的其他接口(MaterialInstanceDynamic.h)
void SetVectorParameterValue(FName ParameterName, FLinearColor Value);
bool SetScalarParameterValue(FName ParameterName,, float Value);
void SetTextureParameterValue(FName ParameterName, class UTexture* Value);
void SetFontParameterValue(const FMaterialParameterInfo& ParameterInfo, class UFont* FontValue, int32 FontPage);
void ClearParameterValuesInternal();
常用技巧
如果Image控件的资源已经设置了材质或者材质实例(MaterialInstance),那么可以直接通过以下接口获取控件的动态材质实例:
UMaterialInstanceDynamic* UImage::GetDynamicMaterial();