Assign Landscape Layer Info - not saving

Hey! I am using plugin to assign Landscape Layer Info to my landscape. It assigns the layer, but this changed is never saved, also, seems like it applies it only ‘visually’ in GUI, but not actually (hence, probably, that is why not saving). I am probably missing some small line of code, but still can’t get it work… Here is relevant code part:

    FStringAssetReference landscapeLayerPath3("LandscapeLayerInfoObject'/Game/DeadHillsLandscape/Maps/Overview/Overview_sharedassets/Layer_03_LayerInfo.Layer_03_LayerInfo'");
UObject* landscapeLayerObject3 = landscapeLayerPath3.TryLoad();
this->landscapeLayerInfoObject3 = nullptr;

if (landscapeLayerObject3 != nullptr)
{
	this->landscapeLayerInfoObject3 = Cast<ULandscapeLayerInfoObject>(landscapeLayerObject3);
}

   for (TActorIterator<ALandscapeProxy> ActorIt(world); ActorIt; ++ActorIt)
{

	ULandscapeInfo* Info = ActorIt->GetLandscapeInfo();

	FLandscapeInfoLayerSettings& LayerSettings = Info->Layers[0];

	if (LayerSettings.LayerInfoObj == nullptr)
	{
		LayerSettings.Owner = *ActorIt;
		LayerSettings.LayerInfoObj = this->landscapeLayerInfoObject3;
		LayerSettings.bValid = true;
	}

            if (GEngine != nullptr)
	{
		Info->UpdateLayerInfoMap(*ActorIt, false);
		ActorIt->Modify(true);
		ActorIt->UpdateAllComponentMaterialInstances();
		ActorIt->MarkPackageDirty();
		GEngine->BroadcastLevelActorListChanged();
		Info->MarkPackageDirty();

	}

    const bool bPromptUserToSave = false;
const bool bSaveMapPackages = true;
const bool bSaveContentPackages = true;
const bool bFastSave = false;
const bool bNotifyNoPackagesSaved = false;
const bool bCanBeDeclined = false;

if (!FEditorFileUtils::SaveDirtyPackages(bPromptUserToSave, bSaveMapPackages, bSaveContentPackages, bFastSave, bNotifyNoPackagesSaved, bCanBeDeclined))
{
	UE_LOG(LogTemp, Error, TEXT("WHELP WE WERE NOT SAVED!"));
	this->actionAssignLayersToLandscapes = false;
	return;
}

Only just slightly late with this one, but I found the following worked for me:

InfoObject->LayerName = LandscapeLayerSettings.LayerName;
InfoObject->bNoWeightBlend = false;

if (!LandscapeLayerSettings.LayerInfoObj)
{
    LandscapeLayerSettings.Owner = Landscape;
    LandscapeLayerSettings.bValid = true;
    LandscapeLayerSettings.LayerInfoObj = InfoObject;
    LandscapeLayerSettings.GetEditorSettings().LayerInfoObj = InfoObject;
}

Hey man, I am also having the same issue but I can’t seem to understand the solution from your code!

Here is my code, everything works fine but the layers are not being set:

void ALandscapeManager::GenerateLandscapeTiles()
{
const int32 GridSize = 7;
const float Spacing = (TileSize - 1) * LandscapeScale.X;

int32 HeightmapIndex = 0;

for (int32 Row = 0; Row < GridSize; ++Row)
{
    for (int32 Col = 0; Col < GridSize; ++Col)
    {
        FString HeightMapAddress = FString(HeightmapPath + "\\" + FString::FromInt(HeightmapIndex + 1) + ".png");

        /*TArray<uint16> HeightData;
        int32 Width, Height;
        if (!LoadHeightmapFromPNG(HeightMapAddress, HeightData, Width, Height))
        {
            UE_LOG(LogTemp, Warning, TEXT("Failed to load heightmap: %d"), (Row * Col));
            HeightmapIndex++;
            continue;
        }*/

        FVector TilePosition = FVector(Row * Spacing, Col * Spacing, 0.0f) + FVector(0);

        UWorld* world = GEditor->GetEditorWorldContext().World();
        ALandscape* NewTile = world->SpawnActor<ALandscape>(TilePosition, FRotator(0));
        ALandscapeProxy* proxy = Cast<ALandscapeProxy>(NewTile);

        if (NewTile)
        {
            NewTile->bCanHaveLayersContent = true;
            NewTile->SetActorScale3D(LandscapeScale);

            int section_size = 63;
            int section_per_component = 1;
            int component_x = 4;
            int component_y = 4;
            int quads_per_component = section_per_component * section_size;
            int size_x = 257;
            int size_y = 257;
            TArray<uint16> ImportLandscape_Data;

            ILandscapeEditorModule& editorModule = FModuleManager::GetModuleChecked<ILandscapeEditorModule>("LandscapeEditor");
            const ILandscapeHeightmapFileFormat* heightmapFormat = editorModule.GetHeightmapFormatByExtension(*FPaths::GetExtension(HeightMapAddress, true));
            if (heightmapFormat)
            {
                FLandscapeHeightmapImportData HeightmapImportData = heightmapFormat->Import(*HeightMapAddress, { 257,257 });
                if (HeightmapImportData.ResultCode == ELandscapeImportResult::Error)
                {
                    UE_LOG(LogTemp, Error, TEXT("Failed to import heightmap: %s"), *HeightMapAddress);
                    return;
                }
                ImportLandscape_Data = MoveTemp(HeightmapImportData.Data);
            }
            TMap<FGuid, TArray<uint16>> heightmapDataPerLayers;
            heightmapDataPerLayers.Add(FGuid(), ImportLandscape_Data);
            

            UMaterialInstanceConstant* MaterialInstance = NewObject<UMaterialInstanceConstant>(NewTile->GetWorld(), UMaterialInstanceConstant::StaticClass());
            if (!MaterialInstance)
            {
                UE_LOG(LogTemp, Warning, TEXT("Failed to create MaterialInstanceConstant."));
                return;
            }

            MaterialInstance->SetParentEditorOnly(landscapeMaterial);
            MaterialInstance->PostEditChange();

            FString Layer1Path = "/Script/Engine.Texture2D'/Game/Maps/Textures/" + FString::FromInt(HeightmapIndex + 1) + "_1." + FString::FromInt(HeightmapIndex + 1) + "_1'";
            FString Layer2Path = "/Script/Engine.Texture2D'/Game/Maps/Textures/" + FString::FromInt(HeightmapIndex + 1) + "_2." + FString::FromInt(HeightmapIndex + 1) + "_2'";
            FString Layer3Path = "/Script/Engine.Texture2D'/Game/Maps/Textures/" + FString::FromInt(HeightmapIndex + 1) + "_3." + FString::FromInt(HeightmapIndex + 1) + "_3'";

            UTexture2D* Layer1Tex = LoadObject<UTexture2D>(nullptr, *Layer1Path);
            UTexture2D* Layer2Tex = LoadObject<UTexture2D>(nullptr, *Layer2Path);
            UTexture2D* Layer3Tex = LoadObject<UTexture2D>(nullptr, *Layer3Path);

            if (MaterialInstance)
            {
                if (Layer1Tex) MaterialInstance->SetTextureParameterValueEditorOnly(FName("Grass Layer"), Layer1Tex);
                if (Layer2Tex) MaterialInstance->SetTextureParameterValueEditorOnly(FName("Rock Layer"), Layer2Tex);
                if (Layer3Tex) MaterialInstance->SetTextureParameterValueEditorOnly(FName("Sand Layer"), Layer3Tex);

                // Apply the material instance back to the landscape
                for (ULandscapeComponent* Component : NewTile->LandscapeComponents)
                {
                    Component->MarkRenderStateDirty();
                }

                NewTile->LandscapeMaterial = MaterialInstance;
            }

            TArray<FLandscapeImportLayerInfo> importLandInfo;
            TMap<FGuid, TArray<FLandscapeImportLayerInfo>> landscapeLayersInfo;
            if (landscapeMaterial != nullptr)
            {
                TArray<FName> layerNames = ALandscapeProxy::GetLayersFromMaterial(landscapeMaterial);
                importLandInfo.Reserve(layerNames.Num());
                for (int32 i = 0; i < layerNames.Num(); ++i)
                {
                    FString LayerInfoPath = "/Game/Maps/LandscapeLayers/" + FString::FromInt(i + 1) + "_LayerInfo";
                    ULandscapeLayerInfoObject* NewLayerInfo = LoadObject<ULandscapeLayerInfoObject>(nullptr, *LayerInfoPath);

                    if (NewLayerInfo)
                    {
                        FLandscapeImportLayerInfo ILayerInfo;
                        ILayerInfo.LayerName = layerNames[i];
                        ILayerInfo.LayerInfo = NewLayerInfo;
                        importLandInfo.Add(MoveTemp(ILayerInfo));
                    }
                }
            }
            landscapeLayersInfo.Add(FGuid(), MoveTemp(importLandInfo));

            for (const auto& layer : landscapeLayersInfo)
            {
                UE_LOG(LogTemp, Warning, TEXT("Guild: %s"), *layer.Key.ToString());
                for (const auto& layerInfo : layer.Value)
                {
                    UE_LOG(LogTemp, Warning, TEXT("Layer info : %s"), *layerInfo.LayerName.ToString());
                    UE_LOG(LogTemp, Warning, TEXT("Layer info : %s"), *layerInfo.LayerInfo.GetFName().ToString());
                }
            }

            proxy->Import(FGuid::NewGuid(), 0, 0, size_x - 1, size_y - 1, section_per_component, section_size, heightmapDataPerLayers, TEXT("MapHeightMap"), landscapeLayersInfo, ELandscapeImportAlphamapType::Additive);
            
            Landscapes.Add(NewTile);
        }

        HeightmapIndex++;
    }
}

UE_LOG(LogTemp, Log, TEXT("Generated %d landscape tiles from heightmaps."), Landscapes.Num());

}