Android - 在活动中嵌入Unity3d场景 - 需要取消注册接收器吗?

gts*_*101 8 android unity-game-engine

我已经成为一名SO成员了一段时间,但从未真正问过一个问题,所以这里......

我的目标

我正在尝试制作一个包含两项活动的Android应用.第一个是菜单屏幕(使用标准的Android UI元素),其中有一个用于打开游戏活动的按钮.游戏活动将包含一些标准的Android UI元素和包含Unity 3D场景的FrameLayout.

我正在使用Unity 5和Eclipse Luna.

我有什么工作

我用一个简单的按钮创建菜单屏幕,开始第二个活动.我已经按照本教程设法将我的Unity场景嵌入到我的第二个活动中.到目前为止一切都好...

问题

我第一次开始玩游戏活动它工作正常(我可以看到嵌入在我的FrameLayout中的Unity场景),但如果我关闭活动(返回菜单活动)然后再次启动游戏活动我得到此错误.. .

Activity has leaked IntentReceiver com.unity3d.player.UnityPlayer$17@41866de0 that was originally registered here.  Are you missing a call to unregisterReceiver()?
Run Code Online (Sandbox Code Playgroud)

我试过的

我在线搜索了很多,看起来我需要在onPauseonDestroy上调用类似的东西;

m_UnityPlayer.currentActivity.unregisterReceiver(receiver);
Run Code Online (Sandbox Code Playgroud)

...但我不知道接收器是什么,所以我无法在我的unregisterReceiver调用中引用它.我已经尝试创建一个BroadcastReceiver,注册它然后取消注册onPause但它没有任何区别.

在团结论坛上找到了一个帖子,询问了完全相同的问题但是,令人沮丧的是,它没有答案(Unity论坛上的很多问题似乎都没有答案,这就是我带着这个问题来到这里的原因).

我也试过在onDestroy中调用这个方法但是当我关闭游戏活动时它实际上会退出我的整个应用程序.

m_UnityPlayer.quit();
Run Code Online (Sandbox Code Playgroud)

代码示例

这是我的游戏活动的代码(为清楚起见,我删除了导入);

public class MyEmbeddedUnityActivity extends Activity {
    private UnityPlayer m_UnityPlayer;
    IntentFilter filter = new IntentFilter("");
    private BroadcastReceiver bRec = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //String action = intent.getAction();
            Log.d("", "onReceive intent: " + intent);
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_embedded_unity);

        if(m_UnityPlayer==null){
            m_UnityPlayer = new UnityPlayer(this);
            int glesMode = m_UnityPlayer.getSettings().getInt("gles_mode", 1);
            m_UnityPlayer.init(glesMode, false);

            m_UnityPlayer.currentActivity.registerReceiver(bRec, filter);

            FrameLayout layout = (FrameLayout) findViewById(R.id.my_frame);
            LayoutParams lp = new LayoutParams(200, 300);
            layout.addView(m_UnityPlayer, 0, lp);
        }

    }

    public void onWindowFocusChanged(boolean hasFocus){
        super.onWindowFocusChanged(hasFocus);
        m_UnityPlayer.windowFocusChanged(hasFocus);
    }

    @Override
    public void onDestroy (){
        //m_UnityPlayer.quit();
        m_UnityPlayer.currentActivity.unregisterReceiver(bRec);
        super.onDestroy();
    }

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

最后......

我在2011年编写了嵌入Unity场景的步骤.整个过程(从Unity项目的暂存区域抓取文件并复制文件等)看起来真的很笨拙且没有文档记录.

有没有更好的方法在Unity活动中嵌入Unity场景中的Unity场景?当然,将Unity场景添加到现有应用程序是一件相当普遍的事情吗?

谢谢,任何帮助将不胜感激!

gts*_*101 11

所以,我做了一些搜索,最终找到了答案,就在这里!

正如本回答中所讨论的,将此行添加到清单中可以解决问题;

android:process=":UnityKillsMe"
Run Code Online (Sandbox Code Playgroud)

所以清单的相关部分看起来像这样;

...

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <activity
        android:name=".Studio"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:process=":UnityKillsMe"
        android:label="@string/title_activity_home" > 
    </activity>

...
Run Code Online (Sandbox Code Playgroud)

这会强制游戏活动在单独的过程中启动.这意味着您可以m_UnityPlayer.quit()onDestroy不关闭整个应用程序的情况下调用activity的方法.

简单的修复,但令人讨厌的是它似乎完全没有记录.

希望这有助于某人!