Интегрируйте Unity3d view в активность Android
В настоящее время я работаю над небольшим AR-приложением для Android и сталкиваюсь с проблемой интеграции Unity3d в деятельность. Требования указывают, что мне нужно иметь возможность представить некоторые пользовательские интерфейсы Android - например, меню и панель действий - и вид с камеры, на котором будет отображаться модель, созданная в Unity3d при обнаружении цели.
Я нашел ссылку, которая мне очень помогла: форумы Unity3d. Один из пользователей там задал тот же вопрос, что и сейчас, но так и не получил правильного ответа - вот почему я публикую здесь.
Проблема:
У меня есть небольшой проект Unity3d, который по сути является белым кубом, и я пытаюсь отобразить его в одном из моих действий на Android. Модель выглядит хорошо, когда нет активности setContentView()
в его onCreate()
метод, но тогда я не могу указать свой макет в файле XML.
Когда я добавлю setContentView()
метод, я могу видеть куб, но он очень маленький, и, кажется, нет никакого способа заставить его изменить его размер.
XML-файл:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/unityView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
1-й вариант реализации мероприятия:
public class HomeActivity extends UnityPlayerActivity {
UnityPlayer unityPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
И полученный скриншот:
2-й вариант реализации мероприятия:
public class HomeActivity extends UnityPlayerActivity {
UnityPlayer unityPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
unityPlayer = new UnityPlayer(this);
int glesMode = unityPlayer.getSettings().getInt("gles_mode", 1);
unityPlayer.init(glesMode, false);
FrameLayout layout = (FrameLayout) findViewById(R.id.unityView);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
layout.addView(unityPlayer.getView(), 0, lp);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
unityPlayer.windowFocusChanged(hasFocus);
}
}
И полученный скриншот:
Может ли кто-нибудь объяснить мне, почему это и как это исправить?
1 ответ
Хотя я до сих пор не знаю, почему это так, я нашел способ исправить это.
Вместо того, чтобы просто использовать setContentView()
в onCreate()
, расширить onResume()
и в этом методе рекурсивно просматривайте все доступные представления, чтобы найти родительское представление объекта UnityPlayer. Как только это найдено, макеты и другие представления могут быть накачаны и добавлены в это родительское представление.
Вот ссылка с примером кода - я использовал это, чтобы заставить мое приложение работать: https://developer.vuforia.com/resources/dev-guide/extending-unity-android-activity-and-adding-custom-views-eclipse
Изменить: Вот фрагмент кода, показывающий мое решение.
@Override
public void onResume() {
super.onResume();
if (unityPlayer == null) {
View rootView = findViewById(android.R.id.content);
unityPlayer = findUnityPlayerView(rootView);
if (unityPlayer != null) {
ViewGroup unityPlayerParentView = (ViewGroup)(unityPlayer.getParent());
View mainHomeView = getLayoutInflater().inflate(R.layout.activity_main, null);
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
unityPlayerParentView.addView(mainHomeView, layoutParams);
}
}
}
а также
private UnityPlayer findUnityPlayerView(View view) {
if (view instanceof UnityPlayer) {
return (UnityPlayer) view;
}
if (view instanceof ViewGroup) {
ViewGroup childrenViews = (ViewGroup) view;
for (int i = 0; i < childrenViews.getChildCount(); i++) {
UnityPlayer foundView = findUnityPlayerView(childrenViews.getChildAt(i));
if (foundView != null) {
return foundView;
}
}
}
return null;
}