UE4-開發中遇到的問題和處理方法


隨筆,隨緣更新,記錄一些UE4不太好分類的問題點和解決方法。

 

 

Q.C++ UObject注冊Tick事件

方式一:

  參考AActor的源碼實現:

    #include "Containers/Ticker.h"

 

auto TickDelegate = FTickerDelegate::CreateUObject(this, &Utest::Tick);
FTicker::GetCoreTicker().AddTicker(TickDelegate, 0.01f);

方式二:繼承 FTickableGameObject

並重新實現以下三個函數:

    virtual void Tick(float DeltaTime) override;
    virtual bool IsTickable() const override ;//非純虛函數,可不實現virtual TStatId GetStatId() const override ; //{ RETURN_QUICK_DECLARE_CYCLE_STAT(UClassName, STATGROUP_Tickables); }

 

 

 

Q.多平台的拖拽drop and drag 擴展開發思路:

  UE4的拖拽本身是支持Mouse和Touch的,但實現拖拽功能后,拖拽目標僅只支持拖拽和雙擊點擊事件(單擊事件將被拖拽事件覆蓋),當拖拽目標需要支持多個可點擊的Button時,就需要自己去擴展

  以下記錄一個Mouse/Touch都支持的拖拽擴展

 

 

Q.UE4 Http 圖片/文件/資源上傳到Net Core WebAPI 示例:

  留底被查

  UE4部分:

NetAPI.cpp代碼段:

TSharedRef<IHttpRequest> UNetAPI::createUploadImageRequest(FString _url, TArray<uint8>& rawData)
{
    TSharedRef<IHttpRequest> ret_request = UNetAPI::GetHttpModule()->CreateRequest();

    ret_request->SetURL(_url);
    ret_request->SetHeader(TEXT("Content-Type"), TEXT("text/html;charset=UTF-8"));

    ret_request->SetVerb(TEXT("POST"));
    ret_request->SetContent(rawData);

    return ret_request;
}

 

BusinssNetAPI.cpp代碼段:

static const FString api_UploadImage = TEXT("http://localhost:63664/api/Test/UploadImageFromCS?size=%d&filename=%s");

FHttpRequestPtr UBusinssNetAPI::UploadImage()
{
    TArray<uint8> binrary_data;
    TArray<FString> arr_path;
    
#if UE_BUILD_DEVELOPMENT
    arr_path.Add(TEXT("d:/left.jpg"));
    arr_path.Add(TEXT("d:/top.jpg"));
    arr_path.Add(TEXT("d:/back.jpg"));
#endif

    for (FString path : arr_path) 
    {
        FString left, right;

        path.Split(TEXT("/"), &left, &right, ESearchCase::IgnoreCase, ESearchDir::FromEnd);        
        
        FString fileName = FGenericPlatformHttp::UrlEncode( right );
        FFileHelper::LoadFileToArray(binrary_data, *path /* TEXT("d:/11.zip") */ );

        FString url = FString::Printf(*api_UploadImage, binrary_data.Num(), *fileName);
        TSharedRef<IHttpRequest> req = UNetAPI::createUploadImageRequest(url, binrary_data);

        req->OnProcessRequestComplete().BindLambda([=](    FHttpRequestPtr Request ,
                                                        FHttpResponsePtr Response ,
                                                        bool bConnectedSuccessfully )
            {
                UE_LOG(LogTemp, Log, TEXT("[UploadImage] : complated {%s}"), *api_UploadImage);
                UE_LOG(LogTemp, Log, TEXT("[UploadImage] : complated {%d}"), bConnectedSuccessfully);
            });

        if (req->ProcessRequest())
        {
            UE_LOG(LogTemp, Log, TEXT("[UploadImage] : starting......"));
        }
    }
    return nullptr;
}

 

Net WebAPI部分:

        [HttpPost]
        public IActionResult UploadImageFromCS(int size = 0, string filename = "")
        {
            Console.WriteLine($" file {size}");

            int index = 0;
            if ( this.Request.Body != null && 
                 size > 0 )
            {
                Stream stream = this.Request.Body;
                byte[] buffer = new byte[size];

                while ( true )
                {
                    if ( this.Request.Body.CanRead )
                    {
                        int offset = stream.Read(buffer, index, size - index);
                        index = index + offset - 1;

                        if ( offset == 0 )
                        {
                            break;
                        }
                    }
                    else
                    {
                        //Thread.Sleep(100);
                    }
                }

                using (FileStream fs = new FileStream($@"d:/Cache/{filename}", FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    fs.Write(buffer, 0, size);
                }
            }

            return Ok();
        }

 

Q.指定攝像機位保存為圖片筆記:

  用到VictoryPlugin插件得Capture2D_SaveImage函數.

結果保存出得圖片偏暗,

排查原因是因為UE4是用得srgb作為顯示格式,而Capture2D_SaveImage函數而是按rgb來保存得。所以導致保存的圖片與程序顯示不一致:

解決:

 

 

VictoryPlugin插件CaptureComponent2D_SaveImage函數源碼修正:

插件下載地址:https://github.com/EverNewJoy/VictoryPlugin

bool UVictoryBPFunctionLibrary::CaptureComponent2D_SaveImage(class USceneCaptureComponent2D* Target, const FString ImagePath, const FLinearColor ClearColour)
{
    // Bad scene capture component! No render target! Stay! Stay! Ok, feed!... wait, where was I?
    if ((Target == nullptr) || (Target->TextureTarget == nullptr))
    {
        return false;
    }
    
    FRenderTarget* RenderTarget = Target->TextureTarget->GameThread_GetRenderTargetResource();
    if (RenderTarget == nullptr)
    {
        return false;
    }

    TArray<FLinearColor > RawPixels;
    
    // Format not supported - use PF_B8G8R8A8.
    if (Target->TextureTarget->GetFormat() != PF_B8G8R8A8)
    {
        // TRACEWARN("Format not supported - use PF_B8G8R8A8.");
        return false;
    }
    if ( !RenderTarget-> ReadLinearColorPixels( RawPixels ) )
    {
        return false;
    }
    
    TArray<uint8> arr_raw;
    for (auto Pixels : RawPixels) 
    {
        auto color = Pixels.ToFColor(true);
        arr_raw.Add(color.B );
        arr_raw.Add(color.G);
        arr_raw.Add(color.R);
        arr_raw.Add(color.A);
    }

    TSharedPtr<IImageWrapper> ImageWrapper = GetImageWrapperByExtention(ImagePath);

    const int32 Width = Target->TextureTarget->SizeX;
    const int32 Height = Target->TextureTarget->SizeY;
    
    auto maxCount = arr_raw.Num() * sizeof(uint8);
    if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(&arr_raw[0], maxCount, Width, Height, ERGBFormat::BGRA, 8))
    {
        FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(), *ImagePath);
        return true;
    }
    
    return false;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM