Java 将Unity3D场景导入Android片段

Java 将Unity3D场景导入Android片段,java,android,android-fragments,unity3d,Java,Android,Android Fragments,Unity3d,我在网上搜索过类似的问题,虽然我找到了几个类似的问题,但没有一个有可靠的答案,这就是为什么我在这里发帖的原因 当Unity3D项目为Android编译时,它基本上只是将场景作为一个活动提供,您可以开始/结束/等等。我想将此活动更改为一个片段,以便将其显示为导航抽屉中的选项卡,以及另一个片段/活动中的子视图 所以基本上我有一个带有打开按钮的main活动,还有一个UnityPlayerNativeActivity,这是实际的Unity3D项目 我搜索了如何将常规活动更改为片段,并将UnityPlay

我在网上搜索过类似的问题,虽然我找到了几个类似的问题,但没有一个有可靠的答案,这就是为什么我在这里发帖的原因

当Unity3D项目为Android编译时,它基本上只是将场景作为一个活动提供,您可以开始/结束/等等。我想将此活动更改为一个片段,以便将其显示为导航抽屉中的选项卡,以及另一个片段/活动中的子视图

所以基本上我有一个带有打开按钮的
main活动
,还有一个
UnityPlayerNativeActivity
,这是实际的Unity3D项目

我搜索了如何将常规活动更改为片段,并将
UnityPlayerActiveActivity
更改为匹配。例如,在下面新标题的
UnityPlayerNativeFragment
中(注释反映了与以前完全不同的内容):

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 5.0,我使用的是Android Studio 0.8.14。
值得注意的是:当场景是一项活动时,我能够成功地将其加载到我的Nexus 5上。

尝试这种方式,它会在我身边工作

1.在活动中创建UnityPlayer

    private UnityPlayer mUnityPlayer;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mUnityPlayer = new UnityPlayer(this);
2.关于碎片


私人MyActivity社区MainActivity;
专用单位层市政层;
查看playerView;
@覆盖
创建视图上的公共视图(更平坦的充气机,
@Nullable视图组容器,@Nullable Bundle savedInstanceState){
//TODO自动生成的方法存根
mUnityMainActivity=(MyActivity)getActivity();
mUnityPlayer=mUnityMainActivity.GetUnityPlayer();
playerView=mUnityPlayer.getView();
LayoutParams lp=新的LayoutParams(LayoutParams.FILL\u父级,LayoutParams.FILL\u父级);
playerView.setLayoutParams(lp);
if(playerView.getParent()!=null){
((ViewGroup)playerView.getParent()).removeAllViews();
        }
返回playerView;

}
通过上面提供的帮助和以下链接,我成功地将其集成到一个片段中:

在活动中采用标准方法至关重要

下文将详细阐述:

  • 在保存片段的活动中(
    MyActivity
    ):
    • 声明变量UnityPlayer mUnityPlayer

    • 这将触发导入
      import com.unity3d.player.UnityPlayer

    • 在下面添加所有覆盖代码

      //region Lifecycle methods
      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mUnityPlayer = new UnityPlayer(this);
      }
      
      /** FOR 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); }
      @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); }
      
      @Override
      protected void onDestroy() {
        super.onDestroy();
        mUnityPlayer.quit();
      }
      
  • 在片段中:
    • 变量声明私有MyActivity MyActivity

    • 变量声明:私有UnityPlayer UnityPlayer

    • 这将触发“导入com.unity3d.player.UnityPlayer;”

    • 以下代码

      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      myActivity = (MyActivity) getActivity();
      View unityPlayViewer = calibActivity.mUnityPlayer.getView();
      new Handler().postDelayed(() -> initialize(), 5000);
      return unityPlayViewer;
      }
      
      private void initialize() {
      calibActivity.mUnityPlayer.UnitySendMessage("your commands to Unity to start playing");
      }
      

    你做到了吗?没有,我最终使用了与Unity完全不同的东西,原因有很多。
    //region Lifecycle methods
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mUnityPlayer = new UnityPlayer(this);
    }
    
    /** FOR 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); }
    @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); }
    
    @Override
    protected void onDestroy() {
      super.onDestroy();
      mUnityPlayer.quit();
    }
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myActivity = (MyActivity) getActivity();
    View unityPlayViewer = calibActivity.mUnityPlayer.getView();
    new Handler().postDelayed(() -> initialize(), 5000);
    return unityPlayViewer;
    }
    
    private void initialize() {
    calibActivity.mUnityPlayer.UnitySendMessage("your commands to Unity to start playing");
    }