Android调用Unity的方法

在Android Studio中,File–》New–》New Module–》Android Library,创建一个新模块,取名为simplelibrary,然后打开unity安装目录

D:\unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar,将classes.jar复制进Android Studio中的simplelibrary\libs,如图:

Android 主动发给unity消息 android调用unity_Android 主动发给unity消息


Android要调用unity的方法就需要将unity中的classes.jar复制进Android Studio。复制进去之后,选中这个文件,右键点击Add As Library。然后在回到Android,新建一个Java class,如图:

Android 主动发给unity消息 android调用unity_c#_02

然后创建一个add方法,通过UnityPlayer.UnitySendMessage()来调用unity里的方法,如上面的图片里的内容。

第一个参数是unity中的Hierarchy面板上的物体
第二个参数是调用的那个物体上所挂载的脚本的方法名
第三个参数是那个方法中的参数

然后选中simplelibrary,Build–》Make Module‘simplelibrary’。

Android 主动发给unity消息 android调用unity_Android 主动发给unity消息_03


将这个jar包拖入unity工程中,要在Plugins/Android目录下,然后写个c#脚本来执行。代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public Text text;
    void Start()
    {
        AndroidJavaObject jo = new AndroidJavaObject("com.guanhui.xiaolin.simplelibrary.Test");
        text.text = jo.Call<int>("add", 1, 2).ToString();
    }

    public void ChangeColor()
    {
        text.color = Color.red;
    }
}

将这个脚本挂载在Main Camera上,新建一个text,给脚本中的text拖拽赋值,然后设置包名,选择Android版本就可以打包了。可以看到,输出了红色的3,图片就不贴了。

Unity直接调用Android方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        AndroidJavaClass jc = new AndroidJavaClass("android.util.Log");
        jc.CallStatic<int>("e", "UnityAndroidTest", "ErrorTest");
    }
}

我们要调用Android的Log方法,所以要取得android.util.Log这个类,然后通过CallStatic或者Call来调用里面的方法。
第一个参数e表示调用了Log中的e方法
第二个参数是标签
第三个参数是要输出的错误信息内容

可以通过这种方式直接调用Android的方法,不需要导入任何的包。
这个打印信息是显示在Android Studio上的,所以要用手机连接上电脑,打开usb调试,启动应用后就可以在Android Studio上看到打印信息了。

Unity制作Toase

Toase就是提示信息,比如手机按一下返回键的时候,显示的“再按一次退出应用”

通过aar包制作Toase

File->New->New Module…创建一个模块(名称随意),选择Android Library,我取名为toaselibrary。

找到unity安装目录下的D:\unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes/classes.jar
按住ctrl将这个资源复制进Android studio工程中的toaselibrary/libs下,然后选中这个文件,右键选择Add As Library…,等待编译。

然后回到Android,在toaselibrary/java/com.guanhui.xiaolin.toaselibrary下右键New–>Activity–>Empty Activity,然后点击Finish。将toaselibrary/res/layout下的.xml文件删除掉,然后将打开的
MainActivity.java下的setContentView(R.layout.activity_main);删掉,将AppCompatActivity改为UnityPlayerActivity,将import android.support.v7.app.AppCompatActivity;也删掉。

接下来就是修改toaselibrary下的manifests下的AndroidManifest.xml,将app/mainfests/AndroidManifest.xml的<application和</ application>包裹的内容复制到刚刚要修改的AndroidManifest.xml里,也就是将那个标签里的内容替换掉,替换之后,将爆红的内容删掉,然后在下面加一句<meta-data

android:name=“unityplayer.UnityActivity” android:value=“true” />

好像不加也可以。到了这里就配置完成了。

回到MainActivity.java,在里面添加代码,如下:

package com.guanhui.xiaolin.toaselibrary;

import android.os.Bundle;
import android.widget.Toast;

import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {

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

    public void ShowToase(final String msg)
    {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this,msg,Toast.LENGTH_LONG).show();
            }
        });
    }
}

选中toaselibrary,点击菜单栏的Build–>Make Module’toaselibrary’,make完成后,在Project下,
toaselibrary/build/outputs/aar点击show in Explorer,将toaselibrary-debug.aar复制到桌面上。

【旧版的unity要这样做,应该是2017以下的版本吧,没测试过】
(用压缩软件打开这个aar包,将libs里面的classes.jar删除,然后返回上一级,将classes.jar拖到桌面,再将它拖进libs的目录下,再返回上一级,将classes.jar删除。整个过程就相当于将外面的classes.jar替换掉libs里面的classes.jar文件。)

【我用的2018的版本,较新版本一点的这样做】
(用压缩软件打开这个aar包,将libs里面的classes.jar删除)

在unity中新建目录Plugins/Android

将桌面的toaselibrary-debug.aar拖入到Plugins/Android中

在unity中设置好Android平台,新建一个脚本,挂载在摄像机上,然后代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    AndroidJavaObject jo;
    void Start()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("ShowToase", "软件启动");
    }
}

打包好之后,启动软件的时候,就会弹出软件启动的消息了,一秒之后,消息就消失了。

Unity直接制作Toase(不需要导入任何包)

新建一个C#脚本,然后直接挂载在相机上,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        //runOnUiThread属于activity类的,所以我们要先取得这个类
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

        AndroidJavaClass toast = new AndroidJavaClass("android.widget.Toast");
        AndroidJavaObject context = currentActivity.Call<AndroidJavaObject>("getApplicationContext");
        currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(()=>
        {
            toast.CallStatic<AndroidJavaObject>("makeText", context, "hello", toast.GetStatic<int>("LENGTH_LONG")).Call("show");
        }));
    }
}
//上面的代码是为了实现下面的Android的方法
//package com.guanhui.xiaolin.toaselibrary;

//import android.os.Bundle;
//import android.widget.Toast;

//import com.unity3d.player.UnityPlayerActivity;

//public class MainActivity extends UnityPlayerActivity
//{

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

//public void ShowToase(final String msg)
//{
//    runOnUiThread(new Runnable() {
//            @Override
//            public void run()
//    {
//        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
//    }
//});
//    }
//}
//getApplicationContext()实际上就是MainActivity.this

导出apk包后,运行,就可以显示一秒的hello字样了。

Unity调用Android的日历(不需要导入任何包)

1.Android代码说明

下面是Android Studio中调用日历的代码,之所以展示出来,是因为要用C#来根据这些代码来调用Android里面的方法。

Android 主动发给unity消息 android调用unity_android_04


里面有个DatePickerDialog.OnDateSetListener(),由于OnDateSetListener()是一个接口,在Android Studio中右键goto到定义的地方就可以看到是个接口了,截图如下:

Android 主动发给unity消息 android调用unity_unity_05


而我们需要用C#实现Android中的接口,就需要定义一个类,并且继承自AndroidJavaProxy,然后里面写个构造方法,通过base将接口名所在位置以字符串形式传入,接口里面的方法也需要我们在C#中定义同样的方法,这样就模拟实现了Android的接口了。

2.unity实现日历功能

在unity中设置为Android平台,新建一个Text,新建一个C#脚本,挂载在Text或者相机,打开C#脚本进行编辑,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class Test : MonoBehaviour
{
    private static Text info;
    private static DateTime selectedDate = DateTime.Now;
    class DateCallBack : AndroidJavaProxy
    {
        public DateCallBack() : base("android.app.DatePickerDialog$OnDateSetListener")
        {
        }
        void onDateSet(AndroidJavaObject view,int year,int month,int dayOfMonth)
        {
            info.text = year + "/" + (month + 1) + "/" + dayOfMonth;
        }
    }

    void Start()
    {
        info = GameObject.Find("Text").GetComponent<Text>();
        AndroidJavaObject currentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
         {
             new AndroidJavaObject("android.app.DatePickerDialog", currentActivity, new DateCallBack(), selectedDate.Year, selectedDate.Month - 1, selectedDate.Day).Call("show");
         }));
    }
}

Android的UI要在Unity的UI之上显示时,要加currentActivity.Call(“runOnUiThread”, new AndroidJavaRunnable(() =>{}这段代码。

效果图如下:

Android 主动发给unity消息 android调用unity_android_06


Android 主动发给unity消息 android调用unity_android_07