Постепенная смена материала в unreal в с++ коде (в режиме редактора)
Так, у меня на дальнем плане есть горы, и есть четыре материала для этих гор для каждого сезона (Зима, Осень, Лето, Весна).
Я создал специальный класс TerrainAccosories, который подбирает эти материалы еще в редакторе и с помощью функции создает динамические инстансы этих материалов (UMaterialInstanceDynamic), после этого я могу просто используя функцию SetMaterial подменять один материал на другой.
ATerrainAccessories::ATerrainAccessories()
{
PrimaryActorTick.bCanEverTick = false;
// SetTag
this->Tags.Add(FName("TerrainAccessories"));
TerrainMaterialInstances.reserve(4);
}
void ATerrainAccessories::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
if (PropertyChangedEvent.GetPropertyName() == GET_MEMBER_NAME_CHECKED(ATerrainAccessories,
TerrainWinterMaterial))
TerrainMaterialInstances[0] = UMaterialInstanceDynamic::Create(TerrainWinterMaterial,
this);
if (PropertyChangedEvent.GetPropertyName() == GET_MEMBER_NAME_CHECKED(ATerrainAccessories,
TerrainSpringMaterial))
TerrainMaterialInstances[1] = UMaterialInstanceDynamic::Create(TerrainSpringMaterial,
this);
if (PropertyChangedEvent.GetPropertyName() == GET_MEMBER_NAME_CHECKED(ATerrainAccessories,
TerrainSummerMaterial))
TerrainMaterialInstances[2] = UMaterialInstanceDynamic::Create(TerrainSummerMaterial,
this);
if (PropertyChangedEvent.GetPropertyName() == GET_MEMBER_NAME_CHECKED(ATerrainAccessories,
TerrainFallMaterial))
TerrainMaterialInstances[3] = UMaterialInstanceDynamic::Create(TerrainFallMaterial,
this);
}
UMaterialInstanceDynamic* ATerrainAccessories::GetSeasonTerrainMaterialInst(uint8 Season) {
UMaterialInstanceDynamic* MaterialInstance = nullptr;
if (Season >= 0 && Season <= 4)
MaterialInstance = TerrainMaterialInstances[Season];
return MaterialInstance;
}
Но материал меняется слишком резко, поэтому я бы хотел смешивать эти материалы постепенно.
Мои предварительные исследования этой задачи привели к пониманию того что для ее решения нужно создавать особый материал, который использует функцию редактора материалов(blend material function). Также в ассортименте классов, связанных с материалами есть класс MaterialLayerBlend, который использует эту же функцию в удобной обертке. Все что нужно это взять атрибуты первого материала, атрибуты второго и отдать их этой функции, третий аргумент это alpha значение, которое определяет текущую пропорцию смешивания (от 0 до 1).
Но проблема в том, что эту функцию вроде как нельзя вызывать из с++ кода. Потому что эти инстансы не компилируются в рантайме. Предполагается что этот MaterialLayerBlend создается еще редакторе, через блюпринты. Однако и мой класс TerrainAccosories тоже настраивается еще в редакторе. Я посмотрел в исходники UMaterialFunction и кажется при условии что код выполняется в редакторе, у него есть доступ к функции Compile.
В общем я предполагаю что в теории возможно создать этот материал в с++, но я не понимаю пока как. Из материалов в с++ через свойство MaterialAttributes можно достать необходимые атрибуты двух материалов. Остается создать новый материал, прописать в его exressions бленд функцию, добавить альфа атрибут и скомпилировать (в режиме редактора), далее создать инстанс на основе это материала и уже пользуясь инстансом постепенно меняя свойство альфа канала получить плавный переход от одного материала к другому. Проблема в том что никакой библиотеки с material functions на с++ нет.
Что думаете по этому поводу?