常用AndroidJavaClass/AndroidJavaObject实现C#调用Java代码,常用UnitySendMessage实现Java调用C#代码。
【调用代码示例】
Java代码为:
package com.test.addtest;import com.unity3d.player.UnityPlayer;public class JavaTestClass {public static int num;public static void Add(int a,int b){int result = a+b;SendMessage(Integer.toString(result));}private static void SendMessage(final String info){UnityPlayer.currentActivity.runOnUiThread(new Runnable() {@Overridepublic void run() {UnityPlayer.UnitySendMessage("GameBase","U3dCallbackMessage",info);}});}public String name;public int Sub(int c){return num-c;}
}
C#代码为:
using UnityEngine;
using UnityEngine.UI;public class TestCode : MonoBehaviour
{public Text text;public void Add(){using (AndroidJavaClass testClass = new AndroidJavaClass("com.test.addtest.JavaTestClass")){testClass.CallStatic("Add", 3, 5);testClass.SetStatic<int>("num", 10);int num = testClass.GetStatic<int>("num");U3dCallbackMessage(num.ToString());using (AndroidJavaObject testObject = new AndroidJavaObject("com.test.addtest.JavaTestClass")){testObject.Set<string>("name", "永恒之星");string name = testObject.Get<string>("name");U3dCallbackMessage(name);int result= testObject.Call<int>("Sub", 8);U3dCallbackMessage(result.ToString());}}}public void U3dCallbackMessage(string message){text.text += message;text.text += " ";}
}
结果为:
【调用过程解析】
- 点击Button后执行Add方法,在Add方法中用AndroidJavaClass生成了一个testClass类,传入的参数是 包名+类名(可以看Java代码),类似于C#中的命名空间+类名。这样我们就得到了Java中写的类,而在C#中,我们是直接就有类。
- testClass.CallStatic("Add", 3, 5); 这是在调用JavaTestClass中的Add方法,Add是静态方法,使用AndroidJavaClass的CallStatic方法实现调用,第一个参数是方法名,后面的参数是Add方法的参数,如果Add方法有三个参数,显然方法名后的参数要有三个。
- 在Add方法中实际调用了UnityPlayer.UnitySendMessage方法将结果传给C#端,其有三个参数,第一个参数是GameObject的名字,第二个参数是方法名,第三个参数是消息内容,这三个参数都是string类型(至于为什么用RunOnUiThread方法,在后面的文章中讲解,可以先认为这是异步调用,所以结果8,显示在最后)
- testClass.SetStatic<int>("num", 10)给Java代码中静态的int类型的字段num设置值为10,int num = testClass.GetStatic<int>("num")获取Java代码中int类型字段num的值,其结果为10
- AndroidJavaObject testObject = new AndroidJavaObject("com.test.addtest.JavaTestClass")是实例化一个Java类。
- testObject.Set<string>("name", "永恒之星");给实例化对象的string类型字段name设置值,string name = testObject.Get<string>("name")获取值
- int result= testObject.Call<int>("Sub", 8);是调用实例化对象的Sub方法,其有一个int类型的返回值。
- 使用using是为了自动调用AndroidJavaClass和AndroidJavaObject的Dispose方法
【AndroidJavaClass与AndroidJavaObject的区别】
使用时将AndroidJavaClass理解为C#中的类,将AndroidJavaObject理解为该类的实例化对象
【UnitySendMessage】
为了使TestCode中的U3dCallbackMessage方法能收到Java中UnityPlayer.UnitySendMessage放松的消息,TestCode脚本必须挂在名字为GameBase的GameObject上。这就是UnityPlayer.UnitySendMessage前两个参数的意义。
【Java代码如何生成】
首先要自己安装Android Studio,Java代码和C#区别不大,很好写,不清楚的语法搜下就能看明白。
创建一个EmptyActivtity
指定PackageName,代码中会用到的
选择Android的目录结构,在app处右键,新建一个Module
选择Android Library
选择Project ,打开Unity目录,在Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations路径下,根据是il2cpp还是mono打包,继续选择debug,还是release模式,在Classes文件夹下找到classes.jar,导入到Java工程中的libs文件夹下面,右键选择 Add as library。导入方式是直接将文件拖过来,或者将文件复制到libs文件夹的路径下也可以。
在addtest->src->main->java->com.test.addtest处右键新建一个JavaClass,这个JavaClass里写代码即可
代码写完点击Mark Project或者Rebuild Project
build成功没有报错,在outputs处右键,选择show in explorer。注意build文件夹是在build完自动出现的,刚创建工程的时候没有这个文件夹。Build一般不会报错,不过运气不好会有各种报错,这些报错搜一下很容易就可解决。
将arr文件解压,选择classes.jar文件,可以重命名为你需要的名字,本文命名为add
将这个文件放入unity中,C#代码即可调用Java代码。
随后可以打个Android包,在模拟器上做测试。
【Build可能出现的报错及解决方式】
出现了再补充。。。