当前位置:   article > 正文

unity与android交互 (Unity嵌入android)_uniapp桥接unity3d

uniapp桥接unity3d

转载请注明出处: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方法一共有四种形式,分别是:

  • 没有返回值的普通方法
  1. AndroidJavaObject jo = new AndroidJavaObject("android.content.res.Configuration");
  2. jo.Call("setToDefaults");

 

  • 带有返回值的普通方法
  1. AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some string");
  2. int hash = jo.Call<int>("hashCode");

 

  • 没有返回值的静态方法
  1. AndroidJavaObject jo = new AndroidJavaObject("android.os.Binder");
  2. jo.CallStatic("flushPendingCommands");

 

  • 带有返回值的静态方法
  1. AndroidJavaObject jo = new AndroidJavaObject("java.lang.String");
  2. string valueString = jo.CallStatic<string>("valueOf", 42.0);

 

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

  1. using UnityEngine;
  2. using System.Collections;
  3. public class Operate : MonoBehaviour {
  4. public Transform target;
  5. public UILabel label;
  6. public bool flag = true;
  7. /// <summary>
  8. /// 定义旋转速度
  9. /// </summary>
  10. public float RotateSpeed=45;
  11. // Use this for in itialization
  12. void Start () {
  13. //Debug.Log("hello");
  14. this.name = "Manager";
  15. GetData ();
  16. }
  17. /// <summary>
  18. /// 通过调用android中的方法获取name,并为label赋值
  19. /// </summary>
  20. void GetData(){
  21. AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
  22. AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
  23. string name = jo.Call <string>("getName", "成功调用android方法");
  24. label.text = name;
  25. }
  26. // Update is called once per frame
  27. void Update () {
  28. //target.Rotate (Vector3.up * Time.deltaTime * RotateSpeed);
  29. }
  30. void OnClick(){
  31. Screen.orientation = ScreenOrientation.Landscape;
  32. if (flag) {
  33. target.localScale = new Vector3 (0.5f, 0.5f, 0.5f);
  34. flag = false;
  35. //label.text = "123456";
  36. } else {
  37. target.localScale = new Vector3 (0.75f, 0.75f, 0.75f);
  38. flag = true;
  39. //label.text = "000000";
  40. }
  41. }
  42. /// <summary>
  43. /// 顶掉之前的scene
  44. /// </summary>
  45. void Unload(){
  46. Application.LoadLevel (1);
  47. AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
  48. AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
  49. jo.Call ("makePauseUnity");
  50. }
  51. /// <summary>
  52. /// 放大
  53. /// </summary>
  54. void ZoomIn(){
  55. target.localScale = new Vector3 (0.75f, 0.75f, 0.75f);
  56. }
  57. /// <summary>
  58. /// 缩小
  59. /// </summary>
  60. void ZoomOut(){
  61. target.localScale = new Vector3 (0.5f, 0.5f, 0.5f);
  62. }
  63. }

 


代码和场景编写好之后,就可以使用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的布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#E0EEE0"
  6. android:gravity="center_horizontal"
  7. android:orientation="vertical" >
  8. <!-- 3D视图区域 -->
  9. <LinearLayout
  10. android:id="@+id/u3d_layout"
  11. android:layout_width="match_parent"
  12. android:layout_height="300dp"
  13. android:background="#a6a9af"
  14. android:orientation="vertical" >
  15. </LinearLayout>
  16. <!-- 放大 -->
  17. <Button
  18. android:id="@+id/zoom_in_btn"
  19. android:layout_width="200dp"
  20. android:layout_height="wrap_content"
  21. android:layout_marginTop="20dp"
  22. android:padding="10dp"
  23. android:text="放大" />
  24. <!-- 缩小 -->
  25. <Button
  26. android:id="@+id/zoom_out_btn"
  27. android:layout_width="200dp"
  28. android:layout_height="wrap_content"
  29. android:layout_marginTop="20dp"
  30. android:padding="10dp"
  31. android:text="缩小" />
  32. <!-- 全屏 -->
  33. <Button
  34. android:id="@+id/u3d_fullscreen_btn"
  35. android:layout_width="200dp"
  36. android:layout_height="wrap_content"
  37. android:layout_marginTop="20dp"
  38. android:padding="10dp"
  39. android:text="全屏" />
  40. </LinearLayout>

 


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

android调用untiy的方法:

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

 

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

图片名称

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

  1. void Start () {
  2. this.name = "Manager";
  3. GetData ();
  4. }

 

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

这里写图片描述

下面看一下activity的代码:

  1. package com.jacksen.unity2android;
  2. import com.unity3d.player.UnityPlayer;
  3. import android.os.Bundle;
  4. import android.view.KeyEvent;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.LinearLayout;
  9. import android.widget.Toast;
  10. public class MainActivity extends UnityPlayerActivity {
  11. private LinearLayout u3dLayout;
  12. private Button zoomInBtn, zoomOutBtn;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. u3dLayout = (LinearLayout) findViewById(R.id.u3d_layout);
  18. u3dLayout.addView(mUnityPlayer);
  19. mUnityPlayer.requestFocus();
  20. zoomInBtn = (Button) findViewById(R.id.zoom_in_btn);
  21. zoomOutBtn = (Button) findViewById(R.id.zoom_out_btn);
  22. zoomInBtn.setOnClickListener(new OnClickListener() {
  23. @Override
  24. public void onClick(View v) {
  25. UnityPlayer.UnitySendMessage("Manager", "ZoomIn", "");
  26. }
  27. });
  28. zoomOutBtn.setOnClickListener(new OnClickListener() {
  29. @Override
  30. public void onClick(View v) {
  31. UnityPlayer.UnitySendMessage("Manager", "ZoomOut", "");
  32. }
  33. });
  34. }
  35. public String getName(final String str) {
  36. runOnUiThread(new Runnable() {
  37. @Override
  38. public void run() {
  39. Toast.makeText(MainActivity.this, str, 1000).show();
  40. }
  41. });
  42. return "我是怪兽,哈哈哈";
  43. }
  44. /**
  45. * 3D调用此方法,用于退出3D
  46. */
  47. public void makePauseUnity() {
  48. runOnUiThread(new Runnable() {
  49. @Override
  50. public void run() {
  51. if (mUnityPlayer != null) {
  52. try {
  53. mUnityPlayer.quit();
  54. } catch (Exception e) {
  55. e.printStackTrace();
  56. }
  57. }
  58. MainActivity.this.finish();
  59. }
  60. });
  61. }
  62. /**
  63. * 按键点击事件
  64. */
  65. @Override
  66. public boolean onKeyDown(int keyCode, KeyEvent event) {
  67. if (keyCode == KeyEvent.KEYCODE_BACK) {
  68. onDestroy();
  69. }
  70. return true;
  71. }
  72. @Override
  73. protected void onDestroy() {
  74. super.onDestroy();
  75. //UnityPlayer.UnitySendMessage("Manager", "Unload", "");
  76. mUnityPlayer.quit();
  77. }
  78. // Pause Unity
  79. @Override
  80. protected void onPause() {
  81. super.onPause();
  82. mUnityPlayer.pause();
  83. }
  84. // Resume Unity
  85. @Override
  86. protected void onResume() {
  87. super.onResume();
  88. mUnityPlayer.resume();
  89. }
  90. @Override
  91. public void onBackPressed() {
  92. super.onBackPressed();
  93. // mUnityPlayer.quit();
  94. // this.finish();
  95. }
  96. }

 


OK,运行效果如下:

图片名称

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/96181
推荐阅读
相关标签
  

闽ICP备14008679号