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; }
本文原创,不定时更新
可以随意转载到任何网站
~但是~ 转载也要按“基本法”
请注明原文出处和作者