I am building an Android application which includes a Unity 3d interactive experience.
I have imported the Unity project into Android Studio but when launched the activ
Piotr answer is working for older version and Lorenzo DM's answer also valid but
mUnityPlayer = new UnityPlayer((ContextWrapper) getApplicationContext());
not working in some devices. So Finally I've modify UnityPlayerActivity here is new solution
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); }
}
I think I've found solution.
Change that line:
mUnityPlayer = new UnityPlayer(this);
so it creates your own UnityPlayer
subclass, which overrides setFullscreen
method (little bit hacky):
public class UnityPlayerWrapper extends UnityPlayer {
public UnityPlayerWrapper(ContextWrapper contextWrapper) {
super(contextWrapper);
}
@Override
protected void setFullscreen(boolean b) {
super.setFullscreen(false);
}
}
In addition, please remove that line: requestWindowFeature(Window.FEATURE_NO_TITLE);
for Unity version 5.5 best way to avoid Immersive Mode in Android is to pass in the constructor not an Activity but to cast of the ApplicationContext to the Wrapper Context.
mUnityPlayer = new UnityPlayer((ContextWrapper) getApplicationContext());
That works because in the obfuscated UnityPlayer.class (in unity-classes.jar) there is a check of instance.
private void h() {
if(this.h instanceof Activity) {
((Activity)this.h).getWindow().setFlags(1024, 1024);
}
}
So if it's not an Activity the UnityPlayer.class doesn't set the flag.