Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in D:\site\54cainiao\web\config\function.php on line 295 Android/Unity大乱斗-完整双方集成交互指南 - 54菜鸟
11

Android/Unity大乱斗-完整双方集成交互指南

  • 时间:2020-01-28 13:51 编辑:54菜鸟 来源: 阅读:569
  • 扫一扫,手机访问
摘要:本文目的,将Unity集成到Android端,学完本文后你可以做到Android任意布局加载Unity 3D场景,任意操作布局中的按钮/3D物品(缩放旋转等),互相消息通信(你叼我,我叼你) ,自由切换Unity中的场景,动态加载手机SD卡3D资源,一次开发到处使用。

开篇

源码地址:GitHub


本文目的,将Unity集成到Android端,学完本文后你可以做到


Android任意布局加载Unity 3D场景

任意操作布局中的按钮/3D物品(缩放旋转等)

互相消息通信(你叼我,我叼你)

自由切换Unity中的场景

动态加载手机SD卡3D资源,一次开发到处使用。

在小白面前装逼用


故事正题

首要任务就是将Unity项目导出来(已经做好了3D的处理,关于通信和动态加载在下面介绍)



敲黑板,重点Export Project一定要勾选,之后点击最下方的Export 静等项目导出。



导出后的结构感觉好熟悉,就跟Android Studio的项目结构一样(PS:本来就是)打开Studio 以 moudle的形式导入android工程,第一次可能慢一些慢慢导,去喝杯茶。成功后重要的操作来了。打开刚才导入的build.gradle文件,首当其冲的就是gradle版本的修改,跟你的studio版本一致。


dependencies {

    classpath 'com.android.tools.build:gradle:3.2.0'

}

我的是3.2 Android Studio,推荐不低于它。

往下走可以找到

apply plugin: 'com.android.application'

改为


apply plugin: 'com.android.library'

因为我们要以library的形式集成,接着再往下面走就是熟悉的sdkVsersion了,保持和你的anroid项目一致。还有个applicationId,删掉这个。


有的项目遇见UnityAds.aar文件,不影响。其他修改以及遇到的一些坑不再赘述,有问题可以留言。我的如下:


复制代码

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN

buildscript {

    repositories {

        google()

        jcenter()

    }

    dependencies {

        classpath 'com.android.tools.build:gradle:3.2.0'

    }

}

allprojects {

    repositories {

        google()

        jcenter()

        flatDir {

            dirs 'libs'

        }

    }

}

apply plugin: 'com.android.library'

dependencies {

    implementation fileTree(dir: 'libs', include: ['*.jar'])

}

android {

    compileSdkVersion 29

    compileOptions {

        sourceCompatibility JavaVersion.VERSION_1_8

        targetCompatibility JavaVersion.VERSION_1_8

    }

    defaultConfig {

        minSdkVersion 21

        targetSdkVersion 29

        ndk {

            abiFilters 'armeabi-v7a', 'x86'

        }

        versionCode 1

        versionName '1.0'

    }

    lintOptions {

        abortOnError false

    }

    aaptOptions {

        noCompress = ['.unity3d', '.ress', '.resource', '.obb']

    }

    buildTypes {

        debug {

            minifyEnabled false

            useProguard false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'

            jniDebuggable true

        }

        release {

            minifyEnabled false

            useProguard false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'

            signingConfig signingConfigs.debug

        }

    }

    packagingOptions {

        doNotStrip '*/armeabi-v7a/*.so'

        doNotStrip '*/x86/*.so'

    }

}

复制代码

接着打开Unity项目的清单文件AndroidManifest.xml,删减application节点,删除intent-filter节点,activity增加内容process(解决某某问题)


复制代码

<application

    //删减其他

    android:banner="@drawable/app_banner"

    android:isGame="true">

    <activity

        .....

        //删除下面两行-否则造成桌面两个icon

        //android:label="@string/app_name"

        //android:launchMode="singleTask"

        //增加这行

        android:process="e.unity3d">

        //删掉intent-filter

        <!--<intent-filter>-->

            <!--<action android:name="android.intent.action.MAIN" />-->

            <!--<category android:name="android.intent.category.LAUNCHER" />-->

            <!--<category android:name="android.intent.category.LEANBACK_LAUNCHER" />-->

        <!--</intent-filter>-->

        <meta-data

            android:name="unityplayer.UnityActivity"

            android:value="true" />

    </activity>

 ......

复制代码

至此,配置完成,已经可以玩了。


但为了玩的顺畅,我们再增加一个自定义控件(1.用来解决kill问题 2.增强自己的扩展性)。自定义一个java文件集成UnityPlayer(核心关键类)



复制代码

public class MUnityPlayer extends UnityPlayer {

    public MUnityPlayer(Context context) {

        super(context);

    }

    @Override

    protected void kill() {

        //super.kill();

        //unity默认一些返回操作等会直接kill掉进程,覆写kill方法,去掉super.kill, 不让他kill

    }

}

复制代码

配置完成,点击菜单栏的Build,Rebuild Project unity的lib项目中生成aar文件



Unity导出的项目配置完成,配置自己的Android项目,首先将几个lib......so复制到你自己的项目jniLibs中。


然后在你需要集成的项目build文件中


implementation(name: 'XingFeiUnity', ext: 'aar')

接着将aar复制的你的项目libs文件下,记得重命名删除后面的“-debug”,否则会出现找不到类的问题。

一波骚操作搞定,跑起来已经基本可以了。但是这就结束了吗?不可能,骚起来我们就停不下来。


布局渲染

我们需要在任意布局加载3d,怎么个任意法?就是找个view来addview 既不影响3d 还有android原生界面


复制代码

//xml布局

<LinearLayout

        android:id="@+id/linear"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:layout_margin="50dp"

        android:orientation="vertical" />


//java文件

mLinear.removeAllViews();

mLinear.addView(mUnityPlayer.getView());

mUnityPlayer.requestFocus();

复制代码

操作效果请看图片,全部具体代码的话 就直接放到Github了


公众号【空名先生】


通信交互

Android调用Unity


//参数二是 Unity中的方法名   参数一是哪个物体挂在了这个C#脚本  参数三 字符串

UnityPlayer.UnitySendMessage("Main Camera", "AndroidCallUnity", "");


Unity调用Android 仔细看注释


复制代码

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class Manager : MonoBehaviour

{

    private AndroidJavaObject m_androidObj = null;

    public GameObject diqiu;


    void Start()

    {

        //注意-情况不同 com.unity3d.player.UnityPlayer  可能不同,可参考其他博主

        AndroidJavaClass androidClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

        m_androidObj = androidClass.GetStatic<AndroidJavaObject>("currentActivity");

        diqiu.SetActive(false);

    }


    //Unity中的某个物体出发此事件

    public void UnityCallAndroid()

    {

        Debug.Log("调用方法");

        if (m_androidObj != null)

        {

            Debug.Log("调用方法进来");

            // 第一个参数是android里面java代码的方法名,第二个是携带的字符串参数

            m_androidObj.Call("CallAndroid", "我是Unity,我给你发消息了");

        }

    }


    //Android调用Unity-方法名一定要注意

    public void AndroidCallUnity(string json)

    {

        if (diqiu.activeInHierarchy)

        {

            diqiu.SetActive(false);

        }

        else

        {

            diqiu.SetActive(true);

        }

    }

}

复制代码

场景切换

Unity内部自己去处理,就跟玩游戏一样,让Unity开发自己去做

andorid触发,unity换场景,这个借助上面说的消息通信来实现

这还有一个技巧,如果资源不是很多且在一个场景的话,可以让Unity一次直接渲染出来存在字典里,然后想显示哪个Android给Unity发消息,Unity根据订好的消息,展示不同的内容,这个好处就是切换展示速度极快。重点处理一下刚启动的时候的耗时即可。

动态资源

态加载资源的问题,因篇幅有限,咱先只提供个思路,Unity支持读取android设备的存储文件,让他们处理即可,然后android发消息告诉他们地址即可


// 参数一是Unity中的物体名称,参数二Unity中的方法名  参数三路径字符串

UnityPlayer.UnitySendMessage("AndriodMethodMgr", "CallUnitySetPath", Environment.getExternalStorageDirectory() + "");

啊哈,到这基本就结束了。快了又开心。


坑中带坑

为了愉快的装逼,最好还是看一看遇到的这些问题,能至少省几天时间。


1. 混淆问题,如果你开启了混淆,切记 切记,把混淆添加进入,这个大坑耽误我好久啊


2. 如果模型在unity中没问题,在android端穿帮,可以看看发布质量,将android的设置成高的

3. 如果反复执行的模型动画不对,怎么不对?举例心脏跳动,这是非常注重动画的衔接的,如果衔接时间不对会造成心脏动画的抖动,这会非常的明显。


可以看动画的setting 退出时间,退出时间是比例(如下图),1代表全部动画,0.5代表动画使劲按的一般。过度时间前后动画重叠(好像默认.95?)  可以改成0,如图设置


4. 集成到apk后 申请了横竖屏 但是apk没作用,是unity发布出的设置导致的,再Unity导出的时候 other setting中设置宣传方向


5. 权限问题,上面说了会导出一个android项目,你仔细看这个项目的AndroidManifest文件,你会发现也有权限。


注意,这时候比如你的android项目有权限A 这个Unity导出的项目没有权限A,当你集成合并之后,导致最终的apk没有权限A,这并不是我们想看到的;


所以为了 解决这个问题,很简单,我们把两个清单文件的权限保持一致即可,记住啊,否则怎么哭的都不知道。


6. 还有一个未解决的问题,放到这,有朋友知道的话,感谢指教。


带有动画的一个物体,在有的android设备上,动画表现征程,但是有的会出现动画跳动的情况,感觉像是电视的进度条那在跳进度一样。


结尾

最后,别问我为啥知道这么多问题,问就是因为自己跪着走过来的。


  • 全部评论(0)
上一篇:已是第一篇内容
下一篇:Android埋点方案的简单实现-AOP之AspectJ
资讯详情页最新发布上方横幅
最新发布的资讯信息
【织梦cms|织梦技巧】织梦默认作者和默认泉源修改(2021-12-08 10:11)
【织梦cms|织梦技巧】 织梦dedecms差异栏目导航显示差异样式的方式(2021-12-08 10:09)
【织梦cms|织梦技巧】织梦dede新建模型中自定义联动类别调用(2020-03-01 13:52)
【织梦cms|织梦技巧】织梦CMS标签中出现“系统无此标签,可能已经移除”(2020-03-01 13:51)
【织梦cms|织梦技巧】dedecms织梦系统后台验证码图片不显示的解决方法(2020-03-01 13:51)
【织梦cms|织梦技巧】dedecms更新文章会出现空白页(2020-03-01 13:50)
【织梦cms|织梦技巧】让织梦dedecms搜索结果按照点击数排序(2020-03-01 13:48)
【织梦cms|织梦技巧】在dedecms织梦内容页中调用文章缩略图(2020-03-01 13:47)
【织梦cms|织梦技巧】在dedecms织梦添加自制的背景图片(2020-03-01 13:47)
【织梦cms|织梦技巧】修改织梦dedecms幻灯片属性(2020-03-01 13:46)