Unity3D项目导入Android Studio并利用Fragment显示


Unity3D导入AS并利用Fragment显示-本文较为详细介绍了,Unity3D项目导入AS,AS中显示Unity3D,利用Fragment显示Unity3D三个问题的主要过程,一些常见错误都在正文中指出,不再单独列出。

AS显示Unity3D场景

参考文章如下:
在Android(AS)中调用unity场景(view)
主要思路就是在Unity3D利用Gradle导出工程,以Module方式导入AS,再修改为library,完成功能。

Unity3D导出

1.设置Player Settings

主要设置内容为:Company Name、Product Name及Other Settings中的Package Name,至于参考文章中提到的Keystore我未做处理以及包名和AS中包名是否相同具体什么情况我不太了解,我在实践中是不相同的,目前并没有遇到问题。
主要截图如下:
Player Settings
Other Settings
Publishing Settings

2.导出项目

选中Gradle导出即可
导出设置如下:
导出
导出后得到文件目录:
文件目录

AS导入Unity3D项目

1.以Module形式导入Unity3D项目

导入

2.修改Module为library

1.导入时在AS中两个项目独立,图标显示这样:
导入
2.在build.gradle中将application修改为library
修改build.gradle
3.提示Sync,点击后报错,直接在build.gradle中删掉bundle()
报错
4.Try Again后,再次报错,这是因为设置了两个applicationId,将Unity3D中的删除即可
报错
删除applicationId
5.再次Try Again,成功,图标改变
图标改变

3.添加依赖

这个有多种方法,我是用AS设置。
1.打开Project Structure
Project Structure
2.在app依赖中添加Module依赖
添加依赖
选中
3.ok后报错(这是因为我的Unity3D项目中使用了别的库,各位自行了解),找不到这个库,我直接在app中添加这个依赖,VuforiaWrapper为aar文件,我将其复制到app的libs再依赖。
报错
复制

加依赖
4.Sync后报错,此时需要将libs加入路径,Try Again后成功
报错
加入路径

repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
    }

4.为了避免冲突及统一修改AndroidManifest

虽说会自动合并,但是我将所有统一写在app的AndroidManifest中
1.将Unity3D项目AndroidManifest中所有合并到app的AndroidManifest中(这里请自行设置常规设置),需要注意的是参考文章中提到的关于启动页的问题。
Unity3DAndroidManifest修改完后
注意需要删除图中选中代码(设置启动页)
删除

5.尝试组建

组建成功,说明导入完成
组建成功

在AS中测试是否能够打开Unity3D场景

通过刚刚导出的Module可以发现Unity3D项目只是提供一个Activity,当你进入这个Activity即可显示Unity3D中的场景,至于加载Unity3D中的那个View是由Unity3D项目自己控制的,当然可以通过AS和Unity3D交互完成切换,这里不讨论。

1.在app的MainActivity中添加一个按钮跳转到Unity3D场景

1.添加按钮,按钮添加过程略去
2.利用intent跳转,发现在打入UnityPlayerActivity过程中会有提示,这是因为我们在app中注册了Unity3D项目中提供的那个Activity
跳转
默认Activity

2.在虚拟机上运行测试

1.点击前
点击前
2.点击后
请求允许
进入虚拟相机场景
3.成功完成

在Fragment中显示Unity3D场景

之前提到Unity3D项目只提供了一个Activity,在Activity中发现具体是利用UnityPlayer完成。经过网上搜索后,成功实现在Fragment中显示Unity3D场景。参考文章如下:
android的fragment中嵌套unity3d+事件控制 附带实例
android与Unity3D交互,fragment显示unity3d视图

创建Fragment

1.创建一个AFragment继承Fragment(注意为v4支持),并添加onAttach、onCreateView、onPause、onResume方法

这几个方法在控制UnityPlayer时需要用到。过程略。

2.在app的MainActivity中创建Fragment容器,并加入AFragment

1.添加容器为了便于观察控制高度为300dp
容器
2.在MainActivity中实例化AFragment并添加至容器
实例化并添加

aFragment = new AFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fl_container_a,aFragment).commitAllowingStateLoss();

若报错
报错
说明没有继承v4的Fragment

3.虚拟机运行测试

虚拟机测试
由于AFragment什么也没有添加,所以显示为空白,但运行成功说明问题不大

在Fragment中添加UnityPlayer

1.在app中添加unity-classes依赖

因为在app需要用到UnityPlayer,故需要添加依赖
1.将jar包复制到app的libs中,添加依赖
加依赖
2.添加后Gradle为报错,但重新组建时,报错,这是因为app依赖的Unity3D项目library中同样依赖了unity-classes,故修改Unity3D中依赖方式为编译时依赖(我就这么一说)即可
报错
修改依赖方式,注意去掉之前那个依赖jar包语句
依赖

//implementation fileTree(dir: 'libs', include: ['*.jar'])
  compileOnly files('libs/unity-classes.jar')

3.Sync后成功,重新组建后成功。

2.在MainActivity中初始化UnityPlayer

这里使用参考文章中的那个方法,使用静态变量mUnityPlayer完成
1.创建一个新类继承Activity以储存静态变量mUnityPlayer
因为Android会自动回收,推荐使用这种方式管理静态变量
Constants类
2.在MainActivity中初始化mUnityPlayer
初始化

Constants.mUnityPlayer = new UnityPlayer(this);
int glesMode = Constants.mUnityPlayer.getSettings().getInt("gles_mode", 1);
Constants.mUnityPlayer.init(glesMode, false);

2.在MainActivity中关联mUnityPlayer的onResume、onPause、onDestroy、onConfigurationChanged、onWindowFocusChanged、dispatchKeyEvent(这些都可以在Unity3D项目中提供的UnityPlayerActivity中找到)
关联
关联

    @Override
    protected void onDestroy() {
        Constants.mUnityPlayer.quit();
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        Constants.mUnityPlayer.resume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        Constants.mUnityPlayer.pause();
        super.onPause();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Constants.mUnityPlayer.configurationChanged(newConfig);
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        Constants.mUnityPlayer.windowFocusChanged(hasFocus);
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return Constants.mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
        return super.dispatchKeyEvent(event);
    }

3.AFragment中返回mUnityPlayer的View,并关联

1.在onCreateView中返回playerView,注意这里windowFocusChanged的关联(黑屏问题)
onCreateView
2.关联onResume、onPause
关联

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mcontext = (Activity) context;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        playerView = Constants.mUnityPlayer.getView();
        if(playerView.getParent() != null){
            ((ViewGroup)playerView.getParent()).removeAllViews();
        }
        playerView.getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
            @Override
            public void onWindowFocusChanged(boolean hasFocus) {
                Constants.mUnityPlayer.windowFocusChanged(hasFocus);
            }
        });
        return playerView;
    }

    @Override
    public void onResume() {
        Constants.mUnityPlayer.resume();
        super.onResume();
    }

    @Override
    public void onPause() {
        Constants.mUnityPlayer.pause();
        super.onPause();
    }

4.大功告成虚拟机测试

1.点击按钮前
点击前
2.点击按钮后退出,原因好像是因为只能有一个UnityPalyer,这不是什么大问题了,mUnitypalyer已经是静态变量了
点击后

可能遇到的问题

1.运行时报错:No implementation found for void com.unity3d.player.UnityPlayer.nativeRestartActivityIndicator()

具体为什么并不清楚,大体上是因为build.gradle设置的问题(大概是32和64的问题),可以尝试在app的build.gradle中加上下面代码

sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
    }
  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值