Android与Unity交互研究

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  itialization
void 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 frame
void 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到此结束~~

感谢大家支持!如有错误,请指出~~

谢谢~

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 13:16:59

Android与Unity交互研究的相关文章

Android 与Unity交互之Toast消息

Toast.makeText(MainActivity.this,message.obj.toString(),Toast.LENGTH_SHORT).show();这一句代码不能直接放在 public void ShowMessage(String msg){ Log.e("-------", msg); // And this is how you call it from the worker thread: Toast.makeText(MainActivity.this,me

android 与js交互

android与js交互 // 设置编码 webView.getSettings().setDefaultTextEncodingName("utf-8"); // 支持js webView.getSettings().setJavaScriptEnabled(true); //参数1为传递的android对象,参数2为传递对象的变量名称之后JS中使用变量名进行对对象的操作 webView.addJavascriptInterface(new TestJs(), "testO

struts2中获取request、response,与android客户端进行交互(文件传递给客户端)

用struts2作为服务器框架,与android客户端进行交互需要得到request.response对象. struts2中获取request.response有两种方法. 第一种:利用ServletActionContext的静态方法 Struts2 利用ServletActionContext类来维护Servlet对象,ServletActionContext利用ThreadLocal来维护 不同线程的Servlet对象,因此可以使用ServletActionContext类获取,这种方法

Android -- 与WEB交互在同一个会话Session中通信

Session与Cookie Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力. Session可以用Cookie来实现,也可以用URL回写的机制来实现. Cookie和Session有以下明显的不同点: 1)Cookie将状态保存在客户端,Session将状态保存在服务器端: 2)Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.网络服务器用HTTP头向客户端发送cookies,在客户

android 1.6 launcher研究之自定义ViewGroup (转 2011.06.03(二)——— android 1.6 launcher研究之自定义ViewGroup )

2011.06.03(2)——— android 1.6 launcher研究之自定义ViewGroup2011.06.03(2)——— android 1.6 launcher研究之自定义ViewGroup 1.用xml来作为ViewGroup里面的View参考:http://www.eoeandroid.com/thread-30888-1-1.html MyViewGroup.java package com.lp; import android.content.Context; impo

Android event logcat的研究

经常有这样的需求:在程序A启动之后,在这个程序上覆盖一个界面,让用户输入密码后才能启动程序A,这类场景主要集中在安全软件中. 那应该怎样得知某某程序启动了,系统没有相应的广播,这很难知道程序启动了. 既然没有通知,那我们就只能用最笨的方法:主动去询问最近启动过哪些程序. 这需要用后台服务器一直跑,每隔一段时间就询问一次.程序启动的时候,会在Logcat中打印出一些日志信息,其中就有类似下面的日志,表明是启动了哪个程序 01-21 15:09:56.957: I/ActivityManager(2

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

这两天刚刚接触Unity3d,之前一直是做android开发,对于Unity3d的开发有专门的人才,我主要涉及在Unity3d与android的交互,经过两天是实验终于完成了下面的效果: 本来想写几篇博客,来详细说明下Unity3d导出android Project然后再进行二次开发的过程,后来发现几篇博客,过程和我的类似,对于重复的过程我就不写了,大家参考他的博客就可以了.而且,包括了Unity3d调用android脚本,这一块我暂时还没有涉及. Unity3D游戏开发之Unity与Andro

浅谈混合开发与Android,JS数据交互

本文是作者原创,如转载请注明出处! 一.概论 现在时代已经走过了移动互联网的超级火爆阶段,市场上移动开发人员已经趋于饱和,显然,只会原生APP的开发已不能满足市场的需求,随着H5的兴起与火爆,H5在原生APP中的使用越来越广泛,也就是我们常说的混合开发(Hybrid APP).最新很火的微信小程序相信大家都是知道的,实际上微信小程序加载的界面就是一个HTML5的界面,HTML5界面在一些电商类的APP中主要承担展示数据的作用,但是他的作用并不仅限于此,最起码js调用原生方法和原生调用js的方法是

Android推送技术研究

前言 近期研究Android推送的实现, 研究了两天一夜, 有了一点收获, 写下来既为了分享, 也为了吐槽. 须要说明的是有些东西偏底层硬件和通信行业, 我对这些一窍不通, 仅仅能说说自己的理解. 为什么要研究Android推送技术? 主要还是毕业设计要做一个即时通信app, 我是不喜欢做什么社交app的, 也就象牙塔里的人想得出来, 说实话有这功夫还不如钻研一个小技术点, 把一个点研究透彻, 比搞个大而全, 还没用的东西好得多, 只是谁叫咱们是普通人, 没得选呢. Android推送服务的几种