隨筆,隨緣更新,記錄一些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; }