• 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

  • 相关阅读:
    go语言的垮平台编译
    vscode使用技巧
    集合
    泛型
    异常
    Java垃圾回收机制
    java学习笔记9.20
    java变量类型
    目前的学习计划
    离第一篇博客三天
  • 原文地址:https://www.cnblogs.com/luxishi/p/10394687.html
Copyright © 2020-2023  润新知