一.开发环境说明
开发平台:Windows 10 X64
Unity版本:Unity2019.3.0f6
ARFoundation相关的package包版本:
ARFoundation preview.4-3.1.0
ARCoreXRPlugin preview.4-3.1.0
ARKitXRPlugin preview.4-3.1.0
ARKitFaceTracking preview.4-3.1.0
ARFoundation相关的package包的版本必须保持一致,否则有可能导致发布后不同平台显示效果不一样或者出现bug
二. 开发前Unity环境配置
如果需要在项目中使用通用渲染管线(UniversalRenderPipeline),建议在新建场景时不勾选通用渲染管线而是默认选择空项目,创建工程后在PackageManager中再添加配置通用渲染管线。
同时也需要在PackageManager上添加版本一致的ARFoundation相关插件。
三.相关插件的作用说明
ARFoundation AR加载显示的核心
ARCoreXRPlugin 发布到安卓平台使用AR功能的依赖 需要与核心版本一致
ARKitXRPlugin preview.4-3.1.0 发布到ios平台使用AR功能的依赖 需要与核心版本一致
ARKitFaceTracking preview.4-3.1.0 ios平台人脸追踪的依赖,需要与核心版本一致
由于ARFoundation是依赖安卓的arcore跟ios的arkit来实现AR功能的,在开发过程中并不能直接使用webcam来进行开发调试,需要发布到移动端后才能看到效果,所以在开发时可以尽量多的debug输出来定位有可能出现bug的位置
四.方法调用和预编译宏指令
安卓与ios能直接调用unity中C#的公有类的公有方法,但要注意只能调用void型函数,返回型的函数可以调用,但获取值时不同平台会出现不同的问题,建议使用回调的方法来传递值。
1. 安卓端
需要在Unity的Assert目录下创建一个Plugins文件夹,并在里面创建一个Android文件夹,用于存放java类文件,unity可以通过AndroidJavaClass方法来获取到对应的java类.
package com.xx.ar;
import android.os.Bundle;
import android.widget.FrameLayout;
import com.unity3d.player.UnityPlayerActivity;
public abstract class xxUnityActivity extends UnityPlayerActivity
{
//
abstract protected void function1(String var);
//
abstract protected void function2();
//
abstract protected void function3();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
instance = this;
}
@Override
protected void onDestroy() {
super.onDestroy();
instance = null;
}
}
在创建完java类后,需要在面板上勾选plugin对应使用的平台,这样在生成安卓工程文件时就能被java的类访问到。
在代码中,使用宏来判断当前的平台,并且触发对应的回调事件,因为回调是用抽象函数来申明的,只要java端复写了对应的函数就能直接进行回调。
#if UNITY_ANDROID
AndroidJavaClass jc = new AndroidJavaClass("com.realibox.ar.RealiboxUnityActivity");
AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("instance");
activity.Call("function", value.ToString());
#endif
2. ios端
需要在Unity的Assert目录下创建一个Plugins文件夹,并在里面创建一个IOS文件夹,用于存放objectc类文件,unity可以通过自定义NativeAPI类来获取到对应的回调方法。
在创建完objectc类后,需要在面板上勾选plugin对应使用的平台,这样在生成ios工程文件时就能被objectc的类访问到,要注意的是ios需要创建对应的.h头文件与同名的.mm类。
xx.h
// [!] important set UnityFramework in Target Membership for this file
// [!] and set Public header visibility
#import <Foundation/Foundation.h>
// NativeCallsProtocol defines protocol with methods you want to be called from managed
@protocol NativeCallsProtocol
@required
-(void)function1:(char*)var;
//
-(void)function2:(char*)var2;
//
-(void)functoin;
// other methods
@end
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;
@end
xx.mm
#import <Foundation/Foundation.h>
#import "NativeCallProxy.h"
@implementation FrameworkLibAPI
id<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi
{
api = aApi;
}
@end
extern "C" {
void function1(char* var1) {
return [api function1:var1];
}
void function2(char* var2) {
return [api function2:var2];
}
void function3() {
return [api function3];
}
}
在Unity中,需要事先定义好一个NativeAPI类,这个类里定义之前在.h里面声名好的所有方法,NativeAPI可以在预编译宏里创建。
#if UNITY_IOS || UNITY_TVOS
public class NativeAPI {
[DllImport("__Internal")]
public static extern void function2(string status);
[DllImport("__Internal")]
public static extern void function1(string msg);
}
#endif
这样的话就能直接在预编译宏里面直接触发回调方法
#elif UNITY_IOS || UNITY_TVOS
NativeAPI.function1();
#endif
需要注意的是,不管是ios还是安卓平台,回调方法里面的传参只支持string型的函数,因为Unity用的是C#代码编写,回调的声名只要按C#的格式来定义,但对应的java类中,string声名要换成String;而在对应的.h与.mm类中,string声名要换成(char*)。
五.移动平台的发布配置
1. 安卓端
安卓端如果是发布成工程给到安卓打包或者应用内嵌的话,需要在BuildSettings中勾选Export Project。
PlayerSettings界面
有几点需要注意,因为RealiboxShader是在Gamma空间下处理的,需要把ColorSpace设置成Gamma,GraphicsAPI只选取OpenGLES3并取消Auto。MinumApiLevel需要选择支持ARCore的Android7.0’Nougat’(API level 24),并且Target API Level选择Automatic(highest installed) 同时XRSettings是不需要勾选ARCore Supports
2. ios端
Unity只能发布ios的XCode工程文件,再由XCode进行打包编译
PlayerSettings界面
发布ios端需要注意几点,ColorSpace需要设置成Gamma(因为我这边着色器是在gamma空间计算的),Graphics APIs默认只选Metal,并取消勾选AutoGraphicsAPI。ios在获取权限时会弹框,弹框的文字需要在这里手动设置。在Target minimun IOS Version中需要设置ARKit支持的11.0以上。并且勾选上Require ARKit support。当工程包需要在ios其他应用中内嵌时,需要取消勾选Strip Engine Code