如何将unity模型导入android程序中

如何将unity模型导入android程序中,第1张

 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 code

mUnityPlayer.init(glesMode, trueColor8888)

// 从UnityPlayer中获取到Unity的View视图

View playerView = mUnityPlayer.getView()

// 将Unity视图加载到根视图上

setContentView(playerView)

// 使Unity视图获取焦点

playerView.requestFocus()

}

protected void onDestroy ()

{

// 当Activity结束的时候调用UnityPlayer.quit()方法,它会卸载之前调用的native code

mUnityPlayer.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个:

UnityPlayerActivity,UnityPlayerProxyActivity,UnityPlayerNativeActivity。具体区别不知道,因为没有文档,没有API,没有源码(这里再次鄙视一下)。刚才我们看过UnityPlayerNativeActivity的代码(虽然很短,但我觉得这个就是源码),知道UnityPlayerActivity,UnityPlayerProxyActivity都是它的子类,而且最终父类为NativeActivity。所以我们继承Unity提供的最外层的子类是最好的选择,我这里选择的是UnityPlayerActivity,因为名字最简单,觉得该封装的都应该封装好了。

public class MainActivity extends UnityPlayerActivity {

private Button topButton

private Button bottomButton

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

// 设置test为我们的根布局

setContentView(R.layout.test)

// 通过刚才的源码分析,知道mUnityPlayer为一个全局的引用变量,而且已经在父类中设置好了,所以直接拿来用就可以了

View playerView = mUnityPlayer.getView()

// 将Unity的视图添加到我们为其准备的父容器中

LinearLayout ll = (LinearLayout) findViewById(R.id.unityViewLyaout)

ll.addView(playerView)

// 上面的button设置监听器

topButton = (Button) findViewById(R.id.topButton)

topButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//发送消息给Unity端,该函数第一个参数为接受消息的类对象,第二个该类对象用接受消息的方法,第三个参数为传递的消息

//所以下面的意思就为:调用Main Camera下面的Previous方法,传送的消息为空

UnityPlayer.UnitySendMessage("Main Camera","Previous","")

}

})

// 为下面的button设置监听器

bottomButton = (Button) findViewById(R.id.bottomBtn)

bottomButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//调用Main Camera下面的Next方法,传送的消息为空

UnityPlayer.UnitySendMessage("Main Camera","Next","")

}

})

}

}

最后看一下Android端的布局文件,布局很简单,上下各有一个button按钮,两个按钮中间是Unity的视图。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<Button

android:id="@+id/topButton"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:text="PREVIOUS" />

<LinearLayout

android:id="@+id/unityViewLyaout"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_above="@+id/bottomBtn"

android:layout_below="@+id/topButton"

android:orientation="horizontal" >

</LinearLayout>

<Button

android:id="@+id/bottomBtn"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:text="NEXT" />

</RelativeLayout>

Android端的代码就介绍完了,很简单。唯一的难点就是UnityPlayerActivity和UnityPlayer的使用。

首先我们要创建一个android项目因为项目需要使用Unity提供的接口,所以需要将接口classes.jar引入至当前工程但中。接口包的所在地,打开Finder->应用程序->Unity->点击Unity图标,鼠标右键选择“显示包内容”->Contents->PlaybackEngines->AndroidPlayer->bin->classes.jar 。接口包引入工程后,开始编写JAVA代码。UnityTestActivity是主Activity,Unity程序一起动就会调用这个Activity,它是在AndroidManifest.xml中配置的。培野厅它需要继承UnityPlayerActivity,然而它就是配隐刚刚我们引入的classes.jar包中提供的接口类。UnityTestActivity对外提供脊兄了两个方法接口,StartActivity0(String name) 方法与StartActivity1(String name)方法,这两个方法是在Unity中使用C#脚本调用的,意思是调用后程序将打开一个新的Activity,参数name也是由C#脚本传递过来的,接着将传递的String参数继续传递给新打开的Activity。接下来就是设置xml文件和布局文件了。对于会android编程的同学就很熟悉了。把写好的java代码发布成jar包。接下来就创建unity工程,Unity工程中文件夹的结构如下,Plugins->Android的名称不能修改,必需保持一致。接着把Eclipse中Android的工程文件拷贝至这里,除了Android工程中的src文件夹,将其它文件夹全部拷贝至Plugins->Android文件夹中。最后在Plugins->Android文件夹中创建bin文件夹,然后将刚刚生成的.jar文件拷贝进来,jar的名称可以随便修改,但是jar包里面必须是com->xys->你的class文件,否则运行程序后提示找不到类文件。接下来就是如何在C#中调用android的方法的代码了。加入如下代码。 AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer") AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity") jo.Call("StartActivity0","第一个Activity")先得到AndroidJavaClass,然后得到AndroidjavaObject就是当前Activity的对象,也就是我们在上面创建的主UnityTestActivity.JAVA。拿到它的对象后调用jo.Call()参数1表示调用UnityTestActivity.JAVA类中的方法名称,参数2表示该方法传递过去的参数。如下图所示:“第一个Activity”与“第二个Activit”就是我在C#中传递过去的字符串。7发布成android平台apk


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12477663.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存