Android与Unity交互研究

转载请注明出处:http://blog.csdn.net/crazy1235/article/details/46733221

  • Android与Unity交互研究
    • unity与android交互的由来
    • unity简单介绍
    • unity与android交互介绍
      • unity调用android的方法
      • android调用untiy的方法

unity与android交互的由来

本人在项目开发过程中,遇到这样一个需求,把unity的场景放到android中去显示。刚开始做的时候也是一头雾水,unity是什么东西都没听说过。后来也是查询很多资料,才实现了需求的效果。所以把自己的一些总结记录于此,方便各位同行参考。

unity简单介绍

unity是可以开发诸如三维视频游戏、建筑模型、三维动画等交互类内容的多平台综合游戏开发工具,具有很强大的跨平台性。在unity之中编写好场景和程序之后,可以导出Android、ios、windows phone、PC等多个平台的版本。

如上图,列出了unity可以导出的所有平台。

unity与android交互介绍

一般的都是,把unity作为android程序中的一部分,将一个u3d场景当成一个界面或者一个界面的一部分。
还有的是把android作为unity的一部分进行开发。不过这种形式的开发很少,也没必要。

我们下面以一个例子来介绍二者之间的交互。

首先,在unity中搞了一个游戏场景,运行之后如下图:

此场景中“1”是一个label,用来显示从android中设置的怪兽人物的名称。“2”用于在android程序中控制大小显示变化的。“3”是用与unity中测试大小变化的。

unity调用android的方法

我们需要在运行起来Unity引擎之后,调用java类中的方法获取怪兽的姓名,就需要Uniy调用Android的方法。
unity调用java方法一共有四种形式,分别是:

  • 没有返回值的普通方法
AndroidJavaObject jo = new AndroidJavaObject("android.content.res.Configuration");jo.Call("setToDefaults");
  • 带有返回值的普通方法
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some string");int hash = jo.Call<int>("hashCode");
  • 没有返回值的静态方法
AndroidJavaObject jo = new AndroidJavaObject("android.os.Binder");jo.CallStatic("flushPendingCommands");
  • 带有返回值的静态方法
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String");string valueString = jo.CallStatic<string>("valueOf", 42.0);

我们往游戏对象上绑定一些操作–Operate.cs :

using UnityEngine;using System.Collections;public class Operate : MonoBehaviour {public Transform target;public UILabel label;public bool flag = true;/// <summary>/// 定义旋转速度/// </summary>public float RotateSpeed=45;// Use this for in itializationvoid Start () { //Debug.Log("hello"); this.name = "Manager"; GetData ();}/// <summary>/// 通过调用android中的方法获取name,并为label赋值/// </summary>void GetData(){ AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");   string name = jo.Call <string>("getName", "成功调用android方法"); label.text = name;}// Update is called once per framevoid Update () { //target.Rotate (Vector3.up * Time.deltaTime * RotateSpeed);}void OnClick(){  Screen.orientation = ScreenOrientation.Landscape;  if (flag) {    target.localScale = new Vector3 (0.5f, 0.5f, 0.5f);    flag = false;    //label.text = "123456";   } else {       target.localScale = new Vector3 (0.75f, 0.75f, 0.75f);       flag = true;       //label.text = "000000";   } } /// <summary> /// 顶掉之前的scene /// </summary>void Unload(){    Application.LoadLevel (1);    AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");    AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");      jo.Call ("makePauseUnity"); }/// <summary>/// 放大/// </summary>void ZoomIn(){    target.localScale = new Vector3 (0.75f, 0.75f, 0.75f);}/// <summary>/// 缩小/// </summary>void ZoomOut(){    target.localScale = new Vector3 (0.5f, 0.5f, 0.5f);}}

代码和场景编写好之后,就可以使用unity到处apk文件运行了。不过我们需要在eclipse中进行二次开发,所以需要到处android工程。

在导出的时候,可以选择导出”Google Android Project”。

如上图,如果不勾选此选项,则导出的是一个apk文件。
在导出android工程或apk之前,需要在”Player Settings”进行一些配置:

这些配置与我们在eclipse等工具进行开发设置的基本一致。
导出android工程之后,看到目录结构如下:

  • assets文件下面是unity的一些资源文件,包括场景和渲染的文件。
  • libs下面当然就是jar包和so文件了。
  • src下面包含三个java类。建议使用UnityPlayerActivity.java

打开UnityPlayerActivity之后,会发现里面有一个对象时UnityPlayer的实例,我们做android中嵌套U3D场景的时候,就是把这个实例当成一个view添加到我们的布局中

导出android工程之后,会出现两种情况:

  • 你已经有android工程了,此时只需要把assets的文件和libs的包拷贝到你的项目中去,在把需要配置的类在AndroidManifest.xml中配置一下。
  • 没有工程,那么只需要把unity导出的工程导入你的IDE中即可。

看一下MainActivity的布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#E0EEE0" android:gravity="center_horizontal" android:orientation="vertical" >    <!-- 3D视图区域 -->    <LinearLayout  android:id="@+id/u3d_layout" android:layout_width="match_parent" android:layout_height="300dp" android:background="#a6a9af" android:orientation="vertical" >    </LinearLayout>    <!-- 放大 -->    <Button  android:id="@+id/zoom_in_btn" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:padding="10dp" android:text="放大" />    <!-- 缩小 -->    <Button  android:id="@+id/zoom_out_btn" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:padding="10dp" android:text="缩小" />    <!-- 全屏 -->    <Button  android:id="@+id/u3d_fullscreen_btn" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:padding="10dp" android:text="全屏" /></LinearLayout>

贴上逻辑代码之前,先介绍一下Android调用unity方法的方式:

android调用untiy的方法:

UnityPlayer.UnitySendMessage("Manager", "ZoomIn", "");

第一个参数是Game Object对象,所以需要在游戏对象上绑定脚本,第二个参数是unity中定义的方法名,第三个参数是定义方法的参数(可空)。

既可以在定义场景的时候将游戏对象改名字,也可以在代码中设置:

void Start () {  this.name = "Manager";  GetData (); }

在unity中运行之后,就会发现出现一个”Manager”的游戏场景了。

下面看一下activity的代码:

package com.jacksen.unity2android;import com.unity3d.player.UnityPlayer;import android.os.Bundle;import android.view.KeyEvent;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.LinearLayout;import android.widget.Toast;public class MainActivity extends UnityPlayerActivity { private LinearLayout u3dLayout; private Button zoomInBtn, zoomOutBtn; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  u3dLayout = (LinearLayout) findViewById(R.id.u3d_layout);  u3dLayout.addView(mUnityPlayer);  mUnityPlayer.requestFocus();  zoomInBtn = (Button) findViewById(R.id.zoom_in_btn);  zoomOutBtn = (Button) findViewById(R.id.zoom_out_btn);  zoomInBtn.setOnClickListener(new OnClickListener() {   @Override   public void onClick(View v) {    UnityPlayer.UnitySendMessage("Manager", "ZoomIn", "");   }  });  zoomOutBtn.setOnClickListener(new OnClickListener() {   @Override   public void onClick(View v) {    UnityPlayer.UnitySendMessage("Manager", "ZoomOut", "");   }  }); } public String getName(final String str) {  runOnUiThread(new Runnable() {   @Override   public void run() {    Toast.makeText(MainActivity.this, str, 1000).show();   }  });  return "我是怪兽,哈哈哈"; } /** * 3D调用此方法,用于退出3D */ public void makePauseUnity() {  runOnUiThread(new Runnable() {   @Override   public void run() {    if (mUnityPlayer != null) {     try {      mUnityPlayer.quit();     } catch (Exception e) {      e.printStackTrace();     }    }    MainActivity.this.finish();   }  }); } /** * 按键点击事件 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) {  if (keyCode == KeyEvent.KEYCODE_BACK) {   onDestroy();  }  return true; } @Override protected void onDestroy() {  super.onDestroy();  //UnityPlayer.UnitySendMessage("Manager", "Unload", "");   mUnityPlayer.quit(); } // Pause Unity @Override protected void onPause() {  super.onPause();  mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() {  super.onResume();  mUnityPlayer.resume(); } @Override public void onBackPressed() {  super.onBackPressed();  // mUnityPlayer.quit();  // this.finish(); }}

OK,运行效果如下:

跳转到MainActivity之后,unity场景启动,调用android中的getName()方法为怪兽头上的label赋值。
点击放大后缩小按钮分别调用Unity中的ZoomIn()和ZoomOut()方法,控制怪兽变大变小。

OK,至此unity与android的简单交互叙述完毕。

此篇blog到此结束~~
感谢大家支持!如有错误,请指出~~
谢谢~

更多相关文章

  1. Android中EditText的使用总结
  2. Android(安卓)教程例子列表
  3. android调用系统自带资源的两种方式
  4. C++调用Android(安卓)与Android调用C++ 例子
  5. C++调用Android(安卓)与Android调用C++ 例子
  6. 分享方法:android 获得屏幕状态
  7. android代码片段二
  8. Android(安卓)N画中画模式
  9. android button 点击事件

随机推荐

  1. Android之SQlite存储
  2. 对android tabactivity中ActionBar中setD
  3. eclipse导入的Android工程报错
  4. 自学第五十八天
  5. android 九宫格 移动 并且删除 带动画效
  6. Qt for Android升级
  7. android获取手机上的图片和视频缩略图thu
  8. Android下NV21转ARGB的方法
  9. Nginx系列教程(三)| 一文带你读懂Nginx的负
  10. Android SDK 下载-Android studio 2020