UE4 创建一个actor,具有截图保存功能(C++实现)
时间: 2024-03-23 20:39:41 浏览: 143
可以参考以下步骤来创建一个具有截图保存功能的Actor:
1. 首先创建一个继承自Actor的子类,并在头文件中添加以下include语句:
```cpp
#include "Engine/TextureRenderTarget2D.h"
#include "EngineUtils.h"
```
2. 在子类中添加以下成员变量:
```cpp
UPROPERTY(EditAnywhere)
int32 Width = 1024;
UPROPERTY(EditAnywhere)
int32 Height = 1024;
UPROPERTY(EditAnywhere)
FString SavePath = FPaths::ProjectSavedDir() + "Screenshots/";
UPROPERTY(EditAnywhere)
FString FileNamePrefix = "Screenshot_";
```
这些变量将控制截图的大小、保存路径和文件名前缀。
3. 在子类中添加以下函数:
```cpp
void SaveScreenshot(UTextureRenderTarget2D* RenderTarget, const FString& FilePath);
FString GetUniqueFilename(const FString& Prefix, const FString& Extension);
```
SaveScreenshot函数将保存截图到指定路径,GetUniqueFilename函数将生成一个唯一的文件名。
4. 在子类的cpp文件中实现以上两个函数:
```cpp
void AMyActor::SaveScreenshot(UTextureRenderTarget2D* RenderTarget, const FString& FilePath)
{
TArray<FColor> Bitmap;
FIntRect Rect(0, 0, RenderTarget->SizeX, RenderTarget->SizeY);
RenderTarget->ReadPixels(Bitmap, FReadSurfaceDataFlags(), Rect);
FString Filename = GetUniqueFilename(FileNamePrefix, ".png");
FString FullPath = FilePath + Filename;
FFileHelper::CreateDirectory(*FilePath);
FSaveImageDialog::SaveImage(FullPath, Rect.Width(), Rect.Height(), Bitmap.GetData(), nullptr);
}
FString AMyActor::GetUniqueFilename(const FString& Prefix, const FString& Extension)
{
FString Filename;
int32 Number = 0;
do
{
Filename = Prefix + FString::FromInt(Number++) + Extension;
} while (FPlatformFileManager::Get().GetPlatformFile().FileExists(*Filename));
return Filename;
}
```
5. 在子类中添加以下函数:
```cpp
void CaptureScreenshot();
```
这个函数将截图并保存到指定路径。
6. 在子类的cpp文件中实现CaptureScreenshot函数:
```cpp
void AMyActor::CaptureScreenshot()
{
UWorld* World = GetWorld();
if (!World)
{
return;
}
TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsOfClass(World, APlayerController::StaticClass(), Actors);
if (Actors.Num() == 0)
{
return;
}
APlayerController* PlayerController = Cast<APlayerController>(Actors[0]);
if (!PlayerController)
{
return;
}
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
if (!LocalPlayer)
{
return;
}
UTextureRenderTarget2D* RenderTarget = NewObject<UTextureRenderTarget2D>();
RenderTarget->ClearColor = FLinearColor::Black;
RenderTarget->InitAutoFormat(Width, Height);
RenderTarget->UpdateResourceImmediate();
FViewport Viewport(0, 0, Width, Height);
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
Viewport,
World->Scene,
LocalPlayer->ViewportClient->EngineShowFlags)
.SetRealtimeUpdate(true));
FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily);
View->ViewRect = FIntRect(0, 0, Width, Height);
View->UpdateViewMatrix();
View->SetScreenPercentage(100.0f);
FTextureRenderTargetResource* RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource();
View->Family->RenderInterface->Render(View, FTextureRHIRef(), FTextureRHIRef(), RenderTargetResource->GetRenderTargetTexture(), View->ViewRect, false);
SaveScreenshot(RenderTarget, SavePath);
}
```
这个函数使用场景中的第一个PlayerController来获取场景视图,并将其渲染到一个RenderTarget上,然后调用SaveScreenshot函数保存截图。
7. 最后,可以在Actor的BeginPlay函数中调用CaptureScreenshot函数来测试截图功能:
```cpp
void AMyActor::BeginPlay()
{
Super::BeginPlay();
CaptureScreenshot();
}
```
这样就完成了一个具有截图保存功能的Actor。
阅读全文