Notes:
URAS 工程隔离模式当前版本为试验性功能,使用 Mono 作为 Backend,因 Mono 运行性能相较 IL2CPP 稍差,因此,工程隔离模式更关注 Client 工程在开发流程上的独立性和灵活性,在性能上暂无明显优势。
URAS 工程隔离模式下,资源集中于各 Client 工程,Service 工程仅承担通用配置、管线等通用设置,为各 Client 提供公共依赖支持。该模式支持各 Client 项目独立开发与更新,可提升了团队间开发协作的灵活性与开发效率。当前模式采用 Mono 作为 Backend,更加适用于功能模块解耦和协作开发的场景。若项目对系统整体性能有更高要求,可参考 URAS 非工程隔离模式。如需了解更多技术细节,欢迎联系商务团队。
本文档为URAS(工程隔离模式)的开发流程介绍和关键操作文字版说明。URAS Demo Package 已上线,可直接在团结引擎中学习如何使用 URAS,详情请查看 URAS Demo Package
URAS(工程隔离模式)现已支持 Asset Bundle 和 Addressable, 请使用最新版团结引擎,可查看 AssetBundle & Addressable in URAS
URAS 工程隔离模式下存在部分限制,一个 Service 及其对应的 Client,需要使用:
相同的渲染管线,相同的 Settings
相同的引擎版本
相同的 Color Space
Render As Service,英文简称为URAS,下同。
工程隔离模式是在 URAS 的基础上新增的模式
因工程隔离模式面向多进程,此文档着重介绍多进程开发模式 Client 端和 Service 端操作说明
Notes:工程隔离模式 URAS 要求 Client 和 Service 使用相同的渲染管线
Notes:
Service端 的操作是为了导出 Service APK,因此需
Service 端仅需 Build 一次,此后无需修改,可反复使用
在顶部菜单栏点击 File >> Build Settings
在弹出的 Build Settings 窗口中
点击 HMI Android
勾选 Project Separation Mode (勾选之后即为工程隔离模式)
将 [Export as Render Service] 设置为 Project Separation Service Mode (注意:选择 Project Separation Service Mode 模式时上面的 Scenes In Build 相关的功能会被禁用,因为此模式下不需要设置相关参数)
在 [Service Package Name] 中配置导出的 Service 包名;若只有单个 Service,用默认包名 com.tuanjie.renderservice 即可
点击 Switch Platform
点击 Build >> Build Bundle(s)/APK(s) >> Build APK(s)
点击launcher >> Edit Configurations,打开对应面板并将 Launch 改为 Nothing,点击 Apply 应用设置
右下角显示 build 的进度,完成之后可通过点击 locate 定位到该 apk
Notes:
为了开发运行在 Service上 的多个Client APK,因此需:
Step1:使用 Tuanjie Editor 开发 3D 场景,并导出包含 RenderServiceLibrary 包的 Android Studio 工程
Step2:
在 Tuanjie Hub 中新建一个3D(URP)工程(推荐3D URP,其他管线同样支持,但需要保证 Service 和 Client 渲染管线一致)
点击顶部菜单栏 File >> Build Settings
在弹出的 Build Settings 窗口中
切换 HMI Android 平台
勾选 Project Separation Mode (勾选之后即为工程隔离模式)
将 [Export as Render Service] 设置为 Project Separation Client Mode
点击 Switch Platform
切换至 HMI Android 平台后,Editor里已集成完整的 URAS 功能
选择需要使用 URAS 的 Camera
在该 Camera 的 Inspector 面板中,找到 Camera 下的 Target Display 参数
注意:若有Canvas,Screen Space - Overlay模式的Canvas的 Target Display 需要与对应相机的 Target Display 参数保持一致。
Touch事件处理的sample code:
void HandleTouch()
{
for (int i = 0; i < 10; i++)
{
#if ENABLE_INPUT_SYSTEM
if(i < Touch.activeTouches.Count)
{
var touch = Touch.activeTouches[i];
Vector3 touchPos = touch.screenPosition;
Debug.Log($"Get touch position {touchPos} at display {touch.displayIndex}");
}
#else
if (i < Input.touchCount)
{
Touch touch = Input.GetTouch(i);
Vector3 touchPos = touch.position;
Debug.Log($"Get touch position {touchPos} at display {touch.displayIndex}");
}
#endif
}
}
点击顶部菜单栏 File >> Bulid Settings
再次确认 [Export as Render Service] 设置为 Project Separation Client Mode
在 [Client Assembly Name] 中配置导出的 dll 的名字,(注意:更改期间会禁用Build功能,更改结束后会重新编译工程中的脚本文件,编译结束后可进行其他操作)
点击 Export,选择任一位置导出
Notes:
根据需求,选择其一操作:
导入 RenderServiceLibrary 包并配置
找到打包出的工程文件中的 RenderServiceLibrary 包
将 RenderServiceLibrary 包导入原生 Android Studio 工程
在原生 app 的 build gradle 中添加 implementation project (’:RenderServiceLibrary‘)
,路径根据需求可修改
implementation project(":renderServiceLibrary")
TuanjieView配置
TuanjieView 创建时,tuanjieServicePkgName 参数需要指定 service 包名进行绑定;tuanjieDisplay 参数需要与Editor中设置的Camera Target Display 参数保持一致,可参考:
xml
<com.unity3d.renderservice.client.TuanjieView
android:id="@+id/tuanjieView1"
android:layout_width="match_parent"
android:layout_height="275dp"
app:tuanjieViewType="SurfaceView"
app:tuanjieDisplay="1"
app:tuanjieRenderFrameInterval="1"
app:tuanjieServicePkgName="com.tuanjie.renderservice" />
Service 启动/停止调试
启动渲染服务可以调用 ensureStarted 方法
停止渲染服务调用 ensureStopped 方法
mStartServiceBtn =findViewById(R.id.startServiceBtn);
mStartServiceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onclick(View view) {
Log.d(LOG_TAG,msg:"onClick To Start TuanjieRenderService");
mTuanjieRenderService.ensureStarted();
}
});
mStopServiceBtn = findViewById(R.id.stopServiceBtn);
mStopServiceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onclick(View view) {
Log.d(LOG_TAG, msg: "onclick To Stop TuanjieRenderService");
mTuanjieRenderService.ensureStopped();
}
});
在 Android Studio 中打开上文中导出的 Android Studio 工程文件
TuanjieView 配置同上文
渲染服务调试同上文
启动渲染服务调用 ensureStarted 方法
停止渲染服务调用 ensureStopped 方法
在初始化、启动和停止 Service 时也需要传入包名
同 Service 端操作
Notes:为了在工程隔离模式下实现场景切换需求,因此新增了以下3个 API 供用户使用:
SceneManagement.SceneManager.RenderServiceAddSceneAsync(string sceneName)
使用此异步 API 向 service 请求 additive 增加新的场景,需要使用 sceneName 作为参数传入
SceneManagement.SceneManager.RenderServiceRemoveSceneAsync(string sceneName)
使用此异步 API 向 service 请求移除场景,需要使用 sceneName 作为参数传入
SceneManagement.SceneManager.RenderServiceReplaceSceneAsync(string unloadSceneName, string loadScenename)
使用此异步 API 向 service 请求替换场景,需要使用 unloadSceneName 作为需要移除的场景名,使用 loadScenename 作为需要 load 的场景名
以下 API 是为了解决 URAS 本身为了解决多个相机内容 culling 而需要占用 layer 使用的问题,会导致用户无法像一般情况下,通过 layer 来进行逻辑处理的问题,新增的 API 通过修改当前 scene 的 SceneCullingMask 参数来对整个场景中的物体进行 culling,用以区分不同相机的渲染内容。默认情况下 Service 会在 Client 链接时为各个 Client 分配各自的 SceneCullingMask ,不需要手动设置。
SceneManagement.SceneManager.GetRenderServiceSceneCullingMask(Scene scene)
使用此 API 查询此场景的 SceneCullingMask 参数值,需要使用 scene 作为参数传入,返回值为 culing 类型
SceneManagement.SceneManager.SetRenderServiceSceneCullingMask(Scene scene, int renderServiceSceneCullingMaskLayer)
使用此 API 设置此场景的 SceneCullingMask 参数值,需要使用需要使用 scene 和 renderServiceSceneCullingMaskLayer 作为参数传入, renderServiceSceneCullingMaskLayer 的范围为(0 - 59),此 API 会将此 scene 中的所有物体的 SceneCullingMask 都设置为此值,只有 SceneCullingMask 为此值的相机才会渲染此 Scene 中的物体