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;
}
原文地址:https://www.cnblogs.com/linqing/p/11321497.html