UE4引擎实现隐藏UI截图拍照并保存到iOS系统相册

需求

Unreal engine隐藏UI截图后保存到系统(iPad)相册

思路

  1. plist中添加相册相关权限
  2. 使用UE截图API获取无UI截图,并保存到项目临时目录
  3. 混编Objective-c原生代码将临时文件复制到系统相册

开发步骤

1.配置plist权限

修改UE配置,位置在:UE引擎>编辑>项目设置>平台>iOS>Extra PList Data>Additional Plist Data
当然也可以直接搜索Additional Plist Data

将下面的配置追加到原有配置里

<key>NSPhotoLibraryUsageDescription</key><string>需要相册权限以保存截图</string>

2.写代码

实现保存iOS相册

c++是可以与objectivec混编的,可以将原生代码直接写到cpp文件中,在UE中可以使用#if PLATFORM_IOS宏来区分平台。

Screenshooter.h
#pragma once

#if PLATFORM_IOS
#import <UIKit/UIKit.h>

@interface Screenshooter : UIViewController <UINavigationControllerDelegate>
+ (void) saveScreenshotNative;
@end

#endif

#include "GameFramework/Actor.h"
#include "Screenshooter.generated.h"

UCLASS()
class AScreenshooter : public AActor
{
    GENERATED_BODY()
public:
    AScreenshooter();
    void onTick(float InDeltaTime);
    //临时截屏路径
    FString screenshot_path = "" ;
};
Screenshooter.cpp
#include "Screenshooter.h"

#if PLATFORM_IOS
    #include "IOSAppDelegate.h"
    #import <Foundation/Foundation.h>
#endif

#if PLATFORM_IOS

@interface Screenshooter()
@end

@implementation Screenshooter
 + (Screenshooter*)GetDelegate
 {
    static Screenshooter* Singleton = [[Screenshooter alloc] init];
    return Singleton;
 }

- (void)saveShot
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"/Game/Saved/Screenshots/IOS/screenshot.png"];
    UIImage *image = [UIImage imageWithContentsOfFile:filePath];
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}

+ (void)saveScreenshotNative
{
    [[Screenshooter GetDelegate] performSelectorOnMainThread:@selector(saveShot) withObject:nil waitUntilDone : NO];
}

@end
#endif

AScreenshooter::AScreenshooter()
{}

void AScreenshooter::onTick(const float InDeltaTime)
{
    //是否有截图需要处理
    if (!AScreenshooter::screenshot_path.IsEmpty()
        && FPaths::FileExists(AScreenshooter::screenshot_path))
    {
        FScreenshotRequest::Reset();
        AScreenshooter::screenshot_path.Reset();
#if PLATFORM_IOS
        [Screenshooter saveScreenshotNative];
#endif
    }
}

截屏实现

头文件

#include "Screenshooter.h"
//...
    public:
        AScreenshooter* m_Screenshooter;
        void OnClickPrtScreenButton();
//...

相关逻辑

//...
//实现拍照
void UInGameWidget::OnClickPrtScreenButton() {
UGameViewportClient::OnScreenshotCaptured().AddStatic(&OnCaptureHandleComplete);
    FScreenshotRequest::RequestScreenshot(TEXT("screenshot.png"),false, false);
    m_Screenshooter->screenshot_path = FScreenshotRequest::GetFilename();
}

//初始化AScreenshooter
void UInGameWidget::OnStart()
{
    m_Screenshooter = NewObject<AScreenshooter>();
}
//每帧检测是否有截图需要处理
void UInGameWidget::tick(const float InDeltaTime)
{
    m_Screenshooter->onTick(InDeltaTime);
}
//...

3.Debug或打包

参考资料
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/FScreenshotRequest/index.html
https://answers.unrealengine.com/questions/164650/how-to-access-ios-photo-library.html
https://answers.unrealengine.com/questions/393721/screenshot-on-ios-dont-show-in-ipad-gallery.html

发表评论

[/0o0] [..^v^..] [0_0] [T.T] [=3-❤] [❤.❤] [^v^] [-.0] [!- -] [=x=] [→_→] [><] 更多 »
昵称

抢沙发~