Unity与Android交互(双端通信)

news2024/11/18 11:36:17

前言

最近小编开始做关于手部康复的项目,需要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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public 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">

    <Button
        android: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;

    @Override
    protected 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() {
            @Override
            public void onClick(View view) {
                UnityPlayer.UnitySendMessage("Cube","Up","");
            }
        });
        left_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                UnityPlayer.UnitySendMessage("Cube","Left","");
            }
        });
        right_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                UnityPlayer.UnitySendMessage("Cube","Right","");
            }
        });
        down_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public 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">

    <RelativeLayout
        android:id="@+id/UnityView"
        android:layout_width="match_parent"
        android:layout_height="600dp">

    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">
        <Button
            android:id="@+id/btn1"
            android:text="上移"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn2"
            android:text="左移"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"/>


        <Button
            android:id="@+id/btn3"
            android:text="右移"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">
        <Button
            android:id="@+id/btn4"
            android:text="上移"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

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

3. 演示效果

Android与Unity双端通信

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装OpenResty

安装OpenResty 1.安装 首先你的Linux虚拟机必须联网 1&#xff09;安装开发库 首先要安装OpenResty的依赖开发库&#xff0c;执行命令&#xff1a; yum install -y pcre-devel openssl-devel gcc --skip-broken2&#xff09;安装OpenResty仓库 你可以在你的 CentOS 系统中…

物联网平台+业务平台基本架构设计与优化想法

前言 目前的交付底座有点老&#xff0c;而且集成的有点杂&#xff0c;计划是要升级下&#xff0c;先说想法&#xff0c;看领导做不做。 1 业务平台定位 我们的愿景&#xff1a;通过物联平台赋能&#xff0c;让数据产生价值。 为客户提供可视化的平台&#xff08;数据价值…

【王道数据结构】第二章 | 线性表

目录 2.1线性表的定义 2.2线性表的基础操作 2.3顺序表的定义 2.4顺序表的基本操作 2.5 线性表的链式表示 2.1线性表的定义 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列&#xff0c;其中n为表长&#xff0c;当n0时线性表是一个空表。若用L命名线性表&#xf…

Block底层原理读书笔记-《高级编程- iOS与OS多线程和内存管理》(更新中)

1 一个Block 真正的底层都有些什么&#xff1f; Block会被解析成一个结构体&#xff08;这里成为Block结构体&#xff09;&#xff0c;这个结构体里有&#xff1a; &#xff08;1&#xff09;isa指针&#xff08;说明Block的本质是一个对象&#xff09;&#xff1a;指向Stack…

动态修改Azure DevOps区域路径或迭代路径的继承权限(Inhertiance)

Contents1. 场景描述2. 解决方案2.1 更改继承的接口&#xff1a;ChangeInhertiance2.2 获取区域路径的接口&#xff1a;ClassificationNodes1. 场景描述客户使用工作项模板&#xff0c;定制了一个设计变更流程&#xff0c;需要在不同的阶段(流程状态)控制工作项的更改权限。我们…

Grafana 系列文章(六):Grafana Explore 中的日志

&#x1f449;️URL: https://grafana.com/docs/grafana/latest/explore/logs-integration/#labels-and-detected-fields &#x1f4dd;Description: Explore 中的日志 除了指标之外&#xff0c;Explore 还允许你在以下数据源中调查你的日志。 ElasticsearchInfluxDBLoki 在基…

[算法设计与分析考点4] 改进的串匹配算法——KMP算法

算法核心思想 在BF算法的基础上加以改进&#xff0c;BF算法中每次当前字符不相等时&#xff0c;主串S要回溯到其下一个字符处&#xff0c;模式串T要回溯到 j0 位置进行下一趟的匹配。然而&#xff0c;大多数情况下&#xff0c;这种回溯是没有必要的&#xff0c;非常耗时且效率低…

qt入门介绍

1.Qt 是一个跨平台的 C开发库。主要用来开发图形用户界面&#xff08;GUI&#xff09;程序。Qt 虽然经常被当做一个 GUI 库&#xff0c;用来开发图形界面应用程序&#xff0c;但这并不是 Qt 的全部&#xff1b;Qt 除了可以绘制漂亮的界面&#xff08;包括控件、布局、交互&…

【css】前端拉下代码后,node-sass sass-loader 与node版本不符怎么办

因为每次node和sass版本匹配都容易出现问题&#xff0c; 所以如果我自己开发&#xff0c;我不使用sass或者less&#xff0c;只用原生css 但如果是拉下来的项目&#xff0c;别人已经成功使用&#xff0c;webview版本 和 sass已经匹配&#xff0c;只需考虑 node版本匹配。 根据…

Hive分析函数系列文章

Hive分析窗口函数(一) SUM,AVG,MIN,MAXhttps://blog.csdn.net/weishuai90/article/details/128843715 Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANKhttps://blog.csdn.net/weishuai90/article/details/128858824 Hive分析窗口函数(三) CUME_DIST,PERCENT_RANKhttp…

Object类有什么作用?怎样使用Object类?

在Java中提供了一个Object类&#xff0c;它是所有类的父类&#xff0c;即每个类都直接或间接继承自该类&#xff0c;因此&#xff0c;Object类通常被称之为超类、基类或根类。当定义一个类时&#xff0c;如果没有使用extends关键字为这个类显示地指定父类&#xff0c;那么该类会…

【微积分易错点总结】函数、极限和连续

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大的激励…

DSPE-PEG-DOTA,磷脂聚乙二醇大环配体 二硬脂酰基磷脂酰乙醇胺- 聚乙二醇-四氮杂环配体

中文名称&#xff1a;二硬脂酰基磷脂酰乙醇胺- 聚乙二醇-四氮杂环配体 英文名称&#xff1a;DSPE-PEG-DOTA 别称&#xff1a;1,2-distearoyl-sn-glycero-3-phosphoethanolamine-poly(ethylene glycol)-DOTA PEG分子量&#xff1a;1000、2000、3400、5000等等 用 途&#xf…

《流浪地球2》的现实倒影(一):从量子计算机到MOSS

编者按&#xff1a;跟大家一样&#xff0c;《流浪地球2》的上映让我们感到无比兴奋。作为科技领域的内容创作者&#xff0c;在《流浪地球2》中不仅看到了中国科幻电影与电影工业的崛起&#xff0c;更看到了大量现实中真实存在的科技脉络。由于这部电影在科技方面的基本功非常扎…

RK3568平台开发系列讲解(驱动基础篇)自旋锁详解

🚀返回专栏总目录 文章目录 一、什么是spinlock 自旋锁二、什么是raw_spinlock原始自旋锁三、自旋锁的使用3.1、spinlock 自旋锁相关API3.2、raw_spinlock原始自旋锁相关API沉淀、分享、成长,让自己和他人都能有所收获!😄 📢自旋锁用于处理器之间的互斥,适合保护很短的…

Python枚举类定义和使用

一些具有特殊含义的类&#xff0c;其实例化对象的个数往往是固定的&#xff0c;比如用一个类表示月份&#xff0c;则该类的实例对象最多有 12 个&#xff1b;再比如用一个类表示季节&#xff0c;则该类的实例化对象最多有 4 个。针对这种特殊的类&#xff0c;Python 3.4 中新增…

@WebServlet注解的解释和使用

大家好&#xff0c;今天分享一下WebServlet注解 首先&#xff0c;我们要知道&#xff0c;我们要写一个servlet程序,web,xml里的配置项很重要,里面包含了很多关于类绑定&#xff0c;以及服务器资源的请求路径问题&#xff08;就是注册&#xff09; 先把我这个看一遍&#xff0c…

【蓝桥杯】历届真题 完全二叉树的权值(省赛)Java

【资源限制】 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 【问题描述】 给定一棵包含N个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依…

SpringBoot将项目打包成JAR包或者WAR包

SpringBoot将项目打包成JAR包或者WAR包前言打包成JAR包打包成WAR包打包遇到的问题Maven环境问题跳过测试并打包前言 本文开发工具使用IDEA&#xff0c;已配置好Maven环境&#xff0c;如果未配置的可以参考另外一篇文章: Maven如何配置阿里镜像及安装全步骤 打包成JAR包 默认…

【C++】继承——切片、隐藏、默认成员函数、菱形

文章目录一、继承概念及定义二、赋值转换——切片三、继承的作用域——隐藏四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、菱形继承及菱形虚拟继承八、继承与组合九、结语一、继承概念及定义 概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最…