2015-11-06 15 views
13

Sto costruendo un'applicazione Android che include un'esperienza interattiva Unity 3d.Android UnityPlayerAttività Barra azioni

Ho importato il progetto Unity in Android Studio ma quando viene avviato l'attività è a schermo intero e non mostra la barra delle azioni di Android.

Come posso fare questo?

integrazione Passi

  • Crea nuovo progetto Unity.
  • Esportare "Progetto Google Android" da Unity.
  • Importare il progetto in Android Studio.

Solutions Tentativo

  • Cambiare il tema nel manifesto.
  • Impostazione del tema nella classe Java UnityPlayerActivity.
  • Sovrascrittura di Unity Android Manifest inserendo un manifest con un tema aggiornato nella directory Unity/Assets/Plugins/Android.
  • Modifica di UnityPlayerActivity per estendere AppCompatActivity. Questo mostrerà la barra delle azioni ma c'è un divario bianco tra esso e la barra di stato.
  • Impostazione "Screen.fullScreen = false;" in Unity SceneManager. Ciò rimuove la modalità immersiva in modo che la barra di stato di Android sia visibile.
  • Disattivazione "Barra di stato nascosta" nelle impostazioni del lettore. Sembra non avere alcun effetto.
  • Avvolgimento di UnityPlayer in un FrameLayout. Questo mi consente di ridimensionare l'Unità come 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); } 
} 
+0

ho scritto è stata modificata a tema in palese ma nell'esempio uno non c'è @android: stile/Theme.NoTitleBar.Fullscreen. È questo un tema che hai cambiato? Se no, allora cos'era? – Lingviston

+0

@Lingviston Il codice che ho pubblicato mostra l'integrazione originale. Ho provato a cambiare il tema in 'android: theme =" @ android: style/Theme.Material.Light.DarkActionBar "' su entrambi i tag delle applicazioni e delle attività, ma nessuno ha reso visibile la barra delle azioni. – Morepork

+0

@Morepork hai trovato una soluzione? – Piotr

risposta

4

credo di aver trovato la soluzione.
Cambio che la linea:

mUnityPlayer = new UnityPlayer(this); 

così crea il proprio UnityPlayer sottoclasse, che sostituisce setFullscreen metodo (po 'hacky):

public class UnityPlayerWrapper extends UnityPlayer { 
    public UnityPlayerWrapper(ContextWrapper contextWrapper) { 
     super(contextWrapper); 
    } 

    @Override 
    protected void setFullscreen(boolean b) { 
     super.setFullscreen(false); 
    } 
} 

Inoltre, rimuovere quella linea: requestWindowFeature(Window.FEATURE_NO_TITLE);

+0

Ho provato questo nel mio progetto ma non vedo una barra delle azioni. Testato su un Samsung Galaxy S6 con Android 5.1 .1. – Morepork

+0

hai disabilitato anche quella linea - requestWindowFeature (Window.FEATURE_NO_TITLE);? – Piotr

+1

Lavora dopo aver disabilitato la funzione no title. Grazie @Piotr. – Morepork

6

per Unity versione 5.5 il modo migliore per evitare la modalità Immersive in Android è passare il costruttore non un'attività ma eseguire cast di ApplicationContext nel contesto wrapper.

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

Questo funziona perché nel UnityPlayer.class offuscato (in unità-classes.jar) v'è un controllo di un'istanza.

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

Quindi, se non è un'attività, UnityPlayer.class non imposta il flag.

+0

che mostra barra degli strumenti ora dopo aver cambiato in ContextWrapper.ma problema è che ora la visualizzazione della fotocamera non rendering. Puoi per favore dare alcuni suggerimenti ? –

+0

È possibile utilizzare le funzioni di estensione di kotlin per ignorare questo metodo? –

+0

Sfortunatamente non è possibile e per sovrascrivere quel metodo, perché è privato. Si potrebbe fare con una soluzione sporca: usando la riflessione. –

0

Piotr risposta sta lavorando per la versione più vecchia e la risposta di Lorenzo DM anche valido, ma

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

non funziona in alcuni dispositivi. Così alla fine ho modificare UnityPlayerActivity qui è la nuova soluzione



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); } 
} 
Problemi correlati