正题:android打jar包到Unity3D的方法及遇到的问题
最近公司在做unity3d游戏方面的业务,从而就遇到了android配合unity3d完成部分功能的需求,比如微信微信登陆、极光推送、电池电量、wifi及运营商信号强度等功能。刚开始我是吧unity3d打包出来作为一个依赖包放进android studio中采取moudle依赖的方式完成需求,可是后面发现在unity中接入第三方sdk后再打包成android工程的时候就会发现无法多重依赖,即 主工程 -> 依赖游戏包,游戏包->依赖,这样的方式是行不通,就算吧游戏包总的依赖工程拖出来和游戏包平级做依赖包给主工程也是问题多多,所以后面就采取了把android library打包成jar依赖进unity中去的方式。这里就不说第一种方式了,主要说说第二种方式怎么做及遇到的坑
按照第二种的方式主要的步骤有如下几种
1、创建新的android工程
2、在android工程中创建新的module
3、在module中写好代码、导入jar包并打包成classes.jar包并生成res资源文件夹
4、把jar包和res文件及module中的AndroidManifest文件copy进入unity中的Assets/Plugins/Android/目录下(如果没有android目录就创建一个)
5、unity中写好脚本文件,进行调用android jar包内的方法
1.创建新的android工程
作为android开发,这一步我就不说了,应该都知道的,如果是unity开发人员请查查资料
2.创建module
(1)studio主面板中File->new->new Modeule,如图:
(2)选择library,下一步,名称随便填写,最后finish。如图:
(3)创建成功后如图所示:
可以看到是一个标准的library格式,这里注意创建成功后需要依赖进主工程,不然编译的时候是不会打包jar的。依赖的方式是鼠标停在app上面右键,出现菜单后点击Open module settings打开模块依赖设置中心,如图所示:
依赖成功后我们就可以开始正式的开始写代码了,简单说下流程,首先把unity中的class.jar包复制进入lirary中的libs文件下,然后创建一个MainActivity主类,继承UnityPlayerActivity,最后在这个类中写入unity调入的方法。
这个地方有点坑,因为我按照网上的资料找Unity包下的class.jar文件始终找不到,先看看网上怎么说的:
windows环境: 在Unity安装目录PlaybackEngines-androidPlayer-release-bin
mac环境: Application中找到Unity,右键打开包路劲,按照上面PlaybackEngines-androidPlayer路劲一层一层找]
这个方法可能在以前是可以找到的,但是我的unity版本号是5.6.5f1,按照步骤走到PlaybackEngines后androidPlayer这个文件夹始终找不到,还反复确认了几次,查了几次资料都没找到,弄得我一脸懵逼,不知道为什么原因,可能是我的unity是破解版的吧。最后没办法,直接用unity打包android工程,把libs下的unity-classes.jar包复制出来了,经过测试发现是没有问题的。如图:
class包搞定后就开始创建MainActivity了,并且继承UnityPlayerActivity这个类,继承后MainActivty就是游戏的入口文件了,也就不需要布局了,直接把setContentView这一行删除,最好把res-layout下的布局也一并删除了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
// EventBusHelper.getInstance().regist(this);
progressDialogUtil = ProgressDialogUtil.getInstance(this);
// jgLogin("zouanfu", "123456");
initGvoice();
}
到这里也就可以把Unity调用android的测试代码加入进来了,这里我们可以toast的一下作为测试,注意要异步线程,不然要崩溃的。
/**
* 定义一个显示Toast的方法,在Unity中调用此方法
*/
public void ShowToast(final String mStr2Show) {
// 同样需要在UI线程下执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), mStr2Show, Toast.LENGTH_SHORT).show();
}
});
}
3.打包module生成jar包及资源文件
打包资源其实就是把整个工程全部build一遍,如图所示,先clean project再rebuild project一遍。
在编译成功后再library/build/intermediates/bundles/debug下查看,如下图所示:
如果在这里一直不生成jar包和资源res,可以在该library build.gradle下anroid节点加入以下代码:
//有时候编译在build中不生成classes.jar包的时候加入这句
lintOptions {
abortOnError false
}
找到这个目录的本地文件夹,把libs下的unity-classes.jar删除,然后把外层的classes.jar复制进入libs下,如下图所示:
完成以后就需要把res和libs文件拖入到unity中的Assets/Plugins/Android/目录下,如下图所示:
这个地方要注意AndroidManifest这个文件,这个文件是从library中复制过来的,简单说下注意的地方:
这段代码只是参考,需要注意的是package的包名,在activity的name中需要附加包名,不然到时候打包出来会找不到,最后复制进入unity目录,位置如上图。而在unity中打包的时候需要在Player Settings中把package name改成和我们的jar包包名一样。如图所示:
最后export打出android工程,用studio打开该工程,编译运行在真机上,查看效果。看看unity打出的工程目录结构:
这里就不写unity如何调用android了,反正挺简单,随便查一下就会了,在要结尾的这里我主要说一下我遇到的几个问题:
第一个问题:遇到classNotfindExp...找不到类的异常,我们要看日志到底是哪一个文件找不到,比如我遇到的有gson,glide,极光的某些类包找不到,解决办法就是我们需要下载各自相应的jar包放在library中然后打包,
第二个问题:打包成功后运行在手机上的时候提示 该硬件不支持此程序
如图所示:
出现这个的原因就是so文件出问题了,要么是so文件是错误的或者找不到,要么就是对不上,比如你的手机cpu是armeabi-v7a的,但是在该包下没有相应的so文件,就会报这个错误,这里造成这个的原因是因为我加了
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
这个代码的意思就是把jnilibs的路劲指向了libs文件夹下,如果你jnilibs下原本没有文件,这样做是没有问题的,假如你jnilibs下本来就有so文件,你这样一指定,这个文件下原本的so文件就找不到了,看图:
加入该代码
unity打出包后的jnilibs目录
编译后把项目结构改成android,再查看jniLibs目录,是不是惊奇的发现原本的libmain.so文件都找不到了
解决办法:把原本jnilibs下的so文件及目录都拷贝到libs下面目录去,编译运行,完美解决。看图:
第三个问题:unity打包出来后报错提示某个style找不到,看图:
在unity-android-resoucse/res/values/values.xml中把标红的样式改成图片中的这个样式就好了,因为错误也是出现在这个地方。
其他的还有些小问题,但是记不住了,反正有些问题网上都能查到,但这三个问题不好查,所以分享出来,希望有不对的地方勿喷。
写到这里也差不多了,如果有不明白的或者有啥问题可以留言,最后提供下地址:
https://github.com/zouanfu/AndroidToUnity里面有两个项目,testJar是android library工程,androidlibrary是加入jar包后unity打出来后的工程。testJar里面写的东西比较多,有微信登陆、微信分享、极光推送、电池电量、wifi等常用的功能,具体的可以下载下来细看。