Unity3D和移动端(Android)交互

Unity3D本身就是一款跨平台开发软件,兼容性高,但是往往在开发移动端过程中,需要与Android原生态进行混合开发,这就包括两中形式:
  • 以Unity3D为主导开发
  • 以Android为主导开发
  1. Unity3D为主导,调用Android原生态代码
    (1)首先我们使用AndroidStudio创建一个普通的Android工程,注意要记着PackageName的名称;

    注意:如果工程格式不对,要打开app目录下的build.gradle文件,将apply plugin: ‘com.android.application‘,改成apply plugin: ‘com.android.library‘,因为android studio只有在这种格式下才可以导出unity需要使用的aar或者jar文件。然后删除defaultConfig下的applicationId,去掉默认的dependencies下的
    compile ‘com.android.support:appcompat-v7:25.0.0‘的引入,因为这里不需要用到它,而且这个包包含了很多的资源文件我们是用不到的,最后格式为。

(2)从unity安装目录的Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes中,复制classes.jar出来,放到该刚才建的工程的libs文件夹里,并右键add as library
Unity3D和移动端(Android)交互
Unity3D和移动端(Android)交互
(3)修改AndroidManifest.xml

首先删除values下的style.xml文件,因为这里面默认包含的是之前删除的com.android.support:appcompat-v7:25.0.0包里面的主题。然后修改AndroidManifest文件中application下的theme为android自带的主题。同时将<activity android:name=".MainActivity">修改为<activity android:name="cn.unity.android.MainActivity">,防止在unity中导出的app与AndroidManifest中的包名不一致产生的问题。然后添加<meta-data>信息,否则在 Unity 导出 APK 时会报找不到manifest 文件的错误信息

 <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> 

最终如下:
Unity3D和移动端(Android)交互
(4)上安卓原生代码

package com.romantic.forunity;
import android.app.AlertDialog;
import android.os.Vibrator;
import android.os.Bundle;
import android.widget.Toast;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    public String ShowDialog(final String _title, final String _content){

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle(_title).setMessage(_content).setPositiveButton("Down", null);
                builder.show();
            }
        });

        return "Java return";
    }

    // 定义一个显示Toast的方法,在Unity中调用此方法
    public void ShowToast(final String mStr2Show){
        // 同样需要在UI线程下执行
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),mStr2Show, Toast.LENGTH_LONG).show();
            }
        });
    }

}

(5)导出aar包和jar包

点击build-->build apk,然后在app-->build-->outputs-->aar目录下的到app-debug.aar文件
将app-debug.aar文件解压,得到根目录下的classes.jar文件,请注意这个classes.jar文件并不是最开始从unity中导入到android的classes.jar文件,而且你写的android代码的class文件的压缩包(可以解压看看里面实际的内容)。之后unity所需要使用的是res文件夹下的文件,classes.jar(android的)和AndroidManifest文件。
Unity3D和移动端(Android)交互

(6)Unity3D上面需要的工作

然后将我们之前导出的jar和res文件拷贝到Plugins/Android文件夹下。

直接上代码

 //获取Android的Java接口  
        AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");  
        jo = jc.GetStatic<AndroidJavaObject> ("currentActivity"); 

    //每个unity app在启动的时候都会有一个unityPlayer实例。通过获取该实例里面currentActivity对象,其实就是我们的MainActivity实例。

    public void  ShowAndroidTime ()
    {
        jo.Call ("showToast", "Test" });
    }

同样安卓也可调用Unity中的方法(在安卓原生态脚本中添加):

   // 第一个参数是unity中的对象名字,记住是对象名字,不是脚本类名
    // 第二个参数是函数名
    // 第三个参数是传给函数的参数,目前只看到一个参数,并且是string的,自己传进去转吧
    public void callUnityFunc(String _objName , String _funcStr, String _content)
    {
        UnityPlayer.UnitySendMessage(_objName, _funcStr, "Come from:" + _content);
    }

最后导出App就OK了。

  1. 以Android为主导开发,从Unity 2019.3.a2开始,我们通过把Unity运行时组件和内容集成到原生平台项目,在原生应用中将Unity作为库使用

    注意:
    Unity版本必须是Unity 2019.3.a2以上
    Android Studio 3.3.2以上
    将Unity作为库使用,要求开发者对Android/Java和iOS/Objective C的架构有着深入的了解。
    由于Unity不再控制运行时的生命周期,因此我们无法确保它可以在所有用例都正常工作

Unity运行时库会公开控制功能,以管理在原生应用中加载,激活和卸载的时间和方式。移动应用的构建过程总体上依旧相同,Unity将创建Android Gradle项目。
为了启用该功能,我们修改了生成iOS Xcode和Android Gradle项目的结构,结构如下:
1、库:Android Archive(AAR)文件,包含所有源文件和插件。
2、精简的启动器:包含应用程序展示数据,它会运行库部分。
如果使用Unity作为库,Android Gradle项目的结构会发生改变。如果使用自定义mainTemplate.gradle或AndroidManifest.xml,这些改变也会影响项目或Unity插件。


此前,Unity会使用单个Gradle模块来构建Android应用。现在,Unity会使用二个模块创建Gradle项目,即:unityLibrary模块和启动器模块。unityLibrary模块包含Unity运行时和项目数据。该模块是一个可以轻松集成到任何其它Gradle项目中的库,也可以把Unity嵌入到现有原生Android项目中。


启动器模块包含所有图标和应用名称,它是一个简单的Android应用程序,可以启动Unity。


将Unity作为库会提供新的Gradle项目结构,它会更好的符合Android Studio项目最佳结构。该结构中有一个根文件夹,其中包含一些可以单独构建和使用的子项目。它让导入Unity Android Studio项目更加简单。
Unity3D和移动端(Android)交互


Gradle模板会描述和配置使用Gradle构建Android应用的方法。每个Gradle模板代表一个Gradle项目,Gradle项目可以包括和依赖其它Gradle项目。

将Unity作为库的Gradle模板文件如下:
1、baseProjectTemplate.gradle:包含所有其它模板和Gradle项目共享的配置,即Android Gradle插件上的代码库和依赖。
2、launcherTemplate.gradle:包含如何构建Android应用的指令,例如:打包,签名和APK分离等,具体取决于unityLibrary项目,它会输出一个APK文件或App Bundle。
3、mainTemplate.gradle:包含如何把Unity构建为库的指令,它会输出.aar格式文件,用户可以提供自定义模板来重写Unity模板,包括编辑器设置。
4、libTemplate.gradle:与之前的工作方式相同。

将Unity作为库会改变Unity Android应用清单文件的使用方式。此前会有一个AndroidManifest.xml文件,用于给Android应用提供图标、行为、权限和其它设置。使用新系统后,我们有二个清单文件,而不是一个:

1、LauncherManifest.xml:负责处理图标、应用名称、开始行为及其目的、安装位置、支持的屏幕大小和设置“isGame”。
2、LibraryManifest.xml:负责声明Unity行为、权限、Unity行为使用的主题、VR模式、VR性能、使行为不可以调整大小、设置最大高宽比、应对配置改动、朝向、启动模式、Android UI硬件加速、使用的功能,例如游戏手柄或图形API和槽口支持。该清单文件可以通过在Plugins/Android文件夹中提供自定义AndroidManifest.xml文件来重写。

(1)下载gradle插件,进行Unity开发。
(2)Unity3D打包切换到安卓平台,选择导出项目
Unity3D和移动端(Android)交互
将UnityProject导出到androidBuild文件夹,文件夹结构应如下所示:
Unity3D和移动端(Android)交互
(3)将Unity库模块添加到NativeAndroidApp,在Android Studio中打开NativeAndroidApp,
打开settings.gradle,在settings.gradle文件的末尾,我们添加了指向unityLibrary模块的新项目:

包括‘:unityLibrary‘
项目(‘:unityLibrary‘ )。projectDir =新文件(‘.. \\ UnityProject \\ androidBuild \\ unityLibrary‘ )

Unity3D和移动端(Android)交互
打开build.gradle(模块:应用),在依赖关系块中添加以下内容

实施项目(‘:unityLibrary‘ )

Unity3D和移动端(Android)交互
打开build.gradle(项目:NativeAndroidApp),在allprojects {repositories {块中添加以下内容

flatDir {
   dirs “ $ {project(‘:unityLibrary‘)。projectDir} / libs”
}

Unity3D和移动端(Android)交互
后面就可以看见unityLibrary模块。
最后运行调试,打包就可以了。
附上官网专家解答地址:
https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app.685240/

Unity3D和移动端(Android)交互

上一篇:一小时学会使用springboot操作阿里云OSS实现文件上传,下载,删除(附源码)


下一篇:Asp.NetCore之AutoMapper基础篇