Постепенная смена материала в 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 на с++ нет.

Что думаете по этому поводу?


Ответы (0 шт):