ANDROID应用中嵌入Unity3D视图(展示3D模型)

转载请注明本文出自大苞米的博客(),谢谢支持!

效果展示:

开篇废话:

我现在所在的Team每周需要一个人给大家介绍一个知识点,或者新技术。这礼拜正好轮到我了,由于我工作才一年,面对那帮老鸟讲知识点感觉有点作死。所以我就准备选个新技术介绍一下。

由于我在大学里自学过一段时间Unity3D,所以我想介绍的技术就是它,但我现在做的是应用开发,不能做个小游戏去给大家演示。所以我想到比较简单,直观,而且有可能真正能用到的就是在Android应用中展示3D模型。比如在产品展示时直接把这个产品的3D模型展示出来而不是个图片,效果应该非常棒(OpenGL应该也可以做)。

思路定下以后就发现大学时学的Unity3D的内容基本忘光了,虽然偶尔有Unity3D的文章都会点开看看,但还是得重新学。记得当时学Unity3D的时候看过一个叫雨松MOMO的博客。那时年轻,懵懂,找不到方向的我还给雨松大神发了一封邮件去请教大学应该怎么学习和做游戏相关的问题,结果人家没回,导致我更加失落于是接着学android去了。。。又扯远了。。。于是我又找到他的博客,把Unity3D基础部分的相关文章都看了一遍。

但是他博客里有介绍如何在Unity3D中调用Android,而我想做的是在Android中调用Unity3D,而且是把Unity3D嵌套在ANDROID的视图里面。最后费了九牛二虎之力才把这个Demo做出来。

准备工作:

下面是我总结的流程,目的是使本文思路更加清晰一些:

1.Android端代码可以在Eclipse中开发(AndroidStudio没有试,应该也可以)

2.Unity3D端代码要在Unity中开发

3.Android和Unity3D端,两边都需要加入一些代码从而可以使之关联交互。

4.将Android端代码编译成jar文件以插件形式放入到Unity端中

5.在Unity中将整个项目Build成apk文件,然后安装到手机或模拟器里运行

本文主要讲解1,2,3。对于4,5建议大家去看雨松MOMO的Unity博客的第17篇和第18篇。

UnityPlay:

在编写Android端和Unity3d端代码前,有必要先了解一下可以使两部分交互的类UnityPlay。

个人理解UnityPlay是个Unity提供给外部交互的一个接口类。

为什么是“个人理解”?这我不得不爆粗口了,TMD官网根本就没有相关的API和文档(如果大家有谁找到一定给我来一份,就当我骂自己了)。

在关联Android时,想拿到UnityPlay以及相关类的jar包可以从下面的地址找到:Unity安装路径\Editor\Data\PlaybackEngines\androidplayer\bin在bin文件夹下有一个classes.jar的jar文件,它就是我们想要的。

而在bin同目录下有一个src文件,点击到最后有3个类,分别是UnityPlayerActivity.java,UnityPlayerProxyActivity.java,UnityPlayerNativeActivity.java。前两个打开个后只有一行代码,说的是UnityPlayerActivity和UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity。而打开UnityPlayerNativeActivity中居然有代码,而且我估计这应该是UnityPlayerNativeActivity的源码。

由于关于UnityPlay的资料我只找到这么一个,所以我把UnityPlayerNativeActivity中的代码都贴出来,如果我注解有不对的地方希望大家指正。

/** * UnityPlayerActivity,UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity * 而UnityPlayerNativeActivity继承自NativeActivity * 在该类里定义了一些和ANDROID生命周期相同的回调方法,留给自定义的Activity子类重写。 */public class UnityPlayerNativeActivity extends NativeActivity{//UnityPlayer的引用,并且我们不能改变这个引用变量的名字,它被native code所引用protected UnityPlayer mUnityPlayer;protected void onCreate (Bundle savedInstanceState){requestWindowFeature(Window.FEATURE_NO_TITLE);super.onCreate(savedInstanceState);// 设置显示窗口参数getWindow().takeSurface(null);setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);getWindow().setFormat(PixelFormat.RGB_565);// 创建一个UnityPlayer对象,并赋值给全局的引用变量mUnityPlayer = new UnityPlayer(this);//为UnityPlayer设置一些参数if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);boolean trueColor8888 = false;// UnityPlayer.init()方法需要在将view附加到layout之前调用。它将会调用native codemUnityPlayer.init(glesMode, trueColor8888);// 从UnityPlayer中获取到Unity的View视图View playerView = mUnityPlayer.getView();// 将Unity视图加载到根视图上setContentView(playerView);// 使Unity视图获取焦点playerView.requestFocus();}protected void onDestroy (){// 当Activity结束的时候调用UnityPlayer.quit()方法,它会卸载之前调用的native codemUnityPlayer.quit();super.onDestroy();}// 下面几个方法都是ANDROID相关回调方法,确保在ANDROID执行相应方法时UnityPlayer也需调用相应方法protected void onPause(){super.onPause();mUnityPlayer.pause();}protected void onResume(){super.onResume();mUnityPlayer.resume();}public void onConfigurationChanged(Configuration newConfig){super.onConfigurationChanged(newConfig);mUnityPlayer.configurationChanged(newConfig);}public void onWindowFocusChanged(boolean hasFocus){super.onWindowFocusChanged(hasFocus);mUnityPlayer.windowFocusChanged(hasFocus);}public boolean dispatchKeyEvent(KeyEvent event){if (event.getAction() == KeyEvent.ACTION_MULTIPLE)return mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);return super.dispatchKeyEvent(event);}}看完这个类后就知道了为什么在自定义的Activity中继承了UnityPlayerActivity等类以后,只要重写了onCreate并调用super.onCreate()方法后不需要任何其他的代码就会自动的显示出Unity3D的视图。因为初始化Unity视图的代码都在UnityPlayerNativeActivity父类中实现了。

ANDROID端代码:

在写ANDROID代码的时候,一定要导入Unity3D提供给我们的jar包,jar包的位置我在上面说了。引入jar包加入到buildpath中这些最基本的我就不多说了。

要想和Unity交互,我们就不能继承ANDROID提供给我们的Activity,我们需要继承刚才jar包中引入的Unity提供的Activity类,一共有这么3个:

累死累活不说,走马观花反而少了真实体验,

ANDROID应用中嵌入Unity3D视图(展示3D模型)

相关文章:

你感兴趣的文章:

标签云: