转载请注明出处: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. 转:PHP环境搭建 - Linux

    本文PHP环境采用,nginx + PHP7 + mysql 5.6 一.安装mysql 5.6 参见:http://www.cnblogs.com/rslai/p/7853465.html 二.Ng ...

  2. java基础9 main函数、this、static、super、final、instanceof 关键字

    一.main函数详解 1.public:公共的.权限是最大的,在任何情况都可以访问  原因:为了保证jvm在任何情况下都可以访问到main法2.static:静态,静态可以让jvm调用更方便,不需要用 ...

  3. LeetCode解题报告—— Best Time to Buy and Sell Stock

    Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...

  4. 原生js粘贴复制【源码】

    <html> <head> <meta charset="UTF-8"> <title>9行代码实现复制内容至剪切板</tit ...

  5. bzoj 1853 容斥 + 搜索

    思路:先把所有幸运数字找出来, 把没有用的去掉,然后爆搜容斥,因为最多只会搜十几个就超过限制了, 所以是可行的. #include<bits/stdc++.h> #define LL lo ...

  6. json调试

    private static void mockapi(OkHttpClient.Builder httpClientBuilder) { if (Config.isMockApi) { MockAp ...

  7. 如何安装及使用PuTTY

    http://www.ytyzx.net/index.php?title=%E5%A6%82%E4%BD%95%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8 ...

  8. 洛谷——P4017 最大食物链计数

    P4017 最大食物链计数 题目背景 你知道食物链吗?Delia生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条.于是她来就来求助你,然而你也不会啊!写一个程序来帮帮她吧 ...

  9. HDU 6199gems gems gems (DP)

    gems gems gems Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  10. snort安装--daq,dnet---ERROR! dnet header not found, go get it from...等错误解决方案

    snort源码安装过程中,需要安装daq,dnet.这里想说下如何进行安装.daq简单,源码下载直接安装就可以.dnet在安装过程中,出错后总想着在网上搜一搜,结果很失望..本篇记录的不仅仅是解决安装 ...