当前位置:   article > 正文

Unity 与Android 交互梳理_unity layout anr

unity layout anr

在这里插入图片描述

1.Unity 代码结构

由研发部门导出 Android Studio IDE可以识别的 Unity Module,手动进行依赖。代码结构同正常的Android Module 结构一致。

 Unity module -
      -build
      -libs
      -src
       -main
        -assets
        -java
        -jni
        -res
         AndroidManifest.xml
 build.gradle
 Gradle.properties
 Local.properties
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
2.Unity通信

项目中Unity 与Android由两种方式进行交互
方式一:unity 调用Android代码
在主Activity中声明与unity端协调好的方法及接收参数的类型
Public void toAppXXX( 参数类型 参数名)
方式二:Android 调用unity代码,底层实现方式由unity-class.jar 这个jar包进行封装。
UnitySendMessage(“GuiCamera”,“UserDataForUnity”,parameter);

Tip:
Unity 与 android 通信的原则,需要双方通信之前开启与unity的链接,onResume(),退出当前界面同时及时停止通信onPause( )

3.Unity初始化及资源解压

首先创建UnityPlayer,该对象继承Framlayout,需要将该对象添加到ViewTree中进行渲染

FrameLayout unityFrameLayout = getView(R.id.unity);
UnityPlayer mUnityPlayer = new UnityPlayer(this);
unityFrameLayout.addView(mUnityPlayer)
  • 1
  • 2
  • 3

将mUnityPlayer的生命周期与Activity进行绑定
主要关注

  • mUnityPlayer.resume(); //开启通信
  • mUnityPlayer.pause(); //暂停通信

资源解压分为obb(海外),非obb。

  • 包含obb的海外版本,需要加载obb之后解压
  • 非obb的国内版,在初始化mUnityplayer之后,展示第一个场景自动解压资源。
4.快速编写具有通信能力的类

4.1 新建空白Activity,取名DemoActivity,并且在DemoActivity布局文件中添加一个Framlayout,作为mUnityPlay的容器。

 <FrameLayout
        android:id="@+id/unity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
  • 1
  • 2
  • 3
  • 4
  • 5

4.2 在DemoActivity的onCreate()或者OnResume()生命周期中进行初始化。初始化方式:

Void onCreate(){
UnityPlayer  mUnityPlayer = UnityPlayViewManager.getUnityPlay();
  unityGameFrameLayout.addView(mUnityPlayer);
}
  • 1
  • 2
  • 3
  • 4

Tip:UnityPlayViewManager 是一个单例,存储管理全局唯一的UnityPlayer对象

4.3 . 完成通信能力关键,将UnityPlayer 的生命周期与Activity的生命周期进行绑定,通过下面模板代码进行绑定。

@Override protected void onNewIntent(Intent intent)
    {
        // To support deep linking, we need to make sure that the client can get access to
        // the last sent intent. The clients access this through a JNI api that allows them
        // to get the intent set on launch. To update that after launch we have to manually
        // replace the intent with the one caught here.
        setIntent(intent);
    }

    // Quit Unity
    @Override protected void onDestroy ()
    {
        mUnityPlayer.destroy();
        super.onDestroy();
    }

    // Pause Unity
    @Override protected void onPause()
    {
        super.onPause();
        mUnityPlayer.pause();
    }

    // Resume Unity
    @Override protected void onResume()
    {
        super.onResume();
        mUnityPlayer.resume();
    }
    @Override protected void onStart()
    {
        super.onStart();
        mUnityPlayer.start();
    }

    @Override protected void onStop()
    {
        super.onStop();
        mUnityPlayer.stop();
    }

    // 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); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

  • 1

4.4 开启通信开关进行通信

这里用开始游戏地方的样例代码

if ( mUnityPlayer != null)
mUnityPlayer.resume()  //打开开关

//向Unity 发送消息参数。
UnityHelper.roomDataForUnity(
mapId.toString(),
detailModel.mapName,
detailModel.mapMd5,
detailModel.mapScreenSchema.toString(),
detailModel.thumb270x153,
if (StringUtil.isEmpty(detailModel.mapCreateUserNickName)) "" else detailModel.mapCreateUserNickName)
//进入游戏
UnityHelper.enterGameForUnity()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.5 关闭通信开关

  override fun onPause() {
        super.onPause()
        if (isGameSwitch && mUnityPlayer != null) {
            mUnityPlayer.pause() //在生命周期中关闭
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Tips
通信开关,一直处于开启状态,会造成界面卡顿。

5.Unity集成需要修改的文件

替换Unity最新导出的Unity_Module 中assert文件夹全部内容,进入Assert文件夹里面修改config.json,config_en.json,config_plat.json,config_versionType.json四个文件中相应的配置与对应环境匹配。

海外版。需要额外替换清单文件中unity.build-id对应的值value,否则会导致obb合成失败,app模块下,AndroidManifest.xml

 <meta-data
            android:name="unity.build-id"
            android:value="5402c169-290b-44af-aa8a-378569ae6916" />
  • 1
  • 2
  • 3
6.Unity通信步骤

1.进入新的activity,关闭上一个activity类中unity通信,将上一个类中mUnityPalyer对象移到新的activity中使用。(mUnityPalyer 全局唯一)

2.在新的activity中奖unity-player 对象添加到新的activity,unity容器中。

3.在新的activity中需要进行通信地方,调用unity-player.resume( ) 方法开启通信开关(这里会有延时)

4.进行unity通信,发送message给unity

5.在MainActivity中处理Unity对activity的响应信息,编写分发逻辑。(EvenBus 进行通知),将响应信息分发到发起通信的类中,进行处理

6.退出新的Activity,在onPause()中暂停消息。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/96166
推荐阅读
相关标签
  

闽ICP备14008679号