發現一般的UI界面都是顯示在Unity界面的後面的,即Unity控件的zOrder是最高的。
用於WebRtc顯示的SurfaceViewRender在視頻(本地或者遠程)出來後是能顯示到Unity上面的,但是視頻還沒有出來時,等待時,是被Unity遮擋着的。
查到一個資料:https://android.jlelse.eu/unity-and-android-connecting-the-dots-6368b31e86c5,這個網頁在家裏電腦居然顯示不了,公司電腦可以(有科學上網)。
英文的,他們是要在unity上面顯示其他東西。
這個效果是我需要的。
調試過程中需要查看程序界面結構,記得AndroidStudio支持的。以前是用DeviceMonitor(參考:Android studio 查看頁面佈局層次結構工具使用教程),現在(AndroidStudio3.5.2)有新的工具(參考:AndroidStudio3.0以上替代DDMS的hierarchyviewer工具查看佈局層級)。
從上面的資料以及LayoutInspector來看,UnityPlayer裏面確實只有一個SurfaceView。
資料的內容總之就是
1.UnityPlayer裏面設置了ZOrder,setZOrderOnTop,所有是顯示在最前面的。
public UnityPlayer(ContextWrapper contextWrapper) {
super(contextWrapper);
...
this.mSurfaceView = new SurfaceView((Context)contextWrapper);
this.mSurfaceView.getHolder().setFormat(2);
...
this.mSurfaceView.setFocusable(true);
this.mSurfaceView.setFocusableInTouchMode(true);
// added on Unity 5.6
// removed in patch 5.6.1p4
this.mSurfaceView.setZOrderOnTop(true);
addView(mSurfaceView);
}
我看到的代碼是這樣的:
private SurfaceView c() {
SurfaceView var1 = new SurfaceView(this.t);
if (b()) {
var1.getHolder().setFormat(-3);
var1.setZOrderOnTop(true);
} else {
var1.getHolder().setFormat(-1);
}
var1.getHolder().addCallback(new Callback() {
....
});
var1.setFocusable(true);
var1.setFocusableInTouchMode(true);
return var1;
}
想起來js代碼格式化後的,這也是格式化了的,c是什麼b是什麼t是什麼....
想着是不是能夠寫一個MyUnityPlayer繼承或者複製UnityPlayer的內容後修改。繼承的話沒有找到相關的可修改的接口,複製的話,看不懂,而且語法上過不去。不像以前幹過的還原awrtc.js的過程,至少它的語法是沒問題的,慢慢裏面內容修改名稱就好了。
2.可以通過修改SurfaceView的ZOrder的方式來處理,但是會有副作用,黑屏一下。
不知道他的具體代碼是怎樣的,我的要麼Unity部分直接就是變黑了,要麼Acitivity退出了。根據在不同地方調用下面的代碼。
private void setSurfaceViewZ(){
SurfaceView unitySurfaceView=(SurfaceView)mUnityPlayer.getChildAt(0);
mUnityPlayer.removeView(unitySurfaceView);
unitySurfaceView.setZOrderOnTop(false);
mUnityPlayer.addView(unitySurfaceView);
//mUnityPlayer.resume();
}
在AS裏面查看UnityPlayer的代碼,發現是處理過的。
3.可以通過創建並顯示一個透明的PopupWindow的方式,實現在Unity上面顯示窗口的效果。
把資料裏面代碼直接拷貝過來會發現,缺少setPopUpWindowLayoutType。
這個TYPE_APPLICATION_SUB_PANEL是核心:
總之就是PopupWindow的默認屬性是TYPE_APPLICATION_PANEL,要改成TYPE_APPLICATION_SUB_PANEL,Unity的默認也是TYPE_APPLICATION_PANEL。TYPE_APPLICATION_SUB_PANEL會顯示在TYPE_APPLICATION_PANEL的前面。
百度上找不到什麼setPopUpWindowLayoutType()的有用的信息,goolge上能夠搜索到github裏面的代碼,其實像這樣找不到代碼時直接在github上找,一般能找到相關的線索。
這兩個都是UnityAndroid相關的項目,有空再研究研究。先把需要的代碼拿出來,參考1裏的
public static void setPopUpWindowLayoutType(PopupWindow popupWindow, int layoutType) {
try {
Method method = PopupWindow.class.getDeclaredMethod("setWindowLayoutType", int.class);
method.setAccessible(true);
method.invoke(popupWindow, layoutType);
} catch (NoSuchMethodException exception) {
Log.w(TAG, String.format("Unable to set popUpWindow window layout type: %s",
exception.getLocalizedMessage()));
} catch (IllegalAccessException exception) {
Log.w(TAG, String.format("Unable to set popUpWindow window layout type: %s",
exception.getLocalizedMessage()));
} catch (InvocationTargetException exception) {
Log.d(TAG, String.format("Unable to set popUpWindow window layout type: %s",
exception.getLocalizedMessage()));
}
}
感覺是用反射的方式修改屬性,大概沒有直接開放接口吧。(是不是也能繼承UnityPlayer並用反射的方式修改abcd呢...)
兩個代碼都加入項目中,(點擊按鈕)創建PopupWindow,看不到效果,因爲是透明的,relativeLayout弄個背景色,就能看到一個擋住全部區域的界面,包括Unity也被擋住了。
把要顯示的SurfaceViewRender放到裏面,可以顯示。但是問題是擋住了,也就意味着無法觸發Unity的事件了。我最開始不打算用Dialog也是因爲這個問題。
換個思路,修改PopupWindow的大小,不全屏,拖動PopupWindow就好了。
參考:5分鐘搞定PopUpWindow,Android Popupwindow 拖動
過程就不寫了,總之這個思路可以,最後得到個UnityPopupWinodw的類: