.. _7 进阶功能: 7 进阶功能 ============================ 7.1 配置EyeBuffer大小 ----------------------------------------------------- SDK支持响应Unreal的“vr.pixeldensity”命令,开发者可以通过该命令来配置EyeBuffer(RenderTexture)的大小。 使用方法: 方式一:打开文件 Project/Config/DefaultEngine.ini,然后在“[/Script/Engine.RendererSettings]”标签下添加字符串“vr.pixeldensity=1”,如果该命令等于一或者没有该命令,则EyeBuffer大小为Pico的默认大小,如果该值不等于一,则会在Pico默认的EyeBuffer大小的基础上进行缩放。 如下图所示: .. image:: _static/9.1.png 图7.1 设置EyeBuffer大小 方式二:可以通过蓝图调用控制台命令实现该效果。使用节点“Execute Console Command”节点,调用“vr.pixeldensity 1”命令(命令中字符串和数字之间有一个空格)。同样数字部分为EyeBuffer的倍数。但是要保证该命令的执行必须足够早,建议放在关切蓝图的EventBeginPlay后。 .. image:: _static/9.0.png 图7.2 设置EyeBuffer大小 原通过项目设置 > 插件 > PicoMobile中的“Multiples of RT size”参数配置EyeBuffer大小的功能已废弃。 Tips: 建议开发者不做修改,仅在特殊需求场合使用自定义RenderTexture大小。对于该选项开发者必须了解以下两点: - RT设置过小,会带来性能的提升,减少延迟,但同时也导致了分辨率降低; - RT设置过大,会带来性能的降低,增加延迟,因此不建议RT设置超过硬件建议纹理尺寸; - 目前RT可设置参数大小范围为0.5 - 2 7.2 眼球追踪 -------------------------------------------------------- Pico Neo2 Eye设备支持眼球追踪, 眼球追踪可以追踪眼球注视位置,配合注视点渲染可以优化渲染性能。眼球追踪功能的开关在 项目设置 > 插件 > PicoMobile,勾选“EnableEyeTracking”即可打开眼球追踪功能。如图: .. image:: _static/9.2.png 图7.3 眼球追踪 可以通过以下阶段获取眼球的位置与方向。 +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.2.1.png |功能 |获取眼球的位置和方向(仅Neo2 Eye支持, | | | |需在项目设置中勾选"Enable Eye Tracking") | + +------------------+---------------------------------------------------------------------------+ | |输入 | 无 | + +------------------+---------------------------------------------------------------------------+ | |输出 |眼球的位置和方向 | + +------------------+---------------------------------------------------------------------------+ | |返回值 |True:成功,False:失败。 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ 7.3 注视点渲染 -------------------------------------------------------- 注视点渲染(Foveation Rendering)可以优化VR场景的渲染,该技术通过为视野中心提供全分辨率(无损),降低周边视野(人眼焦点区域之外)分辨率的方式来达到优化渲染的目的。 这里提供了两种使用注视点渲染的方式: 方法一:在打包之前,可以在“ 项目设置 > 插件 > PicoMobile”中勾选“Enable FoveationRendering”开启注视点渲染功能,并在“Foveation Level”下拉框指定Level即可(SDK默认提供了三个Level:Low/Med/High)。 .. image:: _static/9.3.png 图7.4 FoveationRendering设置 方法二:打包之后,可以通过蓝图节点动态的修改Foveation Rendering的level(注意:打包前,必须勾选“Enable FoveationRendering”开启注视点渲染功能)。 +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.3.1.png |功能 |获取Foveation Rendering等级 | + +------------------+---------------------------------------------------------------------------+ | |输入 | 无 | + +------------------+---------------------------------------------------------------------------+ | |输出 |Foveation Rendering等级 | + +------------------+---------------------------------------------------------------------------+ | |返回值 |True:成功,False:失败。 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.3.2.png |功能 |设置Foveation Rendering等级 | + +------------------+---------------------------------------------------------------------------+ | |输入 |Foveation Rendering等级 | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 |True:成功,False:失败。 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.3.3.png |功能 |设置Foveation Rendering参数 | + +------------------+---------------------------------------------------------------------------+ | |输入 |Foveation Rendering控制参数 | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 |True:成功,False:失败。 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ - Foveation Gain:Vector2类型,X/Y轴方向外围像素的缩减率,值越大缩减的越多。 - Foveation Area:float类型,以注视点为中心,以Foveation Area值为半径的范围内保持全分辨率。 - Foveation Minimum:float类型,最小像素密度限制。 - Foveation Level:提供了Low,Med,High,Top High四种预定义选择。每种级别对应了不同的Foveation参数。 注:除非开发者对“Foveation Rendering”技术有深入的了解,可以使用自定义参数来调整FFR优化细节,否则建议开发者使用官方预定义Level。SDK提供四种种Level: Low [3.0f, 3.0f, 1.0f, 0.125f] Med [4.0f, 4.0f, 1.0f, 0.125f] High [6.0f, 6.0f, 1.0f, 0.0625f] Top High [7.0f, 7.0f, 0.0f, 0.0625f] 7.4 用户权限验证 -------------------------------------------------------- 为了保护开发者内容的版权,SDK提供了用户权限验证功能,分别在内容研发调试阶段和正式发布到Pico应用商店提供用户权限验证。 功能入口:Project Setting -> Plugins -> PicoMobile -> Platform,勾选 User Entitlement Check选项。 用户权限验证不要求用户联网,SDK提供验证结果的返回码,但不会做额外处理,开发者需要在程序中自行处理验证失败的情况。 比如,如果收到“未成功”的结果,向用户展示失败原因并退出应用,或者进入Demo模式,提示用户去Pico应用商店购买完整版内容。 7.4.1 开发调试阶段模拟权限验证 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 在研发阶段,开发者通过在配置界面填入开发机SN号模拟用户权限验证过程,并增加验证失败后的处理逻辑,以测试效果。 确保User Entitlement Check选项勾选的前提下,勾选 Entitlement Check Simulation选项,开启开发调试阶模拟权限验证。 Device SN通过Project Setting->Plugins->PicoMobile->Platform中的Device SN Code List传入。 .. image:: _static/9.4.png 图7.5 用户权限验证模拟 7.4.2 正式上线后的权限保护 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 通过AppID获取用户是否具有应用要求的权限。APPID是Pico开发者平台分配给应用的唯一识别ID,可通过 https://developer.pico-interactive.com/developer/overview 申请和查看。 在最新的SDK中,通过Project Setting->Plugins->PicoMobile->Platform下的App ID传入App ID,SDK在应用启动时执行权限验证。 开发者可以通过“Pico Entitlement Verify Set Callback Delegates”接口绑定代理来获取校验结果。 权限验证回调结果蓝图: +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.4.2.1.png |功能 |返回验证结果code | + +------------------+---------------------------------------------------------------------------+ | |输入 | 无 | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 | 无 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ 权限验证结果如下表所示: +---------------------------------------------------------+---------------------------------------------------------+ |Code |含义 | +---------------------------------------------------------+---------------------------------------------------------+ |0 |成功 | +---------------------------------------------------------+---------------------------------------------------------+ |-2 |服务不存在 | +---------------------------------------------------------+---------------------------------------------------------+ |-3 |服务绑定失败 | +---------------------------------------------------------+---------------------------------------------------------+ |-4 |捕获异常代码 | +---------------------------------------------------------+---------------------------------------------------------+ |-5 |超时未收到服务返回值 | +---------------------------------------------------------+---------------------------------------------------------+ |10 |单击Home键 | +---------------------------------------------------------+---------------------------------------------------------+ |11 |APPID缺失 | +---------------------------------------------------------+---------------------------------------------------------+ |13 |包名和APPID不匹配 | +---------------------------------------------------------+---------------------------------------------------------+ |20 |用户未登录 | +---------------------------------------------------------+---------------------------------------------------------+ |21 |用户未购买 | +---------------------------------------------------------+---------------------------------------------------------+ |31 |未查询到此应用 | +---------------------------------------------------------+---------------------------------------------------------+ |32 |购买SN号与本机SN号不匹配 | +---------------------------------------------------------+---------------------------------------------------------+ **注意:** 模拟验证中填入SN号的开发机,在内容上线到Pico应用商店后,默认通过用户权限验证验证,不会再进行正式的权限验证。 如果需要开发机在应用上线后也进行正式的用户权限验证,请在编译正式版本时,关闭“Entitlement Check Simulation”。 7.5 MultiView -------------------------------------------------------- 如果想要开启MultiView,需要进入Unreal Editor > Settings > Project Settings > Engine > Rendering > VR,然后选择Mobile Multi-View和Mobile Multi-View Direct两个。必须同时勾选以上两项才能起效。注意 : MultiView功能开启需要在OpenGL ES3.1条件下,OpenGL ES2 不支持MultiView。 .. image:: _static/9.5.png 图7.6 开启MultiView 7.6 Pico VR Compositor Layers(StereoLayer) ---------------------------------------------------------- StereoLayer是UE4引擎提供的Layer组件,在VR中,可将单独的纹理发送至VR头戴,并将其重新投射到和不同于项目其他内容的单独渲染通道中。 .. image:: _static/9.6.png 图7.7 场景中的overlay .. image:: _static/9.7.png 图7.8 Stereo Layer相关属性 目前仅支持该组件的以下属性:Texture、Stereo Layer Type、Stereo Layer Shape、Priority、Left Texture、Quad Size。其他属性会在后续版本中逐渐实现。 如何创建一个StereoLayer: 1、 创建一个Pawn,可以拖入到level中。 2、 选择Pawn或者打开Pawn蓝图,添加Component中的Stereo Layer。 3、 Stereo Layer的属性中可以选择Stereo Layer Type有FaceLocked、WorldLocked、TrackerLocked,暂时FaceLocked与TrackerLocked效果相同。 4、 设置Stereo Layer Shape为Quad Layer。 5、 设置Property来确定多个layer的层级关系。 注: 建议不要把Stereo Layer添加到相机组件下。 建议使用正确的坐标位置关系放置模型和叠加层,否则会存在景深冲突,引起视觉不适。 7.7 Pico VR Splash Screen ------------------------------------------- SDK提供了一个在切换场景时显示一张贴图的方式,成为SplashScreen。开启SplashScreen共有两种方式,分别是通过项目设置和使用蓝图。 方式一:使用项目设置来开启SplashScreen: 打开项目设置,依次进入:Plugins->PicoMobile->SplashScreen(配置界面如下): .. image:: _static/9.8.png 图7.9 SplashScreen相关属性 +---------------------------------------------------------+---------------------------------------------------------+ |属性名 |属性作用 | +---------------------------------------------------------+---------------------------------------------------------+ |Enable Auto Show |是否自动显示(只有勾选了切场景是才会显示) | +---------------------------------------------------------+---------------------------------------------------------+ |Texture Path |贴图 | +---------------------------------------------------------+---------------------------------------------------------+ |Transform in Maters |贴图显示的Transform属性,单位为米 | +---------------------------------------------------------+---------------------------------------------------------+ |Quad Size in Maters |显示贴图四边形的大小 | +---------------------------------------------------------+---------------------------------------------------------+ 表7.1Pico VRSplashScreen属性解读 方式二:使用蓝图来开启SplashScreen: +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.7.1.png |功能 |清除SplashScreen当前的属性配置(会设置为不自动显示) | + +------------------+---------------------------------------------------------------------------+ | |输入 | 无 | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 | 无 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.7.2.png |功能 |设置是否自动显示SplashScreen | + +------------------+---------------------------------------------------------------------------+ | |输入 |是否自动显示 | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 | 无 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ | .. image:: _static/7.7.3.png |功能 |设置SplashScreen属性 | + +------------------+---------------------------------------------------------------------------+ | |输入 |Texture、Translation in Meters、Rotation、Size in Maters、 | | | |Auto Show(属性含义见表7.1) | + +------------------+---------------------------------------------------------------------------+ | |输出 | 无 | + +------------------+---------------------------------------------------------------------------+ | |返回值 | 无 | +---------------------------------------------------------+------------------+---------------------------------------------------------------------------+ 7.8 Platform系统 ------------------------------------------- SDK继承了Unreal的OnlineSubsystem模块,实现了其中的部分功能,并开放给开发者。该模块的功能,暂时只支持成就系统。 需要使用Pico提供的OnlineSubSystem模块,需要进行以下步骤 - Step1:启用Online SubSystem Pico 插件 .. image:: _static/7.10.png 图7.10 开启Online Subsystem Pico 插件 - Step2:关闭Plugin->Online Platform 下除Online Subsystem、Online Subsystem Utils插件外的其他插件 - Step3:在[ProjectDirectory]/Config/Android/ 路径下新建AndroidEngine.ini文件,并添加以下内容: .. code-block:: ini [OnlineSubsystem] DefaultPlatformService=Pico - Step4:在[ProjectDirectory]/Source/[ProjectName]/ProjectName.Build.cs文件中添加以下内容来加载必要引擎模块 .. code-block:: cs PublicDependencyModuleNames.AddRange(new string[]{"OnlineSubsystem", "OnlineSubsystemPico" }); - 7.8.1 成就系统 开发者需要登录开发者平台https://developer.pico-interactive.com/,在管理中心中进行成就的定义,具体步骤如下: 1. 点击“查看”进入应用详情页。如果您还没有任何应用,请先“创建应用”。 .. image:: _static/7.11.png 图7.11 开发者平台 2. 在详情页面底部找到并点击“平台服务配置 – 成就”。 .. image:: _static/7.12.png 图7.12 开发者平台 3. 在成就页面可以看到您已创建的所有成就。如果您还没有任何成就,请点击“创建”。 .. image:: _static/7.13.png 图7.13 开发者平台 4. 按要求填写成就的信息。填入的API 名称必须代码中的保持一致。 .. image:: _static/7.14.png 图7.14 开发者平台 以下为成就部分的接口说明: 1、 初始化接口: FOnlineSubsystemPico::InitWithAndroidPlatform(FPicoInitOnCompleteDelegate&& Delegate) 该接口为成就系统的初始化接口,调用该接口,可对成就系统进行初始化,接口传入一个Delegate,返回初始化是否成功。调用该接口需要用户在PUI中登录自己的账号,并需要开发者在Project -> PicoMobile -> Platform中填入其中的对应参数(详见8.11章节)。为防止应用在后台是用户切换账户,该接口要求开发者在每次Resume都需要调用一次。 调用示例如下: .. code-block:: java void UAchievementWidgetClass::InitPicoOnlineSubSystem() { OnlineSubsystemPico*PicoSubsystem=static_cast(IOnlineSubsystem::Get()); if (PicoSubsystem) { PicoSubsystem->InitWithAndroidPlatform(FPicoInitOnCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnInitPicoSubSystemComplete)); } } void UAchievementWidgetClass::OnInitPicoSubSystemComplete(bool Result) { } 注意:以下接口,部分接口不要求先调用初始化接口,部分接口要求初始化,对于需要初始化的接口,仅需整体初始化一次。 2、 向服务器请求所有成就定义并缓存到本地 IOnlineAchievements::QueryAchievementDescriptions(const FUniqueNetId& PlayerId, const FOnQueryAchievementsCompleteDelegate& Delegate)将定义的所有成就的信息缓存到本地,Delegate返回请求是否成功。调用该接口,不需要事先调用初始化接口。调用实例如下: .. code-block:: java void UAchievementWidgetClass:: QueryAchievement() { auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); if (AchievementInterface) { AchievementInterface->QueryAchievements(*UserID, FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnQueryAchievementComplete)); } } void UAchievementWidgetClass:: OnQueryAchievementComplete (const FUniqueNetId& PlayerId, const bool bWasSuccessful) { } 3、 向服务器请求所有成就进度并缓存到本地 IOnlineAchievements::QueryAchievements( const FUniqueNetId& PlayerId, const FOnQueryAchievementsCompleteDelegate& Delegate)接口可以将所有成就的进度信息缓存到本地,Delegate返回请求是否成功。调用该接口,需要事先调用初始化接口和QueryAchievementDescriptions接口。调用示例如下: .. code-block:: java void UAchievementWidgetClass:: QueryAchievement() { auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); if (AchievementInterface) { AchievementInterface->QueryAchievements(*UserID, FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnQueryAchievementComplete)); } } void UAchievementWidgetClass:: OnQueryAchievementComplete (const FUniqueNetId& PlayerId, const bool bWasSuccessful) { } 4、 修改成就进度 IOnlineAchievements::WriteAchievements(const FUniqueNetId& PlayerId, FOnlineAchievementsWriteRef& WriteObject, const FOnAchievementsWrittenDelegate& Delegate) 接口可以修改成就的完成进度。通过WriteObject传入需要修改的成就的名字与要修改的进度,Delegate返回请求是否成功。调用该接口,需要事先调用初始化接口和QueryAchievementDescriptions接口。调用示例如下: .. code-block:: java void UAchievementWidgetClass::WriteAchievement(FString AchievementName, int32 Value) { auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); if (AchievementInterface) { FOnlineAchievementsWritePtr WriteObject = MakeShareable(new FOnlineAchievementsWrite()); WriteObject->SetIntStat(*AchievementName, Value); FOnlineAchievementsWriteRef WriteObjectRef = WriteObject.ToSharedRef(); AchievementInterface->WriteAchievements(*UserID, WriteObjectRef, FOnAchievementsWrittenDelegate::CreateUObject( this, &UAchievementWidgetClass::OnAchievementsWritten)); } } void UAchievementWidgetClass:: OnAchievementsWritten(const FUniqueNetId& PlayerId, const bool bWasSuccessful) { } 5、 获取缓存到本地的所有成就的进度 IOnlineAchievements::GetCachedAchievements(const FUniqueNetId& PlayerId, TArray& OutAchievements) 接口可以获取缓存到本地的所有成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下: .. code-block:: java auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); TArrayAchievements; if (AchievementInterface) { auto State = AchievementInterface->GetCachedAchievements(*UserID, Achievements); } 6、 通过成就名称获取缓存到本地的成就进度 IOnlineAchievements:: GetCachedAchievement(const FUniqueNetId& PlayerId, const FString& AchievementId, FOnlineAchievement& OutAchievement)接口可以通过名字获取缓存到本地的成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下: .. code-block:: java auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); FOnlineAchievement Achievement; if (AchievementInterface) { auto State = AchievementInterface->GetCachedAchievement(*UserID, AchievementName, Achievement); } 7、 通过成就名称获取缓存到本地的成就定义 IOnlineAchievements::GetCachedAchievement( const FUniqueNetId& PlayerId, const FString& AchievementId, FOnlineAchievement& OutAchievement)接口可以通过名字获取缓存到本地的成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下: .. code-block:: java auto AchievementInterface = Online::GetAchievementsInterface(); auto UserID = new FUniqueNetIdPico(0); FOnlineAchievement Achievement; if (AchievementInterface) { auto State = AchievementInterface->GetCachedAchievement(*UserID, AchievementName, Achievement); }