【Unity3D学习记录#2】Android调用Unity界面 与 信息交互

【Unity3D学习记录#2】Android调用Unity界面 与 信息交互

Android 调用 Unity

之前一直在Unity平台上进行开发,被Unity的界面设计困扰,于是想将文字、图片的主要功能放到Android平台上,中间踩过很多的坑,现在将我的步骤总结,希望对后面进行类似工作的朋友有所帮助。本文仅进行最基本的功能测试,用例极为简单,如有其它功能需求,还请自行添加。因为没有经过系统Android学习,使用的术语不准确,如对理解产生障碍,还请见谅。

Unity项目构建

本文使用的Unity3D版本:2019.3.0f6

具体步骤:
1、构建新的3D项目
首先,项目发布平台选择Android,这一步的目的是为了对Game视图进行修改,方便界面的设计与实现(本文选择的视图选项为:1920 x 1080 Portrait(1080 x 1920))。这一步的前提是你已经配置好JDK、SDK的配置,配置的过程在论坛中有很多教程,这里推荐直接使用Unity Hub对Unity3D配置、版本进行管理,能够大大降低出错的可能性。(Unity与Android尽量使用同样的JDK和SDK,否则容易出错)
在这里插入图片描述

在场景中建立如下物体:
(1)Text:用来显示接收到的信息
建立Text后会自动建立一个Canvas,需要对其参数进行修改
在这里插入图片描述

(2)Button:触发测试代码
(3)Cube:早先留做测试,现已弃用,如不需要操作场景和脚本中可以忽略
建立好的界面大致如下图所示:
在这里插入图片描述

2、编写并挂载脚本 Test.cs

using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public Text mtext;
    //一个旋转物体(弃用)
    public GameObject cube;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home) )
  		{
            Application.Quit();
        }
    }

    public void OnClick()
    {
        print("OnClick执行");
        /* com.njucm.unity2android : Android工程定义的包名
         * UnityActivity :java方法(函数)所在的类 */
        using (AndroidJavaClass jc = new AndroidJavaClass("com.njucm.android2unity.UnityActivity"))
        {
            print("Android包寻找成功");
            //jc.CallStatic("sendmessage");
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("m_instance"))
            {
                print("调用m_instance,尝试调用对象下的非静态函数");
                if (jo != null)
                {
                    jo.Call("sendmessage");
                }
                else
                {
                    print("m_instance获取失败");
                }
            }
        }
        
        //m_instance : UnityPlayerActivity类中自己声明 
    }

    public void settextView(string str)
    {
        print("收到了Android信息,str:" + str);
        mtext.text = str;
    }
}


这一部分代码的主要功能为:
①通过AndroidJavaClass,利用Android项目中的包名、类名,获取java中的类。

AndroidJavaClass jc = new AndroidJavaClass(“com.njucm.android2unity.UnityActivity”)

②通过AndroidJavaObject,获取类UnityActivity内的静态数据成员作为对象(Android正在运行的界面)

AndroidJavaObject jo = jc.GetStatic(“m_instance”)

③通过AndroidJavaObject.Call(“函数名”),调用java中的函数(可以加入参数值,但是本文的Android项目内方法没有设置参数,具体使用方法可以到论坛上搜索其他的文章)

jo.Call(“sendmessage”);

脚本需要挂载在Main Camera、Button上,请不要忘记将脚本中的参数实例化(绑定脚本后,拖动场景中的物体进行赋值)。
Button点击事件需要绑定OnClick()函数。
在这里插入图片描述
3、项目的导出
依次(->) 点击/执行操作
-> File
-> Build Settings
-> 在Scenes in Build中添加创建的场景
-> Player Settings
-> 修改Company Name、Product Name(本文中分别为njucm、android2unity)
-> Other Settings
-> Package Name,对照内容是否为“com.{Company Name}.{Product Name}”。({ }表示必填,[ ]表示选填)
-> 设置Minimun API Level (本文选择的版本为API Level 19)
-> Player Settings页面设置完毕,回到Build Settings
-> 勾选Export Project
在这里插入图片描述
-> 点击Export导出,记住放在哪里了,等等要用

Android项目构建

1、新建Android项目
(1)建立一个Empty Activity
在这里插入图片描述
(2)设置Android包名、MIni API Level(需与Unity设置一致)
在这里插入图片描述

2、引入之前建立好的Unity项目
依次(->) 点击/执行操作
-> File=>New => Import Module
-> 选择刚刚Unity导出的文件夹,保证launcher和unityLibrary选中,导入(图片是已经导入过了,正常情况不会报错)
在这里插入图片描述
-> File->Project Structure->Dependencies
-> 给uniyLIbrary加上unity-classes.jar文件依赖(否则会引起UnityPlayer无法使用)给app加上unityLibrary环境依赖,点击OK(新版本的Android Studio可以不修改复杂的代码就可以进行依赖的修改,但是细节处需要自己调整)
给uniyLIbrary加上unity-classes.jar文件依赖
app加上unityLibrary环境依赖

-> 修改依赖方式:
资源管理器 => Gradle Scripts => build.gradle(Module:untiyLibrary) => dependencies{} => 修改关于unity-classes.jar的引用语句:

implementation files(‘libs\unity-classes.jar’)

修改成:

api files(‘libs\unity-classes.jar’)

否则会引起UnityPlayer无法使用。
关于api和implementation两种依赖方式的不同还请到论坛查找,这里不做赘述。

->重新Biuld项目,如未报错则说明导入成功,且依赖修改成功

Android 与 Unity 的信息交互

承接上文
3、修改AndroidManifest.xml文件,要修改两个
(1)untiyLibrary=>manifests文件夹下的:注释掉< intent-filter>标签;
(2)app=>manifests文件夹下的:在之前的< activity></ activity>标签后添加Unity项目的activity(根据代码提示工具即可,现有结果为:

< activity android:name=“com.unity3d.player.UnityPlayerActivity”/>’)

另外,如果这个文件有大片的警示,如下图所示,请将光标放在警示的代码段上,按下alt+enter,根据提示修改错误(否则会页面闪退)
在这里插入图片描述
在这里插入图片描述
4、修改strings.xml文件。
-> 资源管理器(Android视图):app=>res=>values=>strings.xml
-> 在之前的标签下添加如下语句,否则会Unity页面闪退

< string name=“game_view_content_description”>Game view</ string>

5、编辑java文件。
app=>java=>{包名}文件夹下建立 UnityActivity.Java文件(原文件夹下有MainActivity文件,在这里先不做修改,后面会有其他的操作,总之,后面不会使用这个文件,主要原因是Unity的代码已经写好了,懒得再弄一遍了,嘻嘻,后面你可以自己修改),编写代码:

package com.njucm.android2unity;

import android.app.Activity;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class UnityActivity extends UnityPlayerActivity {
    private Button loadBtn;
    protected UnityPlayer mUnityPlayer;
    public static UnityActivity m_instance=null;

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

        //
        loadBtn = findViewById(R.id.loadBtn);

        //
        loadBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(UnityActivity.this,UnityPlayerActivity.class));
            }
        });

        m_instance = this;
    }

    public void sendmessage()
    {
        UnityPlayer.UnitySendMessage("Main Camera","settextView","this is the message from android");
    }
}

这个时候R.id.loadBtn会报错,是因为还有文件没有编写完,不用担心。
在Android中我们使用

UnityPlayer.UnitySendMessage("{Object Name}",“Function Name”[,“parameter values”);

方法给Unity的脚本发送消息,实现信息的发送
6、编写app=>res=layout=>activity.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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/loadBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Open Unity"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.374"
        tools:ignore="HardcodedText" />

</androidx.constraintlayout.widget.ConstraintLayout>

这个时候R.id.loadBtn报错会消失

7、修改app=>manifests文件夹下的AndroidManifest.xml文件
添加新的UnityActivity,并将其设为MainActivity(首先打开的),修改前内容如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.njucm.android2unity">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"/>
    </application>

</manifest>

修改后内容如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.njucm.android2unity">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
        </activity>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"/>
        <activity android:name=".UnityActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

8、重新Build项目,运行一下试试吧
在这里插入图片描述
可以看到,我们成功打开了Unity的界面,并且在Unity的界面调用了android方法,给Unity发送了消息,修改了Unity的场景物体属性值,实现了极为简单的交互。

结语

本文旨在明确 android调用Unity界面并进行信息交互 实现过程中的问题和步骤,更加复杂的内容还是请各位实现,希望这篇文章能给同行者一些帮助。
至此,完本文毕。

参考文献

1、https://blog.csdn.net/m0_38096376/article/details/69567409
2、https://www.jianshu.com/p/b5e3cfcdf081
3、https://www.jianshu.com/p/b4d5a9afcc99
4、https://blog.csdn.net/qq_39091751/article/details/84023996?ops_request_misc=&request_id=&biz_id=102&utm_term=android%20unity%20%E4%BA%A4%E4%BA%92&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-9-84023996.pc_search_result_no_baidu_js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值