Flutter集成unity踩坑之旅

·  阅读 2136

需求说明

最近公司要在现在的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)。

image.png

2.导出unity android包。

打开unity项目,导入步骤1中所说的包之后,开始构建android引用包,主要注意以下几个配置。

image.png

点击export,等待进度条……,完成后会有一个这样目录的文件夹,其中的unityLibrary就是我们需要引入android项目的文件。

image.png

3.android引入及环境配置(这个过程就是把unityLibrary作为一个module引入andorid项目)

第一步:将unityLibrary文件夹整个复制到与app同级的目录

image.png

第二步:在settings文件中加入如下配置

image.png

include ":unityLibrary"
project(":unityLibrary").projectDir = file("./unityLibrary")
复制代码

第三步:在工程的build文件中,加入如下配置

image.png

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文件中加入下面的配置

image.png

unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist
复制代码

第二个坑:原项目中的ndk版本不支持unity,需要修改ndk版本,改为unity项目里下载的支持unity版本

image.png

第三个坑:对于unity-classes.jar的重复引用,需要将unityLibrary目录下的build文件里这一行引用中的implementation改为compileOnly

image.png 到此为止,项目终于是可以运行起来了,运行起来之后发现在启动列表里,有两个app图标,删除unityLibrary目录下的AndroidManifest.xml文件里的两行代码,如下

image.png 以上为android引入unity的全部配置。

4.flutter_unity_widget使用

1.yaml文件中引入flutter_unity_widget插件

flutter_unity_widget: 4.2.1
复制代码

2.在页面里加入UnityWidget组件

image.png

运行之后发现打开此页面之后报错,有一个资源错误,需要在app的资源文件中加入下面的资源

image.png

<string name="game_view_content_description">Game view</string>
复制代码

到此为止,终于能看到我们的unity页面了,激动片刻,发现又有新的问题,继续爬坑……

5.有关页面退出的问题

第一个问题:退出时报错

打开unity页面,然后退出,再次进入,会有报错。我目前的解决办法是,在退出页面时调用pause方法暂停unity播放器,再次进入页面时调用resume方法重启播放器(重启时的50ms延时很重要)。

image.png

第二个问题:内存问题

页面退出后只是暂停了unityPlayer,所以它所占的资源并没有释放,如果unity项目很大的话,会占用大量内存,我暂时的解决方案是:在退出页面时,将unity切换到一个空场景下,把之前的场景资源卸载掉,这样会释放一部分内存。

第三个问题: 打开unity页面之后,activity会被强制沉浸式全屏,退出页面之后,flutter的其他页面依旧是沉浸式全屏状态(因为所有flutter页面其实是在一个activity内)。

image.png

我目前的解决方案是,创建了一个插件,在退出页面时,调用原生代码,强制非沉浸式全屏。

image.png 这两行代码可以做到状态栏隐藏,向下滑动出现,但是无法做到取消沉浸式。可能是我的取消全屏的代码不太对,大家有什么更好的方法的话,可以在下面评论。

目前android项目能运行,也基本可用,估计马上就要发第一个arpha版本。ios在打包的时候遇到了问题,无法引用unity的framework,正在解决。继续踩坑……

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改