我在网上搜索了类似的问题,虽然找到了一些相似的问题,但没有可靠的答案,这就是我在这里发布的原因。
当Unity3D项目编译为Android时,它基本上只是将场景作为一个Activity提供,您可以启动/结束等。我想将此Activity更改为Fragment,以便在导航抽屉中显示它作为选项卡,并在另一个fragment/activity的子视图中显示它。
所以基本上我有一个带有打开按钮的MainActivity
,和一个实际的Unity3D项目UnityPlayerNativeActivity
。
我搜索了如何将通用活动更改为片段,并更改了UnityPlayerNativeActivity
以匹配。例如,在下面新命名的UnityPlayerNativeFragment
中(其中的注释反映了从之前到现在确切的更改内容):
import com.unity3d.player.UnityPlayer;
// Other imports available in full code linked to below
public class UnityPlayerNativeFragment extends Fragment
{
// Changes in this class:
// 1- 'this' references changed to "getActivity()"
// 2- onCreate -> onCreateView
// 3- protected -> public in function names
// 4- @Override added before function calls
// 5- newInstance and onAttach added
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
private static final String ARG_SECTION_NUMBER = "section_number";
public static UnityPlayerNativeFragment newInstance(int sectionNumber) {
UnityPlayerNativeFragment fragment = new UnityPlayerNativeFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((HomeActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
// UnityPlayer.init() should be called before attaching the view to a layout - it will load the native code.
// UnityPlayer.quit() should be the last thing called - it will unload the native code.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
//below line removed because it was causing errors
//getActivity().requestWindowFeature(Window.FEATURE_NO_TITLE);
getActivity().getWindow().takeSurface(null);
getActivity().setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
getActivity().getWindow().setFormat(PixelFormat.RGB_565);
mUnityPlayer = new UnityPlayer(getActivity());
if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
getActivity().getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
mUnityPlayer.init(glesMode, trueColor8888);
View playerView = mUnityPlayer.getView();
return playerView;
}
@Override
public void onDestroy ()
{
mUnityPlayer.quit();
super.onDestroy();
}
// onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.
@Override
public void onPause()
{
super.onPause();
mUnityPlayer.pause();
}
@Override
public void onResume()
{
super.onResume();
mUnityPlayer.resume();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
}
AndroidManifest.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.SamerBekhazi.Test" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:theme="@style/AppTheme" android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:launchMode="singleTask" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="portrait" android:name=".HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
</activity>
</application>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
<uses-feature android:glEsVersion="0x00020000" />
</manifest>
我只包括了这两个文件,因为我认为问题可能来自其中一个。完整的代码可以在这里下载。将其解压缩/导入到Android Studio中-您可能需要按一次
Sync Project with Gradle Files
才能使其正常工作。该项目的其余部分基于Android Studio在创建新项目时自动创建的
Navigation Drawer Activity
项目。当按下相应图标时,我基本上只调用上述UnityPlayerNativeFragment
的newInstance
来实现它在NavigationDrawer
中的呈现。当我按场景选项卡时会出现什么结果:一个黑屏,Action Bar仍然显示,但其他什么也没有。右上角的“设置”按钮仍然可按,Navigation Drawer按钮也是如此,但是当您按下Navigation Drawer上的另一个选项卡时,整个应用程序都会冻结,您必须强制退出。我认为后者的问题是因为您无法关闭未正确打开的
UnityPlayer
,因此主要问题实际上是在Fragment内正确打开UnityPlayer
。应用程序的其余部分(其他选项卡)工作正常。我在上述代码和AndroidManifest.xml
文件中尝试了几种变化(我所能想到的一切),但都没有起作用。Logcat中没有显示任何错误,只是说:
11-11 21:22:19.681 29280-29280/com.Bekhazi.Bouncy_Ball W/linker﹕ libmain.so has text relocations. This is wasting memory and is a security risk. Please fix.
11-11 21:22:19.681 29280-29280/com.Bekhazi.Bouncy_Ball D/dalvikvm﹕ Added shared lib /data/app-lib/com.Bekhazi.Bouncy_Ball-2/libmain.so 0x42d64cd8
11-11 21:22:19.691 29280-29280/com.Bekhazi.Bouncy_Ball W/linker﹕ libmono.so has text relocations. This is wasting memory and is a security risk. Please fix.
11-11 21:22:19.691 29280-29280/com.Bekhazi.Bouncy_Ball W/linker﹕ libunity.so has text relocations. This is wasting memory and is a security risk. Please fix.
这里到底出了什么问题?目标构建是针对Android 5.0的,而我正在使用Android Studio 0.8.14。 值得注意的是:当它是一个Activity时,我能够成功地将场景加载到我的Nexus 5上。