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

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到此结束~~ 
感谢大家支持!如有错误,请指出~~ 
谢谢~

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

  1. Android 与Unity交互之Toast消息

    Toast.makeText(MainActivity.this,message.obj.toString(),Toast.LENGTH_SHORT).show();这一句代码不能直接放在 publi ...

  2. Unity 3D与Android Studio安卓交互之-导出jar包

    u3d与安卓 jar 包交互 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享 ...

  3. Unity与Android之间的交互之AndroidManifest

    https://blog.csdn.net/qq_15003505/article/details/70231975 AndroidManifest,中文名一般称之为清单文件.它描述了应用程序的组件的 ...

  4. Unity与Android的相互交互

    1.Unity调用Android. Unity块代码: using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.play ...

  5. 转:Android推送技术研究

    Android推送技术研究 字数5208 阅读4026 评论5 喜欢35 前言 最近研究Android推送的实现, 研究了两天一夜, 有了一点收获, 写下来既为了分享, 也为了吐槽. 需要说明的是有些 ...

  6. Android与H5交互(java与js的交互)

    一.理论概述 1.js调用java方法 直接调用WebView的该方法就可以添加接口了,不过先要启动交互 // 启用javascript mWebView.getSettings().setJavaS ...

  7. 关于android内存泄漏的研究

    博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基本也快结束了,有点时间来写写博客.好了 ...

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

    用struts2作为服务器框架,与android客户端进行交互需要得到request.response对象. struts2中获取request.response有两种方法. 第一种:利用Servle ...

  9. 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研究之自定义ViewG ...

随机推荐

  1. Codeforces 821C Okabe and Boxes(模拟)

    题目大意:给你编号为1-n的箱子,放的顺序不定,有n条add指令将箱子放入栈中,有n条remove指令将箱子移除栈,移出去的顺序是从1-n的,至少需要对箱子重新排序几次. 解题思路:可以通过把栈清空表 ...

  2. django 解决csrf跨域问题

    1.中间件代码 [root@linux-node01 mysite]# tree middlewares middlewares ├── base.py ├── base.pyc ├── cors.p ...

  3. normalize.css阅读笔记

    最近在被各种浏览器的CSS兼容折磨,所以看了看normalize的源代码来了解一些常见的浏览器间不一致的CSS渲染问题…… 源代码在这里 text-size-adjust 用法参见Apple的文档和M ...

  4. [Matlab]Upper Triangularization & Back Substitution代码

    用来做数值计算作业的代码,来自Numerical Methods Using Matlab (4th Edition) [John H. Mathews, Kurtis K. Fink],改了一下注释 ...

  5. mp4文件数据格式解析

    unsigned int(32)[3]    32*3bit string[32]  32*8bit class VisualSampleEntry(codingname) extends Sampl ...

  6. 【C#】数据类型(sbyte,byte,short,ushort,int,uint,long,ulong和char。、、、)

    C#的数据类型可以分为3类:数值类型,引用类型,指针类型.指针类型仅在不安全代码中使用. 值类型包括简单类型(如字符型,浮点型和整数型等),集合类型和结构型.引用类型包括类类型,接口类型,代表类型和数 ...

  7. Laravel 之父:让 Laravel、Symfony、 Zend 来一场公平的性能测试

    网上充斥着各式各样的 PHP 框架性能对比的文章.然而,他们总是把“苹果”和“橘子”做对比(看上去有点儿像,都是圆的,但其实不是一码事).这次,我将着重对 Laravel.Symfony 和 Zend ...

  8. Python并发编程-一个简单的多进程实例

    import time from multiprocessing import Process import os def func(args,args2): #传递参数到进程 print(args, ...

  9. django celery(QQ蓝鲸)

    官方:http://www.celeryproject.org 文档:http://docs.jinkan.org/docs/celery/index.html FAQ:http://docs.cel ...

  10. 【BZOJ 2440】 2440: [中山市选2011]完全平方数 (二分+容斥原理+莫比乌斯函数)

    2440: [中山市选2011]完全平方数 Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数 ...