基于ARFoundation开发ios与android双平台兼容的配置说明

一.开发环境说明

开发平台: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

猜你喜欢

转载自blog.csdn.net/ssssssilver/article/details/106012118