Unity3D打包android游戏

平时我们都会用手机玩游戏,而有些方式是用Unity3D来开发的。这次我们来探究一下,Unity3D的android游戏是怎么形成的。

一.配置开发环境

首先要说明的一点是unity3D游戏的打包不是android接入游戏内容打包的,而是游戏接入android内容打包的,就是说一般是在unity中进行打包,而不是在androidstudio中,当然也可以在unity中导出项目用androidstudio打包。

首先下载unity开发环境。



在官网找到穷B版下载,然后跟着流程安装就行,如果没有Visual Studio的话,在安装过程中会顺便帮你安装,至少我下载的版本是这个的,环境大概占4G多内存,一定要留出足够的空间。


打开后发现主要分两部分,上面是画布,下面是放脚本。

之后打开AndroidStudio,准备写代码。

二.Unity3D对接android

两块的对接,主要是把android代码丢到Unity中,android代码可以打jar包,也可以打aar,我这里主要讲jar包

1.android部分

先说说android部分,要让unity游戏展示在android的Activity中,需要让这个Activity继承UnityPlayerActivity。当然我们默认的androidSDK中是没有这个类的,我们可以从之前下载的unity中找到。
这个包的位置在
你下的unity的文件\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes


把这个jar包放到android项目中引用就行。还需要注意的一点是这个包的路径不一定在这个文件夹下,我不能保证之后的版本不会变,当前我用的版本是在这里,但不管怎样都可以在Unity中找到。
我android端的代码很简单,就写一个方法用Log打印一句话。

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public void say(String str){
        Log.v("mmp",str);
    }

}

还需要注意的一点是,这个Activity是供Unity的游戏展示的,所有不能写setContentView方法,不然显示的就是本地的xml页面

这样android端就写完了,之后我们打jar包。在gradle中加入jar包命令

task makeJar(type: Jar) {
    archiveName = 'wang.jar' //最终jar包的名称
    from(project.zipTree('build/intermediates/packaged-classes/release/classes.jar')) //需要打的juhepaysdk的编译文件
    destinationDir = file('build/libs') //jar包输出路径
}
makeJar.dependsOn(build)

关于打jar包,很多人之前说在以前的bundle目录中找不到classes.jar,是因为现在的classes.jar换成了在packaged-classes目录下,而且我们也依然不能保证以后的版本不会换,反正找不到的话可以自己在intermediates目录下找。
还有一点是我仅仅打了代码到jar包中,没有和引用到的jar包一起打,因为引用的包可以直接扔到unity中,没必要一起打包,之前网上也有人说一起打也不会影响。
打完jar包之后android这边算是完成了,接下来看看unity端要怎么做处理。

2.unity部分

我们先画图,关于Unity3D其实我不太知道怎么用,但是画一个Button还是难不倒的。



右键Canvas然后选UI再选Button,在右边栏可以选择这个UI的属性。


我们先把这个unity的范围设置成我们手机的范围,这个会更清楚的看出按钮显示在手机上的预览图。按照图中的顺序设置



在中间的预览窗口点击Game,并且在图中的位置设置尺寸,我这里设置1920 x 1080竖屏,然后把按钮拖到中间。

这样我们算是把图简单画好了,接下来我们给控件设置脚本。我对Unity的开发不是很了解,但是好像他能为每个对象设置一个脚本。我们用C#写一个脚本设置给上面的Canvas对象,这样这个对象就能执行这个脚本,注意是设置给最外层的Canvas对象而不是里面的Button对象。

(1)先写C#脚本
public class Test : MonoBehaviour
{

    private AndroidJavaClass jc;
    private AndroidJavaObject jo;
    // Start is called before the first frame update
    void Start()
    {
        jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        jo = jc.GetStatic<AndroidJavaObject>("currentActivity");

        GameObject btnObj = GameObject.Find("Canvas/Button");
        Button btn = (Button)btnObj.GetComponent<Button>();
        btn.onClick.AddListener(onClick);

    }

    void onClick()
    {
        jo.Call("say", "fuck");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

不懂C#也没关系,至少写一个点击事件还难不倒我们,代码中脚本名为Test,AndroidJavaClass和AndroidJavaObject是C#和java通讯的类,这两个类的命名真的是教科书般的命名。

        jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        jo = jc.GetStatic<AndroidJavaObject>("currentActivity");

获取到android类是这样的固定写法,调用类中的方法用Call函数,第一个参数是java那边定义的方法名,后面的参数是方法的参数。

        GameObject btnObj = GameObject.Find("Canvas/Button");
        Button btn = (Button)btnObj.GetComponent<Button>();
        btn.onClick.AddListener(onClick);

这里是获取到Canvas下的Button对象,然后设置点击事件。这里只是简单的讲,有兴趣的可以自己去找详细的API。

代码写好之后把脚本添加给Canvas。



点击1中的Add Component,选着Test脚本,添加后就像2一样显示。同样,如果想移除脚本的话可以右键2的地方选着移除。

这样就把脚本添加成功了。那么现在是怎样的情况呢?点击按钮,就会执行脚本中的监听事件,调用AndroidJavaObject的Call方法,调用到android中的say方法。

最后,我们需要把android中的内容添加到unity中,最后打包的时候才会一起打进去。



如图一样,在Assets中创建Plugin文件夹,在创建Android文件夹,下面创建libs和res。



libs中放入wang.jar,就是我们上面打的包,wang.jar里面是不是调用了android的东西,我这里用的是v4,所以要把一个android的v4包也放进去,不是也用了unity的jar吗?没错,但是这个在打包时会提供,所以这里我们没必要重复放unity的jar包进去。注意了,不放unity的jar包进去。
res下就放android项目中res下的内容。

最后还要把manifest文件放到android文件夹下



这样就只剩最后的打包了。

三.打包

上边已经把android的内容加到unity中了,我们就可以在Unity中打android的apk包了。
还是多说一句,记得要在Edit -》Preferences -》External Tools中设置SDK路径


打包方法是点击File -》 Build Settings



选着player setting,在3中设置得和项目中的gradle一样。
可以看出在Build System中选中的是Gradle,所以unity最后会调用Gradle工具来进行打包。
打包过程中如果出错的话,可以在Console中查看错误日志


这里再讲一个比较坑的地方
我第一次打包时报了一个错,报文件重复。

CommandInvokationFailure: Gradle build failed. 
D:\u3d\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\OpenJDK\Windows\bin\java.exe -classpath "D:\u3d\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-4.6.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"

stderr[
D8: Program type already present: com.example.kylin.androidunitydemo.BuildConfig
java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: D:\testu3d\TestOne\Temp\gradleOut\build\intermediates\transforms\dexBuilder\release\8, D:\testu3d\TestOne\Temp\gradleOut\build\intermediates\transforms\externalLibsDexMerger\release\0, D:\testu3d\TestOne\Temp\gradleOut\build\intermediates\transforms\dexBuilder\release\7.jar
Program type already present: com.example.kylin.androidunitydemo.BuildConfig
Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.

我按照提示找到文件夹,发现重复的文件是BuildConfig。于是我的做法是把jar包的BuildConfig删除(先解压,再删除,再压缩)就正常了,合着unity打包的时候还会给你打进去一个BuildConfig。
虽然我能解决了这个问题,但不知道有没有更好的方法,不然难道每次都要删除jar包的文件吗,这样岂不是很麻烦。

按照上面的操作,我们就能打出一个可以运行的apk文件了,我测试过可以运行,Gif软件被我删了,这里就不演示了,不过我们可以反编译看看unity做处理之后的结构。可以看出多了很多文件。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容