UE4成批处理透明材质
项目中需要控制成批的物体的透明度,但是默认的时候他又不能是透明的,对,项目的要求就这么诡异。
然而却没有找到设置材质的BlendMode的功能,于是只有换了一种办法,物体需要透明时更换为透明材质,默认的时候使用初始的材质,当然我也不会为了每个材质单独再建一个透明材质,这工作量想想都不科学。这里,只是为自己的解决方案作了一个记录,算不上实用。
1.创建一个透明材质,作为通用的资源,并创建三个变量,一个主纹理,一个主颜色,一个透明度值就够了
2.默认材质,我们也需要将他的主纹理或者主颜色定义为变量,方便后面获取,比如这里截图的就是一个主颜色变量,我这里名称都统一为MainColor,MainTexture
3.在C++中定义一些公开变量,具体作用有注释,比如我们开始创建的透明材质也可以会通过这个赋值
/** 模型透明标签 */ UPROPERTY(EditDefaultsOnly, Category = "Transparency") FName TransCompontTag; /** 材质透明参数名称 */ UPROPERTY(EditDefaultsOnly, Category = "Transparency") FName TransMaterialPar; /** 材质主纹理的参数名称 */ UPROPERTY(EditDefaultsOnly, Category = "Transparency") FName TransMaterialTex; /** 材质主纹理的参数名称 */ UPROPERTY(EditDefaultsOnly, Category = "Transparency") FName TransMaterialColor; /** 透明材质 */ UPROPERTY(EditDefaultsOnly, Category = "Transparency") UMaterialInterface* TransMaterial;4.创建StaticMeshComponent数组,默认材质的TMap,透明材质的TMap,还有当前是否为透明状态
/*透明模型*/ TArray<UStaticMeshComponent*> _ArrayTransCompoent; /** 默认材质 */ TMap<FString,UMaterialInterface*> _MapDefaultMaterials; /** 透明材质 */ TMap<FString, UMaterialInstanceDynamic*> _MapTransMaterials; /** 是否透明 */ bool _IsTrans=false;
5.创建一个函数,通过开始的透明材质创建UMaterialInstanceDynamic,并获取默认材质的主纹理或者主颜色赋值给透明材质,效果虽然没默认材质那么多效果,也不至于一片全白,然后参数传一个float值来控制透明度,操作中就可以用滑动条来控制,
#pragma region 设置物体透明度 void SetCompoentTrans(const float value) { #pragma region 通过标签获取需要透明的物体 if (_ArrayTransCompoent.Num() == 0) { TArray<AActor*> _TempArrayOutActors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AStaticMeshActor::StaticClass(), _TempArrayOutActors); for (int32 i = 0; i < _TempArrayOutActors.Num(); i++) { UStaticMeshComponent* _TempStaticMesh = Cast<AStaticMeshActor>(_TempArrayOutActors[i])->StaticMeshComponent; TArray<FName> _TempArrayComTags = _TempStaticMesh->ComponentTags; for (int32 j = 0; j < _TempArrayComTags.Num(); j++) { if (_TempArrayComTags[j] == TransCompontTag) { _ArrayTransCompoent.Add(_TempStaticMesh); break; } } } } #pragma endregion #pragma region 利用TMap将透明物体的材质存储起来 if (_MapDefaultMaterials.Num()==0) { for (int32 i = 0; i < _ArrayTransCompoent.Num();i++) { TArray<UMaterialInterface*> _TempArrayMaterials = _ArrayTransCompoent[i]->GetMaterials(); for (int32 j = 0; j < _TempArrayMaterials.Num(); j++) { FString _TempStringKey = _ArrayTransCompoent[i]->GetAttachmentRootActor()->GetName()+"@"+FString::FromInt(j); _MapDefaultMaterials.Add(_TempStringKey, _TempArrayMaterials[j]); } } } #pragma endregion if (value>0.97f) { #pragma region 设置默认材质 if (_IsTrans) { for (int32 i = 0; i < _ArrayTransCompoent.Num(); i++) { TArray<UMaterialInterface*> _TempArrayMaterials = _ArrayTransCompoent[i]->GetMaterials(); for (int32 j = 0; j < _TempArrayMaterials.Num(); j++) { FString _TempStringKey = _ArrayTransCompoent[i]->GetAttachmentRootActor()->GetName() + "@" + FString::FromInt(j); _ArrayTransCompoent[i]->SetMaterial(j, _MapDefaultMaterials[_TempStringKey]); } } _IsTrans = false; } #pragma endregion } else { if (!_IsTrans) { #pragma region 创建透明材质 if (_MapTransMaterials.Num() == 0) { for (int32 i = 0; i < _ArrayTransCompoent.Num(); i++) { TArray<UMaterialInterface*> _TempArrayMaterials = _ArrayTransCompoent[i]->GetMaterials(); for (int32 j = 0; j < _TempArrayMaterials.Num(); j++) { FString _TempStringKey = _ArrayTransCompoent[i]->GetAttachmentRootActor()->GetName() + "@" + FString::FromInt(j); UMaterialInstanceDynamic*_TempMaterialID = _ArrayTransCompoent[i]->CreateDynamicMaterialInstance(0, TransMaterial); UTexture* _TempOutTexture; if (_MapDefaultMaterials[_TempStringKey]->GetTextureParameterValue(TransMaterialTex, _TempOutTexture)) { _TempMaterialID->SetTextureParameterValue(TransMaterialTex, _TempOutTexture); } /*else { _TempOutTexture = Cast<UTexture>(StaticLoadObject(UTexture::StaticClass(), NULL, TEXT("/Game/Texture/Transparent/Tex_Transparent"))); } _TempMaterialID->SetTextureParameterValue(TransMaterialTex, _TempOutTexture);*/ FLinearColor _TempOutColor; if (_MapDefaultMaterials[_TempStringKey]->GetVectorParameterValue(TransMaterialColor, _TempOutColor)) { _TempMaterialID->SetVectorParameterValue(TransMaterialColor, _TempOutColor); } _MapTransMaterials.Add(_TempStringKey,_TempMaterialID); } } #pragma endregion } else { #pragma region 设置透明材质 for (int32 i = 0; i < _ArrayTransCompoent.Num(); i++) { TArray<UMaterialInterface*> _TempArrayMaterials = _ArrayTransCompoent[i]->GetMaterials(); for (int32 j = 0; j < _TempArrayMaterials.Num(); j++) { FString _TempStringKey = _ArrayTransCompoent[i]->GetAttachmentRootActor()->GetName() + "@" + FString::FromInt(j); _ArrayTransCompoent[i]->SetMaterial(j, _MapTransMaterials[_TempStringKey]); } } #pragma endregion } _IsTrans = true; } for (int32 i = 0; i < _ArrayTransCompoent.Num(); i++) { _ArrayTransCompoent[i]->SetScalarParameterValueOnMaterials(TransMaterialPar, value); } } } #pragma endregion