需求说明
最近公司要在现在的app中加入一个unity游戏页面。因为unity官方提供了android原生和ios原生的接入方法,在接到这个需求的时候,我的第一个想法是自己造轮子,用PlatformView来将unity视图接入到flutter层。后来在调研过程中发现一个插件flutter_unity_widget,看了下他的实现原理,和我想的一致,所以索性就用了这个插件。
版本说明
unity版本:2020.3.19f1
flutter版本:2.2.2
flutter_unity_widget插件版本:4.2.1
接入步骤(Android)
1.下载插件
从github下载flutter_unity_widget的demo项目,下载下来的文件里有下面图片里的文件,这几个文件是这个插件用来和unity交互用的unity包,选择其中的一个,作为package导入unity项目中(我选的v4.1.0)。
2.导出unity android包。
打开unity项目,导入步骤1中所说的包之后,开始构建android引用包,主要注意以下几个配置。
点击export,等待进度条……,完成后会有一个这样目录的文件夹,其中的unityLibrary就是我们需要引入android项目的文件。
3.android引入及环境配置(这个过程就是把unityLibrary作为一个module引入andorid项目)
第一步:将unityLibrary文件夹整个复制到与app同级的目录
第二步:在settings文件中加入如下配置
include ":unityLibrary"
project(":unityLibrary").projectDir = file("./unityLibrary")
复制代码
第三步:在工程的build文件中,加入如下配置
allprojects {
repositories {
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
google()
mavenCentral()
}
}
复制代码
第四步:在app下的build文件中加入对unityLibrary的引用
implementation project(':unityLibrary')
复制代码
第五步:在AndroidManifest.xml文件中加入下面的配置
<activity
android:name="com.xraph.plugin.flutter_unity_widget.OverrideUnityActivity"
android:theme="@style/UnityThemeSelector"
android:screenOrientation="fullSensor"
android:launchMode="singleTask"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:hardwareAccelerated="false"
android:process=":Unity">
<meta-data android:name="com.xraph.plugin.flutter_unity_widget.OverrideUnityActivity" android:value="true" />
</activity>
复制代码
做完上面的步骤,点击编译项目,发现会报错,以下就是解决报错及踩坑的过程
第一个坑:一个有关unityStreamingAssets的错,需要在gradle.properties文件中加入下面的配置
unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist
复制代码
第二个坑:原项目中的ndk版本不支持unity,需要修改ndk版本,改为unity项目里下载的支持unity版本
第三个坑:对于unity-classes.jar的重复引用,需要将unityLibrary目录下的build文件里这一行引用中的implementation改为compileOnly
到此为止,项目终于是可以运行起来了,运行起来之后发现在启动列表里,有两个app图标,删除unityLibrary目录下的AndroidManifest.xml文件里的两行代码,如下
以上为android引入unity的全部配置。
4.flutter_unity_widget使用
1.yaml文件中引入flutter_unity_widget插件
flutter_unity_widget: 4.2.1
复制代码
2.在页面里加入UnityWidget组件
运行之后发现打开此页面之后报错,有一个资源错误,需要在app的资源文件中加入下面的资源
<string name="game_view_content_description">Game view</string>
复制代码
到此为止,终于能看到我们的unity页面了,激动片刻,发现又有新的问题,继续爬坑……
5.有关页面退出的问题
第一个问题:退出时报错
打开unity页面,然后退出,再次进入,会有报错。我目前的解决办法是,在退出页面时调用pause方法暂停unity播放器,再次进入页面时调用resume方法重启播放器(重启时的50ms延时很重要)。
第二个问题:内存问题
页面退出后只是暂停了unityPlayer,所以它所占的资源并没有释放,如果unity项目很大的话,会占用大量内存,我暂时的解决方案是:在退出页面时,将unity切换到一个空场景下,把之前的场景资源卸载掉,这样会释放一部分内存。
第三个问题: 打开unity页面之后,activity会被强制沉浸式全屏,退出页面之后,flutter的其他页面依旧是沉浸式全屏状态(因为所有flutter页面其实是在一个activity内)。
我目前的解决方案是,创建了一个插件,在退出页面时,调用原生代码,强制非沉浸式全屏。
这两行代码可以做到状态栏隐藏,向下滑动出现,但是无法做到取消沉浸式。可能是我的取消全屏的代码不太对,大家有什么更好的方法的话,可以在下面评论。
目前android项目能运行,也基本可用,估计马上就要发第一个arpha版本。ios在打包的时候遇到了问题,无法引用unity的framework,正在解决。继续踩坑……