Unity和Android互相呼叫方法
阿新 • • 發佈:2019-02-04
前言
我們unity程式有很多依賴android的地方,以為很簡單,後來發現坑好多。unity只有在主執行緒才能調android的方法,在unity中調android的方法啟動執行緒都不能執行,在unity的子執行緒無法獲取AndroidJavaObject,這樣耗時方法呼叫就會有問題了。
Unity與Android互相呼叫方法
Unity調Android,使用AndroidJavaClass和AndroidJavaObject就可以獲取到java類和物件了,下面這個方法是獲取預設UnityPlayerActivity物件的方法:
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); jo = jc.GetStatic<AndroidJavaObject> ("currentActivity"); string result = jo.Call<string>("getVersion");
- 1
- 2
- 3
- 4
Android調unity也很簡單
UnityPlayer.UnitySendMessage("objectName", "functionName","value");
- 1
- 2
Unity中需要有name為“objectName”的物件,其繫結的指令碼類需要這樣的方法:
void functionName(string str)
- 1
- 2
這樣就可以接受到android發來的訊息了,但這個訊息引數是String,複雜物件無法直接傳遞。
特殊方法
前面埋了幾個坑,現在來填一下。
Unity需要呼叫Android的耗時方法怎麼辦呢,我想到可以先Unity呼叫Android方法,在Android調Unity的方法的形式來達到回撥的目的。
Android部分:
定義一個訊息格式:
class UnityCallMessage {
String contentId;
String name;
public UnityCallMessage(String name, String contentId) {
this.name = name;
this.contentId = contentId;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
新建一個handler,用來接收訊息:
mHandler = new Handler() { public void handleMessage(Message msg) { if (msg.what == GET_CONTENG && msg.obj instanceof UnityCallMessage) { getVrContentReturn((UnityCallMessage) msg.obj); } super.handleMessage(msg); } };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
被unity呼叫的方法,傳送一個訊息,直接結束:
public void getVrContentAsync(String name, String contentId) {
Log.d("myth", "getVrContentAsync start" + contentId);
Message msg = new Message();
msg.what = GET_CONTENG;
msg.obj = new UnityCallMessage(name, contentId);
this.mHandler.sendMessage(msg);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
調unity的方法,這個方法被handler呼叫,完成後調unity:
public void getLocalResReturn(UnityCallMessage message) {
ContentsCoverData[] data = getData();
if (data != null) {
DataTransport.getInstance().put(KEY_GET_LOCAL_RES, data);
UnityPlayer.UnitySendMessage(message.name, "getLocalResReturn", KEY_GET_LOCAL_RES);
Log.d("myth", "getLocalResReturn");
return;
}
UnityPlayer.UnitySendMessage(message.name, "getLocalResReturn", "failed");
Log.d("myth", "failed");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
其中有個DataTransport類,用於在記憶體中儲存物件的,之前文章有講過,Unity中可以根據對應key去取到這個物件,對應方法:
public Object getSavedObject(String key) {
Object data = DataTransport.getInstance().get(key);
Log.d("myth", "data:" + data);
return data;
}
- 1
- 2
- 3
- 4
- 5
- 6
Unity中需要對應方法為:
public void getLocalResReturn(string key)
{
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
AndroidJavaObject[] array = jo.Call<AndroidJavaObject[]> ("getSavedObject", key);
//do some thing using the datas
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
感受
Android和unity互調是比較簡單的,但也有很多限制,我們應用因為有奇怪地需求就用了這樣的特殊方法,但不建議使用。