当前位置:   article > 正文

Unity学习笔记006.Android Plugin for Unity

Unity学习笔记006.Android Plugin for Unity


以简单计算器为例,记录Unity调用Android Activity原生接口,实现Unity与Android交互。
本文使用Windows10系统下的Unity 2018.1.2f1、Android Studio 3.2。

1. 思路

Unity端:UI
Android端:代码逻辑

2. 步骤

2.1 新建工程

新建Android工程:SimpleCalc。
新建Android工程:SimpleCalc
选择最低版本4.0.3.
在这里插入图片描述
选择Empty Activity。
在这里插入图片描述
MainActivity默认设置就好,Finish.
由于我们不使用Android来布局,故activity_main.xml默认即可。
在这里插入图片描述

2.2 导入Unity封装的接口jar

位置:

Unity3d_1.2\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
  • 1

classes.jar复制到工程中的libs下
在这里插入图片描述
将classes.jar添加为library。
在这里插入图片描述
添加完成后,classes.jar可展开。
在这里插入图片描述
到此,SimpleCalc/app/build.gradle得到如下所示:
在这里插入图片描述

2.3 编写Android原生接口

2.3.1 添加子Activity

创建4个Empty Activity如下(均使用默认设置):
在这里插入图片描述

2.3.2 修改子Activity

AdditionActivity

原(同下):
在这里插入图片描述
修改后:
在这里插入图片描述

SubtractionActivity

修改后:
在这里插入图片描述

MultiplicationActivity

修改后:
在这里插入图片描述

DivisionActivity

在这里插入图片描述

2.3.2 修改MainActivity
将MainActivity作为接口。原MainActivity如下:
在这里插入图片描述
修改为:

import android.app.Activity;
import com.unity3d.player.UnityPlayerActivity;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MainActivity extends UnityPlayerActivity {
	/**
     * unity项目启动时的的上下文
     */
    private Activity _unityActivity;
    /**
     * 获取unity项目的上下文
     * @return
     */
     Activity GetActivity(){
        if(null == _unityActivity) {
            try {
                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
                _unityActivity = activity;
                        } catch (ClassNotFoundException e) {

            } catch (IllegalAccessException e) {

            } catch (NoSuchFieldException e) {

            }
        }
        return _unityActivity;
    }
    
    /**
     * 调用Unity的方法
     * @param gameObjectName    调用的GameObject的名称
     * @param functionName      方法名
     * @param args              参数
     * @return                  调用是否成功
     */
     boolean CallUnity(String gameObjectName, String functionName, String args){
        try {
            Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
            Method method =classtype.getMethod("UnitySendMessage", String.class,String.class,String.class);
            method.invoke(classtype,gameObjectName,functionName,args);
            return true;
        } catch (ClassNotFoundException e) {

        } catch (NoSuchMethodException e) {

        } catch (IllegalAccessException e) {

        } catch (InvocationTargetException e) {

        }
        return false;
    }
	
	public void Calc(int operator, double a, double b){
        if (operator >=0 && operator < 4){
            switch (operator){
                case 0:
                    CallUnity("Canvas","FromAndroid",String.valueOf(AdditionActivity.Add(a,b)));
                    break;
                case 1:
                    CallUnity("Canvas","FromAndroid",String.valueOf(SubtractionActivity.Subtract(a,b)));
                    break;
                case 2:
                    CallUnity("Canvas","FromAndroid",String.valueOf(MultiplicationActivity.Multiply(a,b)));
                    break;
                case  3:
                    CallUnity("Canvas","FromAndroid",String.valueOf(DevisionActivity.Devide(a,b)));
                    break;
                default:
                    break;
            }
        }
//        else{
//            return false;
//        }
//        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

2.4 导出jar包作为Unity Plugin

2.4.1 修改app下的build.gradle

修改如下:

//apply plugin: 'com.android.application'
apply plugin: 'com.android.library'

android {
    compileSdkVersion 28

    // Add
    sourceSets {
        main {
            //Path to your source code
            java {
                srcDir 'src/main/java'
            }
        }
    }

    defaultConfig {
//        applicationId "com.polin.simplecalc"
        minSdkVersion 15
        targetSdkVersion 28
//        versionCode 1
//        versionName "1.0"
//        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    // Add
    lintOptions {
        abortOnError false
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/classes.jar')
}

// Add
//task to delete the old jar
task deleteOldJar(type: Delete) {
    delete 'release/AndroidPlugin.jar'
}

//task to export contents as jar
task exportJar(type: Copy) {
    from('build/intermediates/packaged-classes/release/')
    into('release/')
    include('classes.jar')
    ///Rename the jar
    rename('classes.jar', 'AndroidPlugin.jar')
}

exportJar.dependsOn(deleteOldJar, build)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

修改完成后,在顶端会出现Sync提示:
在这里插入图片描述
Sync后,打开Studio右侧的Gradle控制台,Refresh。
在这里插入图片描述
之后,在SimpleCalc下找到other,之后找到exportJar,点击即可生成jar包。
在这里插入图片描述
注意不同版本的Android Studio中,自动生成的jar包目录不同。在Android Studio 3.2中,默认目录为:

build/intermediates/packaged-classes/release/
  • 1

2.5 配置AndroidManifest.xml

原:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.polin.simplecalc">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".AdditionActivity" />
        <activity android:name=".SubtractionActivity" />
        <activity android:name=".MultiplicationActivity" />
        <activity android:name=".DevisionActivity"></activity>
    </application>
</manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

修改后:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.polin.simplecalc">

    <application
        android:allowBackup="true"
        android:label="@string/app_name">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
        <activity android:name=".AdditionActivity" >
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
        <activity android:name=".SubtractionActivity" >
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
        <activity android:name=".MultiplicationActivity" >
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
        <activity android:name=".DevisionActivity">
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
    </application>
</manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

SimpleCalc/app/release下的AndroidPlugin.jar以及src/main下的AndroidManifest.xml就是我们要导入unity中的android原生接口文件。

2.6 Unity端

新建工程SimpleCalc

在这里插入图片描述

导入jar包

在根目录下创建Plugins/Android,并将刚才的AndroidPlugin.jar和AndroidManifest.xml复制进去。

创建4个Button作为操作按钮,2个InputFeild输入操作数,1个Button作为计算按钮,1个Text显示结果。

在这里插入图片描述

在Canvas挂载SimpleCalc脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SimpleCalc : MonoBehaviour {

    private Button add;
    private Button subtract;
    private Button multiply;
    private Button devide;
    private Text text;
    private InputField inputField1;
    private InputField inputField2;
    private Button done;

    private int index = -1;

    // Use this for initialization
    void Start () {
        add = transform.Find("Add").GetComponent<Button>();
        subtract = transform.Find("Subtract").GetComponent<Button>();
        multiply = transform.Find("Multiply").GetComponent<Button>();
        devide = transform.Find("Devide").GetComponent<Button>();
        text = transform.Find("Text").GetComponent<Text>();
        inputField1 = transform.Find("InputField1").GetComponent<InputField>();
        inputField2 = transform.Find("InputField2").GetComponent<InputField>();
        done = transform.Find("Done").GetComponent<Button>();

        add.onClick.AddListener(Add);
        subtract.onClick.AddListener(Subtract);
        multiply.onClick.AddListener(Multiply);
        devide.onClick.AddListener(Devide);
        done.onClick.AddListener(Done);
    }
	
    public void Add(){ index = 0; }
    public void Subtract() { index = 1; }
    public void Multiply() { index = 2; }
    public void Devide() { index = 3; }
    
    public void Done()
    {
        AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("Calc", index, Convert.ToDouble(inputField1.text), Convert.ToDouble(inputField2.text));
    }

    public void FromAndroid(string content)
    {
        text.text = string.Format("Res: {0}", content);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

保存场景。
还要注意Unity中Android SDK的版本要高于Android Studio中设置的最低版本。
最后一步,修改一下Build Settings中的Android的Player Settings中的Bundle Identifier为Android studio的包名,查看Android Studio中的AndroidManifest.xml,包名为:com.polin.simplecalc。
在这里插入图片描述

2.7 测试

测试必须是真机测试,在unity editor player是不能测试的,会报错Exception: JNI: Init’d AndroidJavaClass with null ptr!。
将生成的apk装入真机或虚拟机调试即可实现在Unity中调用Android原生接口。
本文使用网易MuMu模拟器调试,在Android Studio的terminal使用adb连接:

adb connect 127.0.0.1:7555
  • 1

在这里插入图片描述


[注]
在Unity中若打包apk不通过,可在Android Studio的Project视窗下找到gradle.properties,注释掉该句:

org.gradle.jvmargs=-Xmx1536m
  • 1

或将打包方式由Gradle改为Internal。

参考:link

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/287591
推荐阅读
相关标签
  

闽ICP备14008679号