UE问题分部解决

0.寻找Actor

ALandscape *land=nullptr;
    for (TActorIterator<ALandscape> It(GEditor->GetEditorWorldContext().World()); It; ++It) {
        if (It) {
            FString  name = It->GetName();
            if (name == "Landscape_0")
            {
                UE_LOG(LogTemp, Log, TEXT("已找到%s"), *name);
                land = *It;
                break;
            }
        }
    }
    if (land == nullptr)
    {
        UE_LOG(LogTemp, Log, TEXT("未找到"));
        return;
    }

1.获取材质球

UMaterialInterface *matInterFace= land->GetLandscapeMaterial();

2.获取材质球属性

UMaterialInterface *matInterFace= land->GetLandscapeMaterial();
UTexture *tex = nullptr;
FName texName="Color01";
matInterFace->GetTextureParameterValue(texName,tex,false);
if (tex != nullptr)
{
    FString fullName = tex->GetPathName();
    UE_LOG(LogTemp, Log, TEXT("已找到Color01的图为%s"),*fullName);
}

3.动态设置材质球属性

UMaterialInstanceConstant *materialConstantInstance = nullptr;
materialConstantInstance = Cast<UMaterialInstanceConstant>(matInterFace);
materialConstantInstance->SetTextureParameterValueEditorOnly(FName("Color02"), tex);

3.5.创建文件夹

VerifyOrCreateDirectory("D:\WWW");
bool SLPanel::VerifyOrCreateDirectory(const FString& TestDir)
{
    
    // Every function call, unless the function is inline, adds a small
    // overhead which we can avoid by creating a local variable like so.
    // But beware of making every function inline!
    IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();

    // Directory Exists?
    if (!PlatformFile.DirectoryExists(*TestDir))
    {
        PlatformFile.CreateDirectory(*TestDir);

        if (!PlatformFile.DirectoryExists(*TestDir))
        {
            UE_LOG(LogTemp, Log, TEXT("未能成功创建"));
            return false;
            //~~~~~~~~~~~~~~
        }
    }
    UE_LOG(LogTemp, Log, TEXT("已成功创建"));
    return true;
}

4.创建图片

SaveTextureToDisk(Cast<UTexture2D>(tex),"D:\Output\1.png");

void SaveTextureToDisk(UTexture2D* texture, const FString& file)
{
    TextureCompressionSettings prevCompression = texture->CompressionSettings;
    TextureMipGenSettings prevMipSettings = texture->MipGenSettings;
    texture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
    texture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
    texture->UpdateResource();
    FTexture2DMipMap* MM = &texture->PlatformData->Mips[0];

    TArray<FColor> OutBMP;
    int w = MM->SizeX;
    int h = MM->SizeY;

    OutBMP.SetNumUninitialized(w*h);

    FByteBulkData* RawImageData = &MM->BulkData;

    FColor* FormatedImageData = static_cast<FColor*>(RawImageData->Lock(LOCK_READ_ONLY));
    if (FormatedImageData)
    {
        for (int i = 0; i < (w*h); ++i)
        {
            OutBMP[i] = FormatedImageData[i];
            OutBMP[i].A = 255;
        }

        RawImageData->Unlock();
        FIntPoint DestSize(w, h);

        FString ResultPath;
        FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
        HighResScreenshotConfig.SaveImage(file, OutBMP, DestSize, nullptr);
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("SaveTextureToDisk: could not access bulk data of texture! Texture: %s"), *texture->GetFullName());
    }

    texture->CompressionSettings = prevCompression;
    texture->MipGenSettings = prevMipSettings;
}

5.图片转二维数组

TArray<TArray<FColor>> SLPanel::GetArrayFromLocalTex(const FString &_TexPath)
{
    TArray<TArray<FColor>> colorArray;

    TArray<uint8> OutArray;
    if (FFileHelper::LoadFileToArray(OutArray, *_TexPath))
    {
        int length = OutArray.Num();
        int size =FMath::Sqrt(length / 4);
        colorArray.Init(TArray<FColor>(),size);
        for (int index = 0; index < size; index++)
        {
            colorArray[index].Init(FColor(), size);
        }
        int count = 0;
        for (int i = 0; i < size; i++)
            for (int j = 0; j < size; j++)
            {
                colorArray[i][j].R = OutArray[count++];
                colorArray[i][j].G = OutArray[count++];
                colorArray[i][j].B = OutArray[count++];
                colorArray[i][j].A = OutArray[count++];
            }
    }
    else
    {
        colorArray.Init(TArray<FColor>(), 0);
    }
    return colorArray;
}

6.获取地形混合图3维数组

ULandscapeComponent* landComponent=Cast<ULandscapeComponent>(land->GetComponentByClass(ULandscapeComponent::StaticClass()));
TArray<UTexture2D*> weightTextures = landComponent->WeightmapTextures;
ALandscapeProxy *proxy = landComponent->GetLandscapeProxy();
ULandscapeInfo*LandscapeInfo = proxy->GetLandscapeInfo();
for (int32 i = 0; i < LandscapeInfo->Layers.Num(); ++i)
{
    ULandscapeLayerInfoObject*LayerInfo = LandscapeInfo->Layers[i].LayerInfoObj;
    if (LayerInfo)
    {

        FString LayerName = "D:/Output/" + LayerInfo->LayerName.ToString() + ".png";
        LandscapeInfo->ExportLayer(LayerInfo, LayerName);
    }
}


7.动态更换地形材质球

UMaterialInterface* newMat = LoadObject<UMaterialInterface>(NULL, TEXT("MaterialInstanceConstant'/Game/Landscape_2_Inst.Landscape_2_Inst'"));
land->LandscapeMaterial = newMat;

8.脚本创建材质实例

    UMaterial* newMat = LoadObject<UMaterial>(NULL, TEXT("Material'/Game/Landscape.Landscape'"));
    FAssetToolsModule &AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
    UMaterialInstanceConstantFactoryNew* Factory = NewObject<UMaterialInstanceConstantFactoryNew>();
    Factory->InitialParent = newMat;
    FString AssetPath = TEXT("/Game/");
    UMaterialInstanceConstant *MInst = CastChecked<UMaterialInstanceConstant>(AssetToolsModule.Get().CreateAsset(TEXT("MatInstance"), FPackageName::GetLongPackagePath(AssetPath), UMaterialInstanceConstant::StaticClass(), Factory));

    if (MInst)
    {
        MInst->SetFlags(RF_Standalone);
        MInst->MarkPackageDirty();
        MInst->PostEditChange();
    }

 9.脚本创建dds

UE_LOG(LogTemp, Error, TEXT("开始合并dds"));
    //FString  exeStr = "D:\software\PowerVR\Tool\PVRTexTool\CLI\Windows_x86_64\PVRTexToolCLI.exe";
    //FString  exeStr = "G:\UEProject\UESource\LocalBuilds\Engine\Windows\Engine\Binaries\ThirdParty\ImgTec\PVRTexToolCLI.exe";
    FString  exeStr = FPaths::EngineDir()+"Binaries/ThirdParty/ImgTec/PVRTexToolCLI.exe";
    const TCHAR* url= *exeStr;

    FString paraStr = "C:\Users\Administrator> PVRTexToolCLI -m 1 -f b8g8r8a8 -i D:\Texs\0.tga,D:\Texs\1.tga,D:\Texs\2.tga,D:\Texs\3.tga -array -r 512,512 -o D:\Output\2dArray.dds";
    const TCHAR* paras=*paraStr;
    FPlatformProcess::CreateProc(url,paras, true, false, false, nullptr, -1, nullptr, nullptr);

 10.脚本创建LayerInfo

FName LayerName = FName("layer03");
    FName LayerObjectName = FName("Layer03_LayerInfo");
    FString PackageName =FString("/Game/") + LayerObjectName.ToString();
    UPackage* Package = CreatePackage(nullptr, *PackageName);
    ULandscapeLayerInfoObject* LayerInfo = NewObject<ULandscapeLayerInfoObject>(Package, LayerObjectName, RF_Public | RF_Standalone | RF_Transactional);
    LayerInfo->LayerName = LayerName;
    LayerInfo->bNoWeightBlend =false;
    const UObject* LayerInfoAsUObject = LayerInfo; // HACK: If SetValue took a reference to a const ptr (T* const &) or a non-reference (T*) then this cast wouldn't be necessary
    //ensure(PropertyHandle_LayerInfo->SetValue(LayerInfoAsUObject) == FPropertyAccess::Success);
    // Notify the asset registry
    FAssetRegistryModule::AssetCreated(LayerInfo);
    // Mark the package dirty...
    Package->MarkPackageDirty();
    // Show in the content browser
    TArray<UObject*> Objects;
    Objects.Add(LayerInfo);
    GEditor->SyncBrowserToObjects(Objects);

 11.动态指定LayerInfo(目前还无法做到刷新,但点击其他模式就行了)

    ULandscapeComponent* landComponent = Cast<ULandscapeComponent>(land->GetComponentByClass(ULandscapeComponent::StaticClass()));
    TArray<UTexture2D*> weightTextures = landComponent->WeightmapTextures;
    ALandscapeProxy *proxy = landComponent->GetLandscapeProxy();
    ULandscapeInfo*LandscapeInfo = proxy->GetLandscapeInfo();

    ULandscapeLayerInfoObject* obj= LoadObject<ULandscapeLayerInfoObject>(NULL, TEXT("LandscapeLayerInfoObject'/Game/ALayer03_LayerInfo.ALayer03_LayerInfo'"));
    LandscapeInfo->ReplaceLayer(LandscapeInfo->Layers[2].LayerInfoObj,obj);
    FLandscapeInfoLayerSettings& LayerSettings = LandscapeInfo->Layers[2];
    LayerSettings.LayerInfoObj =obj;

 12.自动import资源https://www.cnblogs.com/username/p/7483340.html

FAssetToolsModule &AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
IAssetTools& AssetTool = AssetToolsModule.Get();
TArray<FString> fileArray;
fileArray.Init(FString("D://Output//Layer01.png"),1);
AssetTool.ImportAssets(fileArray, FString("/Game"),NULL);

设置权重数据bool LandscapeEditorUtils::SetWeightmapData(ALandscapeProxy* Landscape, ULandscapeLayerInfoObject* LayerObject, const TArray<uint8>& Data)

获得权重数据 void GetWeightData(ULandscapeLayerInfoObject* LayerInfo, int32& X1, int32& Y1, int32& X2, int32& Y2, TMap<FIntPoint, uint8>& SparseData);

或者 LandscapeEdit文件中:void ULandscapeComponent::InitWeightmapData(TArray<ULandscapeLayerInfoObject*>& LayerInfos, TArray<TArray<uint8> >& WeightmapData)

这里面貌似高度图之类的东西都有,以后可以参考

FEdModeLandscape* LandscapeEdMode = (FEdModeLandscape*)GLevelEditorModeTools().GetActiveMode(FBuiltinEditorModes::EM_Landscape); 这个为nullptr就表示当前不在刷地形栏

void FLandscapeEditorCustomNodeBuilder_TargetLayers::OnTargetLayerCreateClicked(const TSharedRef<FLandscapeTargetListInfo> Target, bool bNoWeightBlend) 创建Layer

原文地址:https://www.cnblogs.com/luxishi/p/10394687.html