keywords: [UE4][Material]使用蓝图和C++动态创建材质并设置材质参数属性(Parameter)

蓝图

步骤

使用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等接口,无法动态修改参数。

设置动态参数的其他接口(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();