Unity 与 Android/iOS 交叉开发主要有两种方式,以 Android 为例,一是 Android 生成 jar 或者 aar 包,导入到 unity3d plugin/bin/ 目录下;二是 Unity 导出 Android 工程,在 Android Studio 中作为库继续开发。网上的教程几乎全是第一种方式,而本文主要分析第二种方式。

这种方式可以在移动端的 NativeApp 中以,库的形式集成已经写好的 Unity 工程,利用 Unity 游戏引擎便捷的开发手段进行跨平台开发。

Unity官方文档 Unity as a Library integration example to iOS and Android

以下以安卓平台作为示例。

环境

  • Android Studio 3.5.3
  • Unity version 2019.3.7f1

新建工程

  • Android Studio 新建项目:

  • Unity 新建项目:
  • 最终工程结构如下:

Unity导出

  • 通过 Unity 打开 UnityProject

  • 选择 File -> Build Settings -> Switch Android Platform -> Export Project

  • 这时候选择Export可能会提示JDK路径配置出错,没关系我们到 Preference -> Externl Tools 设置路径

  • 现在就可以点击 Export 了,路径选择可以自由选择,这里建议按照官方来

Android接入

  • 通过 Android Studio 打开 NativeAndroidApp

  • 选择 setting.gradle 文件添加 unityLibrary module

    include ':unityLibrary'
    project(':unityLibrary').projectDir = new File('..\\UnityProject\\androidBuild\\unityLibrary')
  • 选择 build.gradle(Module:app)添加 dependencies

    dependencies {
    implementation project(':unityLibrary')
    implementation fileTree(dir: project(':unityLibrary').getProjectDir().toString() + ('\\libs'), include: ['*.jar'])
    // 自己项目的配置
    }
  • 选择 build.gradle(Module:NativeAndroidApp)

    allprojects {
    repositories {
    google()
    jcenter() // Add Code
    flatDir {
    dirs "${project(':unityLibrary').projectDir}/libs"
    }
    // End
    }
    }
  • 选择 NativeAndroidApp 的 strings.xml 添加

    <resources>
    <string name="app_name">NativeAndroidApp</string>
    <string name="action_settings">Settings</string>
    // Add Code
    <string name="game_view_content_description">Game view</string>
    // End
    </resources>
  • 点击 AS 的 sync project,可以看到已经多了一个 module:



    现在我们可以直接使用这个 module 里的 java class 了。

如何使用

作为Activity

现在我们的工程包含了两个 module ,一个是新建工程自带的 app,一个是刚才导入的 unityLibrary。点开 unityLibrary 的目录可以看到两个主要的 class :

其中 UnityPlayerActivity 是最重要的 class ,我们可以通过这个类在安卓 app 中显示 Unity 的场景。至于怎么使用—— OverrideUnityActivity 则是对 UnityPlayerActivity 用法的一个官方示例,里面的代码也很简单

import com.unity3d.player.UnityPlayerActivity;

public abstract class OverrideUnityActivity extends UnityPlayerActivity
{
public static OverrideUnityActivity instance = null; abstract protected void showMainActivity(String setToColor); @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
instance = this;
} @Override
protected void onDestroy() {
super.onDestroy();
instance = null;
}
}

显然官方是希望我们在安卓内用一个 Activity 去显示 Unity 渲染的场景,至于这个 Activity ,直接继承 UnityPlayerActivity 就基本完事了,非常简单。

那么我们新建一个 Activity,这里我起名为 MainUnityActivity:

public class MainUnityActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

你大可什么都不写,只要继承 UnityPlayerActivity 就行了。现在构建 app,进入 MainUnityActivity 的时候就会显示 Unity 的场景了。

作为subView

当然你可能需要将 Unity 的场景作为子视图显示,而不是让 Unity 占据你的整个屏幕,这套简单方法就不适合了,不过仍然有解决方案,参考 Display Unity Scene as Sub View in android studio

我们先来观察 UnityPlayerActivity 里面到底写了什么:

public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
{
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code // Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player
// The command line arguments are passed as a string, separated by spaces
// UnityPlayerActivity calls this from 'onCreate'
// Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan
// See https://docs.unity3d.com/Manual/CommandLineArguments.html
// @param cmdLine the current command line arguments, may be null
// @return the modified command line string or null
protected String updateUnityCommandLineArguments(String cmdLine)
{
return cmdLine;
} // Setup activity layout
@Override protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState); String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
getIntent().putExtra("unity", cmdLine); mUnityPlayer = new UnityPlayer(this, this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
} ......
}

其实关键就在于这几行

protected UnityPlayer mUnityPlayer;
......
mUnityPlayer = new UnityPlayer(this, this);
setContentView(mUnityPlayer);//←

我们只要照猫画虎的把 UnityPlayer 写进一个 FrameLayout 里就行了:

private UnityPlayer mUnityPlayer;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Create the UnityPlayer
mUnityPlayer = new UnityPlayer(this); setContentView(R.layout.activity_sub); FrameLayout layout = (FrameLayout) findViewById(R.id.FrameLayout); LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
layout.addView(mUnityPlayer.getView(), 0, layoutParams); }

这样下来 UnityActivity 就能显示在一个 FrameLayot 里了。

进阶用法

举个例子,Unity中有很多内置插件可以自动操控摄像头,编译到移动平台时,使用这些插件可以满足大部分场景,不需要额外编程,直接在 Unity 做好后打包就可以了。但是当你需要以下应用场景:

  • 检测摄像头视频数据中的人脸
  • 自定义美颜(CPU美颜算法)

的时候,使用Unity内置或扩展插件就难以完成这个任务了。这时候,就需要 Unity 和移动平台交叉开发,比如以下这套流程

Android/iOS native app 操作摄像头 -> 获取视频流数据 -> 人脸检测或美颜 -> 传输给 Unity 渲染 -> Unity做出更多的效果(滤镜/粒子)

只后会发一篇安卓和 Unity 线程共享 eglcontext 的博客,先占个坑位。

参考资料:

Android/iOS内嵌Unity开发示例的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  2. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  3. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  4. Android IOS WebRTC 音视频开发总结(四六)-- 从另一个角度看国内首届WebRTC大会

    文章主要从开发者角度谈国内首届WebRTC大会,支持原创,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help. -------------------- ...

  5. Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验

    前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...

  6. Android IOS WebRTC 音视频开发总结(五七)-- 网络传输上的一种QoS方案

    本文主要介绍一种QoS的解决方案,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help QoS出现的背景: 而当网络发生拥塞的时候,所有的数据流都有 ...

  7. Android IOS WebRTC 音视频开发总结(十七)-- 调试技巧

    本文章主要介绍WEBRTC在各平台下调试或日志查看方式,以方便问题排查,包括BS,PC,Android,IOS(本系列文章转载请说明出处,博客园RTC.Blacker). 1,浏览器开发: 这种开发方 ...

  8. 移动端开发利器vConsole.js,app内嵌H5开发时调试用

    vConsole:一个轻量.可拓展.针对手机网页的前端开发者调试面板,主要还是用于内嵌app页面时在手机上进行调试,打印完全和在PC端一样,方便大家找出问题所在. 不说废话直接进入主题,vConsol ...

  9. Android IOS WebRTC 音视频开发总结(二三)-- hurtc使用说明

    本文主要介绍如何测试基于浏览器和手机的视频通话程序,转载请说明出处,文章来自博客园RTC.Blacker,更多详见www.blackerteam.com   很多人想测试浏览器(包括浏览器版本和桌面e ...

随机推荐

  1. 关于Graph Convolutional Network的初步理解

    为给之后关于图卷积网络的科研做知识积累,这里写一篇关于GCN基本理解的博客.GCN的本质是一个图网络中,特征信息的交互+与传播.这里的图指的不是图片,而是数据结构中的图,图卷积网络的应用非常广泛 ,经 ...

  2. [转] strtol()详解

    点击此处阅读原文 今天,在review 一些代码的时候,看到了strtol()这个函数,由于以前使用它的时候,还没有深刻的了解,这次,我决定探个究竟. 网上关于这个函数的资料大都来源于同份资料,lin ...

  3. (十一)Maven运行TestNG的testcase 两种方式:testng.xml和testngCase.java

    原文:https://blog.csdn.net/wwhrestarting/article/details/46596869?utm_source=copy 1.通过maven-surefire-p ...

  4. Jlink设置正确,但下载程序失败

    [图中reset and run]勾选后即每次·下载程序后会自动复位,不需要再在硬件上进行复位 各参数设置正确 但依然下载失败. 原因是需要重新再编译一次,因为上次设置错误,编译后目标未创建! 重新编 ...

  5. 一篇看懂Docker

    松勤教育2020.4.20 我要分享     Docker 是什么? Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口.它是目前最流行的 Linux 容器解决方案. Dock ...

  6. excel筛选重复项代码

    Sub test()'updateby Extendoffice 20151030    Dim xRng As Range    Dim xTxt As String    On Error Res ...

  7. post请求头的常见类型

    1.application/json(JSON数据格式) xhr.setRequestHeader("Content-type","application/json; c ...

  8. Oracle调用Java方法(上)如何使用LoadJava命令和如何将简单的Jar包封装成Oracle方法

    最近在工作中遇到了遇到了一个需求需要将TIPTOP中的数据导出成XML并上传到FTP主机中,但是4GL这方面的文档比较少最终决定使用Oracle调用Java的方法,在使用的过程中发现有很多的坑,大部分 ...

  9. opencv C++全局直方图均衡化

    cv::Mat histogramEqualization(cv::Mat img){ int rows=img.rows; int cols=img.cols; cv::Mat grayScale= ...

  10. 黎活明8天快速掌握android视频教程--15_采用Pull解析器解析和生成XML内容

    1.该项目主要有下面的两个作用 (1)将xml文件解析成对象的List对象,xml文件可以来自手机本地,也可以来自服务器返回的xml数据 (2)强list对象保存成xml文件,xml保存到手机的内存卡 ...