Unity与Java通信

转自:http://www.wxdgame.com/blog/2015/11/08/study2/

因为unity需要接入java的sdk,所以今天主要学习了一下相关的通信方法。需要先做如下准备工作:
  1、下载android SDK安装包,http://pan.baidu.com/s/1dDGM8oD,里面会包含sdk和eclipse两个文件夹;
  2、unity工程从Build Settings界面选择android平台,选中Google Android Projects,导出安卓工程;
  3、打开eclipse导入安卓工程,测试编译通过。

  有两种方法可以让unity跟java进行通信:
  第一种写法,在eclipse中自定义个包名,在里面创建一个类,例如我自定义了com.sdk.SDKAPI:

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 package com . sdk ; import org . json . JSONException ; import org . json . JSONObject ; import android . os . Bundle ; import android . util . Log ;   import com . unity3d . player . * ; public class SDKAPI { private String test ( int a , String b ) { Log . i ( “unity” , “test: “ + a + ” “ + b ) ; JSONObject obj = new JSONObject ( ) ; try { obj . put ( “first” , 43 ) ; obj . put ( “second” , “testCall” ) ; } catch ( JSONException e ) { e . printStackTrace ( ) ; } com . unity3d . player . UnityPlayer . UnitySendMessage ( “ARCamera” , “UnityTest” , obj . toString ( ) ) ; return “wxd” ; } private static int test1 ( int a , String b ) { Log . i ( “unity” , “test1: “ + a + ” “ + b ) ; JSONObject obj = new JSONObject ( ) ; try { obj . put ( “first” , 55 ) ; obj . put ( “second” , “test1Call” ) ; } catch ( JSONException e ) { e . printStackTrace ( ) ; } com . unity3d . player . UnityPlayer . UnitySendMessage ( “ARCamera” , “UnityTest” , obj . toString ( ) ) ; return 6543 ; } }

  打开AndroidManifest.xml文件,在application节点下有若干个activity节点,找到android:name=”com.xxxxx.UnityPlayerNativeActivity”属性,后面字符串显示的是目前java工程中当前正在使用的activity类文件,把他改成我们刚才自定义的com.sdk.SDKAPI,然后在unity中代码如下:

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 using UnityEngine ; using System . Collections ;   public class GameWorld : MonoBehaviour {      private AndroidJavaClass _class ;   void Start ( )      {          _class = new AndroidJavaClass ( “com.sdk.SDKAPI” ) ; }      void UnityTest ( string b )      {          Debug . Log ( “UnityTest — “ + b ) ;      }      void OnGUI ( )      {          if ( GUI . Button ( new Rect ( 0 , 0 , 200 , 100 ) , “test …” ) )          {              if ( _class != null )              {                  string a = _class . Call < string > ( “test” , 119 , “wxdgame” ) ;                  Debug . Log ( “::1:::” + a ) ;              }          }          if ( GUI . Button ( new Rect ( 0 , 100 , 200 , 100 ) , “test1 …” ) )          {              if ( _class != null )              {                  int b = _class . CallStatic < int > ( “test1” , 911 , “testgame” ) ;                  Debug . Log ( “::2:::” + b ) ;              }          }      } }

  编译运行通过,点击我们放置的按钮,查看log输出,于是我们得到了两个结论:1、java类中的私有方法也可以被unity调用;2、只能调用静态方法。如果我想调用java非静态方法怎么办呢?于是就有了第二种写法,我们修改下unity的代码:

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 using UnityEngine ; using System . Collections ;   public class GameWorld : MonoBehaviour {      private AndroidJavaClass _class ;      private AndroidJavaObject _obj ;   void Start ( )      {          _class = new AndroidJavaClass ( “com.unity3d.player.UnityPlayer” ) ;          _obj = _class . GetStatic < AndroidJavaObject > ( “currentActivity” ) ; }      void UnityTest ( string b )      {          Debug . Log ( “UnityTest — “ + b ) ;      }      void OnGUI ( )      {          if ( GUI . Button ( new Rect ( 0 , 0 , 200 , 100 ) , “test …” ) )          {              if ( _obj != null )              {                  string a = _obj . Call < string > ( “test” , 119 , “wxdgame” ) ;                  Debug . Log ( “::1:::” + a ) ;              }          }          if ( GUI . Button ( new Rect ( 0 , 100 , 200 , 100 ) , “test1 …” ) )          {              if ( _obj != null )              {                  int b = _obj . CallStatic < int > ( “test1” , 911 , “testgame” ) ;                  Debug . Log ( “::2:::” + b ) ;              }          }      } }

  同时java里的代码也要进行调整:

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 package com . sdk ; import org . json . JSONException ; import org . json . JSONObject ; import android . os . Bundle ; import android . util . Log ;   import com . and3 . UnityPlayerNativeActivity ; import com . unity3d . player . * ; public class SDKAPI extends UnityPlayerNativeActivity { private String test ( int a , String b ) { Log . i ( “unity” , “test: “ + a + ” “ + b ) ; JSONObject obj = new JSONObject ( ) ; try { obj . put ( “first” , 43 ) ; obj . put ( “second” , “testCall” ) ; } catch ( JSONException e ) { e . printStackTrace ( ) ; } com . unity3d . player . UnityPlayer . UnitySendMessage ( “ARCamera” , “UnityTest” , obj . toString ( ) ) ; return “wxd” ; } private static int test1 ( int a , String b ) { Log . i ( “unity” , “test1: “ + a + ” “ + b ) ; JSONObject obj = new JSONObject ( ) ; try { obj . put ( “first” , 55 ) ; obj . put ( “second” , “test1Call” ) ; } catch ( JSONException e ) { e . printStackTrace ( ) ; } com . unity3d . player . UnityPlayer . UnitySendMessage ( “ARCamera” , “UnityTest” , obj . toString ( ) ) ; return 6543 ; } }

  这样java里的两个方法就都可以被调用了,那么差别主要包括哪些呢,总共有四点:
  1、java里面的类需要继承UnityPlayerNativeActivity;
  2、unity里面AndroidJavaClass的参数改为:

1 _class = new AndroidJavaClass ( “com.unity3d.player.UnityPlayer” ) ;

  3、从刚才得到的class实例中获取currentActivity:

1 _obj = _class . GetStatic < AndroidJavaObject > ( “currentActivity” ) ;

  4、下面在调用call方法的时候,把之前从AndroidJavaClass实例调用改成从AndroidJavaObject调用。

  此外,关于java调用unity的接口比较简单,直接调用com.unity3d.player.UnityPlayer.UnitySendMessage接口就行了。总共包含三个参数,第一个表示unity中包含c#脚本的GameObject实例名称,第二个表示方法名,第三个表示传递的参数,由于只是个字符串类型,所以如果有多个参数需要传递的话,可以像我这样使用JSONObject传递多个参数。

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/bsmmaoshenbo/article/details/51025472
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞