Unity与Android交互(双端通信)

前言

最近小编开始做关于手部康复的项目,需要Android集成Unity,以Android为主,Unity为辅的开发;上一篇给大家分享了Unity嵌入Android的操作过程,所以今天想给大家分享一下双端通信的知识;

一. Android与Unity哪个为主?

一般情况下,根据需求来决定Android与Unity的轻重,可以总结为以下两种

1.  将Unity作为Android程序中的一部分进行开发 ,将Unity3D场景当成一个界面或者说是界面的一部分

2.  将Android作为Unity程序中的一部分进行开发,将Android当作一个插件

小编这里由于项目需要,我是以Android为主,Unity辅助

二. Unity端调用Android端方法

实例化AndroidJavaClass对象,用于拿到Android的UnityClass和Activity要用到的接口

实例化AndroidJavaObject对象,是Unity发送消息给Android的关键

//获取Android中com.unity3d.player.UnityPlayer,这个类在Unity3d导出工程的unity-class.jar中
//这是通过反射的机制
AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//获取Android当前正在运行的Activity
AndroidJavaObject androidJavaObject = androidJavaClass.GetStatic<AndroidJavaObject>("currentActivity");//调用Activity中的无返回值普通方法
androidJavaObject.Call("Android方法名");//调用Activity中的无返回值普通带参方法
androidJavaObject.Call("Android方法名","参数");//调用Activity中返回值String类的普通方法
androidJavaObject.Call<string>("Android方法名");//调用Activity中返回值String类的普通带参方法
androidJavaObject.Call<string>("Android方法名","参数");//调用Activity中返回值int类的普通方法
androidJavaObject.Call<int>("Android方法名");//调用Activity中返回值int类的普通带参方法
androidJavaObject.Call<int>("Android方法名","参数");//调用Activity中的无返回值静态方法
androidJavaObject.GetStatic("Android方法名");//调用Activity中的无返回值静态带参方法
androidJavaObject.GetStatic("Android方法名","参数");//调用Activity中返回值String类的静态方法
androidJavaObject.GetStatic<string>("Android方法名");//调用Activity中返回值String类的静态带参方法
androidJavaObject.GetStatic<string>("Android方法名","参数");//调用Activity中返回值int类的静态方法
androidJavaObject.GetStatic<int>("Android方法名");//调用Activity中返回值int类的静态带参方法
androidJavaObject.GetStatic<int>("Android方法名","参数");

这里列举了一些Unity调用Android的一些初级方法,记住,这种方式的调用最多只能传递一个参数,下一篇将为大家分享高级用法

三. Android端调用Unity端方法 

UnityPlayer.UnitySendMessage("Unity场景物体名","Unity脚本函数名","Unity脚本函数所需参数名");

UnityPlayer为Unity导出包,可以直接引用
UnitySendMessage()方法必须要传递三个参数
第一个参数为Unity场景中脚本挂载的游戏物体名

第二个参数为Unity脚本中的函数名
第三个参数为Unity脚本中函数所需要的参数,可以为空,但必须要有

这里只列举了双端通信的函数调用,可以满足Android与Unity之间参数不多的情况,如果需要大量参数传递的话要采用实现接口的方式在进行,双端通信接口之间的实现下一篇给大家分享

四. 双端通信实战演练

我给大家演示一个Android端控制Unity场景物体移动,并且Unity反过来控制Android端的一个Demo,希望大家能快速喜欢上Unity与Android的乐趣

1. Unity端

我在Unity的场景中创建一个Cube物体,在物体上挂载Move脚本,然后在场景中新建Canvas,Canvas下四个Button按钮,如下图所示

 Move脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Move : MonoBehaviour
{public Button btn_up;public Button btn_down;public Button btn_left;public Button btn_right;private AndroidJavaClass androidJavaClass;private AndroidJavaObject androidJavaObject;private void Start(){androidJavaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");androidJavaObject = androidJavaClass.GetStatic<AndroidJavaObject>("currentActivity");btn_up.onClick.AddListener(AndroidUp);btn_down.onClick.AddListener(AndroidDown);btn_left.onClick.AddListener(AndroidLeft);btn_right.onClick.AddListener(AndroidRight);}public void Up(){transform.Translate(0, 0.5f, 0);Debug.Log("Android端调用了Unity场景Cube物体上的Move脚本中的Up方法");}public void Down(){transform.Translate(0, -0.5f, 0);Debug.Log("Android端调用了Unity场景Cube物体上的Move脚本中的Down方法");}public void Left(){transform.Translate(-0.5f, 0, 0);Debug.Log("Android端调用了Unity场景Cube物体上的Move脚本中的Left方法");}public void Right(){transform.Translate(0.5f, 0 , 0);Debug.Log("Android端调用了Unity场景Cube物体上的Move脚本中的Right方法");}public void AndroidUp(){androidJavaObject.Call("Up");Debug.Log("Unity端调用了Android端的Up方法");}public void AndroidDown(){androidJavaObject.Call("Down");Debug.Log("Unity端调用了Android端的Down方法");}public void AndroidLeft(){androidJavaObject.Call("Left");Debug.Log("Unity端调用了Android端的Left方法");}public void AndroidRight(){androidJavaObject.Call("Right");Debug.Log("Unity端调用了Android端的Right方法");}}

2. Android端

AndroidStudio新建空项目,按照我上一篇集成Unity的文章来操作,然后新建一个类,让这个类继承UntyPlayerActivity,具体步骤如下

MainActivity.java:

package com.example.test;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {private Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(MainActivity.this, AndroidToUnityActivity.class);startActivity(intent);}});}
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="进入Unity"android:textAllCaps="false"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

AndroidToUnityActivity.java:

package com.example.test;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;import com.unity3d.player.UnityPlayer;public class AndroidToUnityActivity extends UnityPlayerActivity{/*** 声明变量*/private RelativeLayout Unity_View;private Button up_btn,left_btn,right_btn,down_btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_androidtounity);/*** 为变量绑定控件*/Unity_View = (RelativeLayout) findViewById(R.id.UnityView);up_btn = (Button) findViewById(R.id.btn1);left_btn = (Button) findViewById(R.id.btn2);right_btn = (Button) findViewById(R.id.btn3);down_btn = (Button) findViewById(R.id.btn4);/*** 将Unity视图添加到RelativeLayout中*/Unity_View.addView(mUnityPlayer);up_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {UnityPlayer.UnitySendMessage("Cube","Up","");}});left_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {UnityPlayer.UnitySendMessage("Cube","Left","");}});right_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {UnityPlayer.UnitySendMessage("Cube","Right","");}});down_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {UnityPlayer.UnitySendMessage("Cube","Down","");}});}private void Up(){UnityPlayer.UnitySendMessage("Cube","Up","");}private void Down(){UnityPlayer.UnitySendMessage("Cube","Down","");}private void Left(){UnityPlayer.UnitySendMessage("Cube","Left","");}private void Right(){UnityPlayer.UnitySendMessage("Cube","Right","");}
}

activity_androidtounity.xml:

<?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:orientation="vertical"><RelativeLayoutandroid:id="@+id/UnityView"android:layout_width="match_parent"android:layout_height="600dp"></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"><Buttonandroid:id="@+id/btn1"android:text="上移"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:orientation="horizontal"><Buttonandroid:id="@+id/btn2"android:text="左移"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginHorizontal="20dp"/><Buttonandroid:id="@+id/btn3"android:text="右移"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginHorizontal="20dp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"><Buttonandroid:id="@+id/btn4"android:text="上移"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout></LinearLayout>

到此为止,以上就是我的全部源码,大家可以参考一下,要是有问题,我们可以评论区讨论一下

3. 演示效果

Android与Unity双端通信

如果有致力于Android+Unity的小伙伴私信联系我,我们一起交流平时项目中的疑问,一起拓展这片领域

要是有疑问大家可以加我微信详聊 yf1553653788

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/297161.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql原理--连接查询的成本

1.准备工作 连接查询至少是要有两个表的&#xff0c;只有一个 single_table 表是不够的&#xff0c;所以为了故事的顺利发展&#xff0c;我们直接构造一个和 single_table 表一模一样的 single_table2 表。为了简便起见&#xff0c;我们把 single_table 表称为 s1 表&#xff0…

【动态规划】斐波那契数列模型

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 前言 算法原理 1.状态表示 是什么&#xff1f;dp表(一维数组…

[deepspeed]deepspeed安装和测试代码

deepspeed官方对linux系统支持非常好&#xff0c;安装流程较为简单&#xff0c;推荐使用linux系统使用deepspeed.deepspeed由于要使用大模型进行训练和推理&#xff0c;建议显存>24GB。windows上官方不直接支持&#xff0c;但是网上有安装whl文件&#xff0c;只能0.8.3这样老…

Go自定义PriorityQueue优先队列使用Heap堆

题目 分析 每次找最大的&#xff0c;pop出来 然后折半&#xff0c;再丢进去 go写法 go如果想用heap&#xff0c;要实现less\len\swap\push\pop 但可以偷懒&#xff0c;用sort.IntSlice,已经实现了less\len\swap 但由于目前是大根堆&#xff0c;要重写一下less 因此&#xff…

CFA II 考试公式大全 (WILEY’S CFA PROGRAM LEVEL II)

WILEY’S CFA PROGRAM LEVEL II quicksheet, quantitative 和 economics部分 网址&#xff1a;http://deepnlp.org/blog/cfa-ii-quantitative-economics 公式目录: 1.QUANTITATIVE METHODS 1.1 LINEAR REGRESSION-Standard Error of the Estimate LINEAR REGRESSION-Predict…

unity脚本API中OnCollisionEnter()、OnTriggerEnter()二者的区别

Unity中的OnCollisionEnter和OnTriggerEnter两个函数在日常的开发中很常见但也容易混淆&#xff0c;下面说一说两者的区别。 碰撞器&#xff08;Collider&#xff09;与触发器&#xff08;Trigger&#xff09;的概念 碰撞器&#xff08;Collider&#xff09;和触发器&#xff…

进行鸿蒙开发前的一些工具了解

文章概叙 文章主要讲的是开发的一些工具&#xff0c;如DevEco Studio,以及ArkTs的一些基础。 为啥要学习鸿蒙开发 抛开各种遥遥领先不讲&#xff0c;现在打开BOSS直聘&#xff0c;已经可以看到在BOSS上有不少的岗位是关于鸿蒙的&#xff0c;甚至是华为的岗位&#xff0c;而在…

simulink代码生成(二)——ADC采样模块

这一节梳理如何使用C2000库中的ADC模块&#xff0c;从而实现采样&#xff1b; 先预留几个问题&#xff0c;逐步进行解决。 &#xff08;1&#xff09;在simulink中C2000的ADC采样模块设置是怎么样的&#xff1f;各个选项卡代表什么&#xff1f; &#xff08;2&#xff09;AD…

相机内参标定理论篇------张正友标定法

一、为什么做相机标定&#xff1f; 标定是为了得到相机坐标系下的点和图像像素点的映射关系&#xff0c;为摄影几何、计算机视觉等应用做准备。 二、为什么需要张正友标定法&#xff1f; 张正友标定法使手工标定相机成为可能&#xff0c;使相机标定不再需要精密的设备帮助。…

婚庆婚礼策划服务网站建设的效果如何

品牌效应越来越重要&#xff0c;婚庆行业在多年的发展下&#xff0c;部分区域内也跑出了头部品牌&#xff0c;连锁门店也开了很多家&#xff0c;无论新品牌还是老品牌在新的区域开店总归少不了线上线下的宣传&#xff0c;虽然几乎每个人都会接触婚庆服务&#xff0c;但因为市场…

编译原理--词法分析C++

一、实验项目要求 1.实验目的 通过设计编制调试一个具体的词法分析程序&#xff0c;加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程&#xff0c;从输入的源程序中&#xff0c;识别出各个具有…

华为交换机Telnet原理与配置

Telnet远程连接到每一台设备上&#xff0c;对这些网络设备进行集中的管理和维护。 Telnet应用场景 Telnet可以通过终端对本地和远程的网络设备进行集中管理。Telnet提供了一个交互式操作界面&#xff0c;允许终端远程登录到任何可以充当Telnet服务器的设备。Telnet用户可以像通…