Barra de Acción de Android UnityPlayerActivity

Estoy construyendo una aplicación para Android que incluye una experiencia interactiva de Unity 3d.

He importado el proyecto de Unity en Android Studio, pero cuando se inicia la actividad es de pantalla completa y no muestra la barra de acción de Android.

¿Cómo puedo hacer esto?

Pasos de integración

  • Crear nuevo proyecto Unity.
  • Exportar "Google Android Project" de Unity.
  • Importar proyecto en Android Studio.

Soluciones intentadas

  • Cambiar el tema en el manifiesto.
  • Configuración del tema en la clase Java de UnityPlayerActivity.
  • Anulando el manifiesto de Unity Android colocando un manifiesto con un tema actualizado en el directorio Unity / Activos / Plugins / Android.
  • Cambiar UnityPlayerActivity para extender AppCompatActivity. Esto mostrará la barra de acción pero hay una brecha blanca entre ella y la barra de estado.
  • Configuración "Screen.fullScreen = false;" En Unity SceneManager. Esto elimina el modo de inmersión para que la barra de estado de Android sea visible.
  • Desactivación de "Barra de estado oculta" en la configuración del reproductor. Aparece sin efecto.
  • Envolviendo el UnityPlayer en un FrameLayout. Esto me permite cambiar el tamaño de la Unidad como una vista.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.unity.test" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" /> <application android:banner="@drawable/app_banner" android:debuggable="false" android:icon="@drawable/app_icon" android:isGame="true" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> <activity android:name="com.company.unity.test.UnityPlayerActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="fullSensor"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" /> <uses-feature android:glEsVersion="0x00020000" /> <uses-feature android:name="android.hardware.sensor.accelerometer" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" /> </manifest> 

UnityPlayerActivity.java

 package com.company.unity.test; import android.app.Activity; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Window; import com.unity3d.player.UnityPlayer; public class UnityPlayerActivity extends Activity { protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy mUnityPlayer = new UnityPlayer(this); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } } 

Creo que he encontrado la solución.
Cambiar esa línea:

 mUnityPlayer = new UnityPlayer(this); 

Por lo que crea su propia subclase UnityPlayer , que anula el método setFullscreen (hacky poco):

 public class UnityPlayerWrapper extends UnityPlayer { public UnityPlayerWrapper(ContextWrapper contextWrapper) { super(contextWrapper); } @Override protected void setFullscreen(boolean b) { super.setFullscreen(false); } } 

Además, elimine la línea: requestWindowFeature(Window.FEATURE_NO_TITLE);

Para Unity versión 5.5 la mejor manera de evitar el modo Immersive en Android es pasar en el constructor no una actividad, sino para transmitir el ApplicationContext al contexto de Wrapper.

 mUnityPlayer = new UnityPlayer((ContextWrapper) getApplicationContext()); 

Eso funciona porque en la UnityPlayer.class ofuscada (en unit-classes.jar) hay una comprobación de instancia.

  private void h() { if(this.h instanceof Activity) { ((Activity)this.h).getWindow().setFlags(1024, 1024); } } 

Así que si no es una actividad, la UnityPlayer.class no establece el indicador.

La respuesta de Piotr está funcionando para la versión anterior y la respuesta de Lorenzo DM también es válida pero

 mUnityPlayer = new UnityPlayer((ContextWrapper) getApplicationContext()); 

No funciona en algunos dispositivos. Así que finalmente he modificar UnityPlayerActivity aquí es una nueva solución

 public class UnityPlayerActivity extends AppCompatActivity { protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code ActionBar actionBar; private Toolbar toolbar; private FrameLayout unityContainer; // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); mUnityPlayer = new UnityPlayer(this); setContentView(R.layout.activity_unity_player); mappingWidgets(); init(); } void mappingWidgets(){ toolbar = (Toolbar) findViewById(R.id.toolbar); unityContainer = (FrameLayout) findViewById(R.id.unity_container); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); unityContainer.addView(mUnityPlayer.getView(), 0, layoutParams); mUnityPlayer.requestFocus(); } void init(){ setSupportActionBar(toolbar); actionBar = getSupportActionBar(); if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); onDestroy(); } }); setTitle(getString(R.string.app_name)); } @Override protected void onNewIntent(Intent intent) { setIntent(intent); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // Low Memory Unity @Override public void onLowMemory() { super.onLowMemory(); mUnityPlayer.lowMemory(); } // Trim Memory Unity @Override public void onTrimMemory(int level) { super.onTrimMemory(level); if (level == TRIM_MEMORY_RUNNING_CRITICAL) { mUnityPlayer.lowMemory(); } } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer //@Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK) { finish(); onDestroy(); return true; } return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } } 
  • Detectar si otro jugador salió involuntariamente (por ejemplo, desconexión de Internet) y volver a conectar - Google play en tiempo real multijugador
  • La mejor manera de crear un cliente de chat Android XMPP en Unity3D
  • Ant jar error: Execute failed: java.io.IOException: No se puede ejecutar el programa ... $ {aapt} ": error = 2, No hay tal archivo o directorio
  • Vista más reciente o reorientada con SDK de cartón en Unity
  • Obtener un puntero JNIEnv válido
  • Proguard con código de error de devolución Unity3d 1
  • ¿Cómo puedo conectar mi teléfono Android a la unidad para los juegos de prueba?
  • ¿La API del complemento de servicios de Google Play de Unity no está sincronizada con la función de interfaz de usuario de Show Leaderboard?
  • Unity no puede fusionar el error de generación de manifiestos de Android
  • Exportación y ejecución del proyecto Unity3D a Android Studio
  • Library plugin :: Recursos de la biblioteca no encontrados
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.