转自: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传递多个参数。