android与Unity3D交互,fragment显示unity3d视图。

这两天刚刚接触Unity3d,之前一直是做android开发,对于Unity3d的开发有专门的人才,我主要涉及在Unity3d与android的交互,经过两天是实验终于完成了下面的效果:

本来想写几篇博客,来详细说明下Unity3d导出android Project然后再进行二次开发的过程,后来发现几篇博客,过程和我的类似,对于重复的过程我就不写了,大家参考他的博客就可以了。而且,包括了Unity3d调用android脚本,这一块我暂时还没有涉及。

Unity3D游戏开发之Unity与Android交互调用研究

Unity3D游戏开发之在Android视图中嵌入Unity视图

Unity3D游戏开发之从Unity3D到Eclipse

在此,道一声博主辛苦,对于上面的三篇博客大家看完之后,肯定已经可以从Unity3d导出android project,然后再倒入Eclipse了。我们可以看到MainActivity不是继承自NativeActivity就是集成自UnityPlayerActivity(或者UnityPlayerNativeActivity),这样就会给新手一个错觉,就是要展示Unity3d的视图,就必须要集成自这几个接口,那么这个想法,是错误的,具体大家可以参考一下这个博客:

这个帖子中,就是使用继承自Activity的类来展示的U3d的视图。

这样的话,之前可能存在的一个问题,如果只能继承自那几个类,那么supportV4包中的Fragment岂不是不能用了,我们都知道,android.app.Fragment只支持2.3以上的版本,而V4中可以支持到1.6,所以一般来说都推荐大家使用V4包中的Fragment。

好了,说完这个问题,我们就看上面那个效果,如果在android原生应用的话,这个是很常见也很简单的应用,我们可以不停的切换中间的Fragment。

那么换成Fragment来展示U3d,并且相互切换的话,应该怎么样书写代码呢?大家看看下面两个代码块。

/** * 主界面 * @author gavin * */public class MainActivity extends FragmentActivity implements OnClickListener {private Button btn1;private Button btn2;private FragmentManager fm;View playerView;private Fragment currentFragment;private U3dFragment u3dFragment = new U3dFragment();private MenuOneFragment menuOneFragment = new MenuOneFragment();private MenuTwoFragment menuTwoFragment = new MenuTwoFragment();@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);Constants.mUnityPlayer = new UnityPlayer(this);int glesMode = Constants.mUnityPlayer.getSettings().getInt("gles_mode", 1);boolean trueColor8888 = false;Constants.mUnityPlayer.init(glesMode, trueColor8888);fm = getSupportFragmentManager();setContentView(R.layout.activity_main);initView();currentFragment = u3dFragment;changeFragment(currentFragment);}/** * 初始化控件 */private void initView(){btn1 = (Button) findViewById(R.id.btn1);btn2 = (Button) findViewById(R.id.btn2);btn1.setOnClickListener(this);btn2.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch(v.getId()){case R.id.btn1:Toast.makeText(MainActivity.this, "btn1", Toast.LENGTH_SHORT).show();if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuTwoFragment){currentFragment = menuOneFragment;changeFragment(currentFragment);}else{currentFragment = u3dFragment;changeFragment(currentFragment);}break;case R.id.btn2:Toast.makeText(MainActivity.this, "btn2", Toast.LENGTH_SHORT).show();if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuOneFragment){currentFragment = menuTwoFragment;changeFragment(currentFragment);}else{currentFragment = u3dFragment;changeFragment(currentFragment);}break;}}/** * 方法用来改变界面 */private void changeFragment(Fragment fragment){FragmentTransaction ft = fm.beginTransaction();ft.replace(R.id.content, fragment);ft.commit();}protected void onDestroy (){Constants.mUnityPlayer.quit();super.onDestroy();}// onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.protected void onPause(){super.onPause();Constants.mUnityPlayer.pause();}protected void onResume(){super.onResume();Constants.mUnityPlayer.resume();}public void onConfigurationChanged(Configuration newConfig){super.onConfigurationChanged(newConfig);Constants.mUnityPlayer.configurationChanged(newConfig);}public void onWindowFocusChanged(boolean hasFocus){super.onWindowFocusChanged(hasFocus);Constants.mUnityPlayer.windowFocusChanged(hasFocus);}public boolean dispatchKeyEvent(KeyEvent event){if (event.getAction() == KeyEvent.ACTION_MULTIPLE)return Constants.mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);return super.dispatchKeyEvent(event);}}上面是Activity的写法。

/** * 展示u3d的界面 * @author gavin * */public class U3dFragment extends Fragment {private Activity context;View playerView;@Overridepublic void onAttach(Activity activity) {// TODO Auto-generated method stubsuper.onAttach(activity);context = activity;}@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);}@Overridepublic View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {// TODO Auto-generated method stubplayerView = Constants.mUnityPlayer.getView();LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);playerView.setLayoutParams(lp);if(playerView.getParent() != null){((ViewGroup)playerView.getParent()).removeAllViews();}return playerView;}@Overridepublic void onDestroy() {// TODO Auto-generated method stub//Constants.mUnityPlayer.quit();super.onDestroy();}@Overridepublic void onPause() {// TODO Auto-generated method stubsuper.onPause();Constants.mUnityPlayer.pause();}@Overridepublic void onResume() {// TODO Auto-generated method stubsuper.onResume();Constants.mUnityPlayer.resume();}}上面是展示U3d视图的Fragment的写法。

要注意的有以下几点:

1.UnityPlayer这个对象被定义为了静态变量,在MainActivity中进行初始化,在Fragment中进行使用,用来获取Unity3d的view。

2.在U3dFragment中没有在onDestroy中,,调用quit()方法。

3.在U3dFragment中的onCreateView()方法中,进行了下面的处理。

((ViewGroup)playerView.getParent()).removeAllViews();

对于上面三个问题,如果不处理会相应的引发下面三个问题。

1.展示U3d视图的Fragment无法显示Unity3d的动画效果。

2.切换页面的时候会报下面的错误:

为何是一个人?也有善意的提醒:

android与Unity3D交互,fragment显示unity3d视图。

相关文章:

你感兴趣的文章:

标签云: