随着技术的发展,越来越多的APP期望拥有3D,AR的能力。要达到这个目标可以选择使用原生开发,也可以使用Unity成熟的3D开发技术链,通过嵌入的方式将Unity容器嵌入到APP中。这里介绍的是通过嵌入Unity容器的方式来实现APP的3D,AR能力的。
 
Unity集成到iOS应用的本质是将Unity中所有用到的资源,模型,代码打包成一个framework动态库,然后嵌入到APP的内部。APP启动后加载Unity页面时,会加载这个framework动态库和里面的所有资源。然后在APP中展示这个Unity页面。
 
Unity集成到iOS应用的官方提供的方案是以Workspace的方式集成,具体步骤如下:
1.Unity项目通过Unity Editer 导出一个iOS项目,这个iOS项目里包含了整个Unity项目的所有代码和资源,可以直接运行在iOS系统上。
2.用Xcode创建一个原生的iOS项目
3.用Xcode创建一个Workspace, 然后通过add file 的形式将这2个项目添加到一个Workspace下面。
4.修改Unity-iPhone项目打包设置,使其打包出适合嵌入的UnityFramework动态库,
5.修改NativeiOSApp项目配置,添加UnityFramework动态库。
对Workspace下面的2个项目进行配置
Unity-iPhone创建
在生成UnityFramework动态库前,需要将Unity项目导出一个iOS项目,导出的过程如下:
1.点击File->Building Settings进入到选择导出页面

2.选择要导出的平台,这里选择iOS,然后点击右下角的"Switch Plateform"按钮,然后点击上面的“Add Open Scenes”添加场景

3.点击“Build”,导出iOS项目

Unity-iPhone设置
关闭以Workspace方式打开的Xcode,单独打开Unity-iPhone项目
1.在Unity-iPhone项目中,设置Data 这个Group的 Target Memebership, 将里面的UnitFramework项打勾,表示这个Data在生成Framework静态库时也要作为其中的一员,放置进去。
2.将NativeCallProxy.h头文件从Framework的 protect组移动到public组,将头文件开放出来。路径为: Unity-iPhone / Libraries / Plugins / iOS / NativeCallProxy.h
3.手机连接电脑,运行,生成静态库。
NativeiOSApp原生项目设置
以Workspace方式打开项目
1.在NativeiOSApp Target - General - Frameworks, Libraries, and Embedded Content 通过点击+ 将UnityFramework设置嵌入到项目中
2.在NativeiOSApp Target - Build Phases - Link Binary With Libraries中,点击-,将UnityFramework移除,表示禁止在项目链接时将UnityFramework链接到可执行文件中,它只作为内嵌在APP中的静态库在运行时加载使用。
3.手机连接电脑,运行,看到Demo运行的效果。
 
 
Unity与原生通信
Unity调用原生
1.首先在原生中实现代理协议NativeCallProxy中的方法(注册由谁来处理unity的调用)和添加暴露给unity的方法。
NativeCallProxy.h文件中方法的声明
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi; @end
NativeCallProxy.cpp文件中方法的实现
@implementation FrameworkLibAPI

id<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi
{
api = aApi;
} @end
给Unity暴露的原生调用方法
extern "C" {
void showHostMainWindow(const char* color) { return [api showHostMainWindow:[NSString stringWithUTF8String:color]]; }
}
2.然后在原生的Unity启动时,注册这个处理的对象
- (void)initUnity
{
[self setUfw: UnityFrameworkLoad()];
// Set UnityFramework target for Unity-iPhone/Data folder to make Data part of a UnityFramework.framework and uncomment call to setDataBundleId
// ODR is not supported in this case, ( if you need embedded and ODR you need to copy data )
[[self ufw] setDataBundleId: "com.unity3d.framework"];
[[self ufw] registerFrameworkListener: self];
[NSClassFromString(@"FrameworkLibAPI") registerAPIforNativeCalls:self];
}
3.在Unity中,调用iOS的原生方法
Cube.cs脚本中声明在APP中存在方法showHostMainWindow
#if UNITY_IOS || UNITY_TVOS
public class NativeAPI {
[DllImport("__Internal")]
public static extern void showHostMainWindow(string lastStringColor);
}
#endif
Cube.cs脚本中添加Unity 2d按钮点击事件,调用iOS原生方法
void OnGUI()
{
GUIStyle style = new GUIStyle("button");
style.fontSize = 45;
if (GUI.Button(new Rect(10, 300, 600, 100), "Show Main With Color", style)) showHostMainWindow();
} void showHostMainWindow()
{
#if UNITY_ANDROID
try
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity.mynativeapp.SharedClass");
jc.CallStatic("showMainActivity", lastStringColor);
} catch(Exception e)
{
appendToText("Exception during showHostMainWindow");
appendToText(e.Message);
}
#elif UNITY_IOS || UNITY_TVOS
NativeAPI.showHostMainWindow(lastStringColor);
#endif
}
原生调用Unity
点击原生发送消息按钮,发消息给Unity。
self.btnSendMsg = [UIButton buttonWithType: UIButtonTypeSystem];
[self.btnSendMsg setTitle: @"Send Msg" forState: UIControlStateNormal];
[self.btnSendMsg addTarget: self action: @selector(sendMsgToUnity) forControlEvents: UIControlEventPrimaryActionTriggered]; - (void)sendMsgToUnity
{
[[self ufw] sendMessageToGOWithName: "Cube" functionName: "ChangeColor" message: "yellow"];
} /*
goName: 场景中的游戏物体GameObject
name: 这个游戏物体挂载的脚本中的一个方法
msg: 参数
*/
- (void)sendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg
{
UnitySendMessage(goName, name, msg);
} void UnitySendMessage(const char* obj, const char* method, const char* msg);
Cube.cs脚本中的方法实现
string lastStringColor = "";
void ChangeColor(string newColor)
{
appendToText( "Changing Color to " + newColor ); lastStringColor = newColor; if (newColor == "red") GetComponent<Renderer>().material.color = Color.red;
else if (newColor == "blue") GetComponent<Renderer>().material.color = Color.blue;
else if (newColor == "yellow") GetComponent<Renderer>().material.color = Color.yellow;
else GetComponent<Renderer>().material.color = Color.black;
}
 
Unity热更新
在Unity项目中使用纯C#构建的渐渐不能适应移动端的需求,移动端通常通过添加热更新插件来实现热更新功能。这个过程起关键作用的是Lua和起对应的解释器。
lua是解释型语言,并不需要事先编译成块,而是运行时动态解释执行的。
这样LUA就和普通的游戏资源如图片,文本没有区别,因此可以在运行时直接从WEB服务器上下载到持久化目录并被其它LUA文件调用。
Lua热更新解决方案是通过一个Lua热更新插件(如ulua、slua、tolua、xlua等)来提供一个Lua的运行环境以及和C#进行交互。
所以lua热更新的流程可以简单理解为:将逻辑代码使用脚本实现,再将脚本转化为文本资源,最后以更新资源的形式来更新程序,以此来实现热更新。
注意:
在iOS应用内的Unity容器中,Untiy的C#资源和Lua资源都是在Unity容器内部进行加载的。如果Unity采用的Lua热更新,则需要原生侧在Lua脚本和资源下载完成后通知Unity进行加载展示。
Demo地址
NativeiOSApp项目地址:https://github.com/zhfei/uaal-example
将 Unity 集成到原生 iOS 应用程序中官方文档:https://docs.unity3d.com/cn/2020.2/Manual/UnityasaLibrary-iOS.html
 
 
 
 
 

在原生APP中集成Unity容器的更多相关文章

  1. iOS原生项目中集成React Native

    1.本文的前提条件是,电脑上已经安装了CocoaPods,React Native相关环境. 2.使用Xcode新建一个工程.EmbedRNMeituan [图1] 3.使用CocoaPods安装Re ...

  2. 怎么在我们的App中集成条码扫描功能?

    现在很多App都有条码扫描功能,有的手机比如某米在照相机中集成了条码扫描功能,但是还有一部分手机没有这样的集成,比如韩国某星,需要自己下载一个条码扫描App.今天我们就来看看怎么在自己的App中集成一 ...

  3. APICloud原生APP中ajax需要用api.ajax

    报错截屏: APICloud原生APP中ajax请求需要用api.ajax(api对象的ajax方法来替代),否则会将引起请求失败. APICloud api.ajax

  4. c#中的Unity容器

    DIP是依赖倒置原则:一种软件架构设计的原则(抽象概念).依赖于抽象不依赖于细节 IOC即为控制反转(Inversion of Control):传统开发,上端依赖(调用/指定)下端对象,会有依赖,把 ...

  5. 在APP中集成iAd Banner展示广告盈利

    如果你已经做了一款超牛X的APP.你也许还有一件是需要操心.APP够好了,怎么盈利呢?你可以对下载你的APP的用户收费.也可以完全的免费,然后在APP里放广告来实现盈利.现在来说,除非一款APP真的是 ...

  6. 在Android App中集成Google登录

    技术文章 来源:码农网 发布:2016-09-19 浏览:194 摘要:今天,几乎所有的web和移动app都自带谷歌和Facebook登录,这对app开发者和用户来说是一个非常有用的功能,因为几乎每个 ...

  7. 如何在WCF中集成unity

    第一种是代码方式: 点击打开链接http://blogs.microsoft.co.il/gadib/2010/11/30/wcf-and-unity-20/ 还有一种方式可以扩展成配置文件,有时间再 ...

  8. RN与现有的原生app集成

    https://facebook.github.io/react-native/docs/integration-with-existing-apps.html RN可以很好地支持往一个原生的app上 ...

  9. 转发-UI基础教程 – 原生App切图的那些事儿

    UI基础教程 – 原生App切图的那些事儿 转发:http://www.shejidaren.com/app-ui-cut-and-slice.html 移动APP切图是UI设计必须学会的一项技能,切 ...

  10. 原生App切图的那些事儿

    如何切图? 了解iphone界面的尺寸 最小的分辨率是320x480,我们把这个尺寸定为基准界面尺寸(baseline),基准尺寸所用的图标定为1倍图(1x). 在实际设计过程中,为了降低设计成本,一 ...

随机推荐

  1. MVC 三层架构案例详细讲解

    MVC 三层架构案例详细讲解 @ 目录 MVC 三层架构案例详细讲解 每博一文案 1. MVC 概述 2. MVC设计思想 3. 三层架构 4. MVC 与 三层架构的关系: 5. 案例举例:用户账户 ...

  2. 【一步步开发AI运动小程序】二、引入插件

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的"乐动力"."天天跳绳"AI运动APP,让云上运动会.线上运动会.健身打卡.AI体育指导等概念空前火热.那 ...

  3. 顶会ICSE-2023发布LIBRO技术,利用大模型技术进行缺陷重现,自动重现率达33%

    摘要:本文围绕LIBRO技术的主要步骤进行介绍. 本文分享自华为云社区<[LLM for SE]顶会ICSE-2023发布LIBRO技术,利用大模型技术进行缺陷重现,自动重现率(33%)实现业界 ...

  4. MariaDB server_audit 审计插件

    具体安装步骤: 1.使用SHOW VARIABLES LIKE 'plugin_dir'; 查出插件安装目录 2.复制 mariadb-5.5.58-linux-x86_64/lib/plugin 下 ...

  5. Prompt 手册——gpt-best-practices

    本文链接:https://www.cnblogs.com/wanger-sjtu/p/17470388.html 本文是 OpenAI gpt-best-practices 对如何使用GPT的Prom ...

  6. 【TVM模型编译】0.onnx模型优化流程.md

    本文以及后续文章,着重于介绍tvm的完整编译流程. 后续文章将会按照以上流程,介绍tvm源码.其中涉及一些编程技巧.以及tvm概念,不在此部分进行进一步讲解,另有文章进行介绍. 首先介绍一下,从onn ...

  7. 完全兼容DynamoDB协议!GaussDB(for Cassandra)为NoSQL注入新活力

    摘要:DynamoDB是一款托管式的NoSQL数据库服务,支持多种数据模型,广泛应用于电商.社交媒体.游戏.IoT等场景. 本文分享自华为云社区<完全兼容DynamoDB协议!GaussDB(f ...

  8. 【C#/.NET】RESTful风格的Post请求与CreateAtAction

    ​  目录 引言 实现步骤 概念介绍 创建控制器 总结 引言 在构建Web应用程序时,遵循RESTful风格的API设计原则能够使我们的系统更加灵活.可扩展和易于维护.其中,Post请求在创建资源时起 ...

  9. CSS_相关问题及解决_持续更新

    css_margin塌陷问题 问题描述 <div class="father"> <div class="child1"></di ...

  10. 基于SM4和LSB算法实现图片数字水印加密软件(密码赛)

    一.前言 密码赛和星火杯时做的小项目,密码赛的时候是个半成品,没有过初赛,星火杯之前完善了 设计思路 最开始是想做一个图片水印用作对图片来源的不可否认性做保护,又考虑保护数据完整性,因此选中了易损水印 ...