Интегрируйте 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;
}
Другие вопросы по тегам