Android与Unity交互研究
转载请注明出处: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中进行二次开发,所以须要到处androidproject。
在导出的时候,能够选择导出”Google Android Project”。
如上图,假设不勾选此选项,则导出的是一个apk文件。
在导出androidproject或apk之前,须要在”Player Settings”进行一些配置:
这些配置与我们在eclipse等工具进行开发设置的基本一致。
导出androidproject之后。看到文件夹结构例如以下:
- assets文件以下是unity的一些资源文件,包括场景和渲染的文件。
- libs以下当然就是jar包和so文件了。
- src以下包括三个java类。
建议使用UnityPlayerActivity.java
打开UnityPlayerActivity之后,会发现里面有一个对象时UnityPlayer的实例,我们做android中嵌套U3D场景的时候,就是把这个实例当成一个view加入到我们的布局中。
导出androidproject之后。会出现两种情况:
- 你已经有androidproject了。此时仅仅须要把assets的文件和libs的包复制到你的项目中去,在把须要配置的类在AndroidManifest.xml中配置一下。
- 没有project,那么仅仅须要把unity导出的project导入你的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赋值。
点击放大后缩小button分别调用Unity中的ZoomIn()和ZoomOut()方法,控制怪兽变大变小。
OK,至此unity与android的简单交互叙述完成。
此篇blog到此结束~~
感谢大家支持!如有错误,请指出~~
谢谢~
来源:https://www.cnblogs.com/cynchanpin/p/7250741.html