差不多玩Unity已经玩了4年了,几乎没啥机会去真正研究Unity是如何build APK,也没仔细研究过Unity在安卓端到底是怎么个工作原理,毕竟都是业余时间自己做手游玩。最近在给游戏做微信登录相关的feature,不得已还是要研究一下Unity和Android是怎么玩在一起的。虽说网上倒是有好几篇挺不错的攻略,然而实际做起来却发现是一堆又一堆的坑。因为很多东西在网上并没有什么很好的答案,只能一步步试错,摸爬滚打。所以我就发誓说要是最后搞定了一定把插件的代码开源(然而写的差不多了发现和网上给出的代码长得几乎是一样的)再写篇文章,可能很多解决方法不是最优解,也希望能做到抛砖引玉,同时也希望能帮到一些卡在和我遇到的问题相似的“叫Google Google不灵,叫Baidu Baidu不应”的问题的人。具体的一些实现细节可以参考
两篇我认为对我算是帮助最大的文章:Android 和 Unity 交互 Unity 接入各种第三方登录
关于 Unity 的插件,很喜欢这个老哥的提议,目前的extend UnityPlayerActivity的方法的确是有点傻。No more extending UnityPlayerActivity
插件的兼容性
有可能是网上写出相关攻略的大佬都忽略了这个点,就是当你想给你的Unity项目添加微信登录相关功能时,一些你正在使用的基于安卓原生的插件可能会对此产生影响。
以我的项目为例,我们使用了DeepLinkPlugin(实现deep link,我们是用来实现玩家通过URL拉起我们游戏并接受游戏邀请), UniPasteBoard(实现将内容复制到剪切板)和 JPush (我们是用极光推送实现的推送,这里要给极光推送点赞,算是少有的提供了Unity SDK、SDK好用、文档齐全的第三方服务)。后两者好说,因为不需要改变APK最先启动的Activity,它们可以理解为写了一些Java Class并在Unity中提供了调用它们的方法。而上述提到的DeepLink Plugin就是标准的extend了UnityPlayerActivity的插件,它相当于extend了本来Unity build出来的APK最先启动的Activity,并将其作为了新的最先启动的Activity。而实现可以在Unity中调用的微信登录相关的插件,也需要extend UnityPlayerActivity 并将新的Activity作为最先启动的Activity。也就是说,如果我想在支持微信登录的同时继续使用DeepLink Plugin,除非我拿到它的source code把我的微信登录加到他实现的类里面,不然我就得放弃使用它(和 No more extending UnityPlayerActivity 这篇文章中提到的窘境类似)。
只是会出现类似找不到Package Manager这样奇怪的错误(我猜测可能和intent的属性和设置有关)。因为对于安卓实在不熟悉,网上也没找到非常有用的解释,所以没有办法啦,毕竟微信登录还是得做啊,所以也就放弃了DeepLink Plugin,转而编写自己的MainActivity作为Unity的新入口。因为DeepLink这相关的功能也并不难,所以就准备以后把相关功能加到支持微信登录的安卓原生插件里面。我目前的计划是通过extend UnityPlayerActivity来写一个整合了所有安卓原生插件的类,用来支持比如微信登录、支付,微博登录,支付宝支付等相关的功能。
Package Name 和 Signature
很多网上相关的文章都有提到这一点,就是你写插件的项目,无论你是用eclipse还是用Android Studio,你的package name一定要和你的Unity 项目的package name相同。另外一个就是当你把你的APK装到手机上以后,记得用微信提到的签名获取工具获得签名并提交到微信开放平台。
几个有趣的情况:
几个有趣的错误情况
所以倒是有几个点要反复确认:
1. Unity Build APK的时候用的package name已经要和你在微信开放平台注册应用后填写的一摸一样
2. 写的支持微信登录的包,比如各种攻略中的com.example.wechat_plugin.MainActivity和com.example.wechat_plugin.wxapi.WXEntryActivity,已经要改成 <你的package name>.MainActivity和<你的package name>.wxapi.WXEntryActivity
3. 应用的签名一定要对
4. 在Unity中添加如正确的AndroidManifest.xml并加入类似下图的设置:
AndroidManifest.xml Sample
回到Unity
这个最后一个“坑”算是一个非常特殊的地方,我个人感觉是因为我对于安卓应用Activity以及Intent的详细概念不够熟悉。当我配置好了所有改配置的东西,我的游戏可以正确拉起微信,我可以对我的游戏进行授权并将微信返回的code传回我的游戏(P.S. 我们的设计是AppSecret放在server测,所以客户端和微信的交互仅限于拿到code,和几个基础的验证接口,在这个case中如果从微信拿到code就大功告成了)。只是,这个“进行授权”以后,我只能看到一个黑屏,我可以点击下方的返回按钮或者使用我测试机上的返回按钮来回到我的游戏中。我怀疑是微信通过.wxapi.WXEntryActivity回调并传回了code,但是因为UnityPlayerActivity的特殊性,应用并没有回到(加载?)UnityPlayerActivity这个Activity。尝试了很多方法,都没能成功,玩了个骚操作,在 .wxapi.WXEntryActivity.onResp 中加了一个“super.onBackPressed();” 想不到居然成功了,拿到了code,回到了我的游戏。当然我感觉这个不是一个特别好的解决方案,因为 super.onBackPressed() 有其局限性。也希望如果有哪个大佬可以指条明路,优化一下这个地方(或者我其实写错了的话,fix 一下这个地方)









网友评论