One. Development environment description
Development platform: Windows 10 X64
Unity version: Unity2019.3.0f6
ARFoundation related package package version:
ARFoundation preview.4-3.1.0
ARCoreXRPlugin preview.4-3.1.0
ARKitXRPlugin preview.4-3.1.0
ARKitFaceTracking preview.4-3.1.0
The versions of ARFoundation-related packages must be consistent, otherwise it may cause different platform display effects or bugs after release
2. Unity environment configuration before development
If you need to use the Universal Render Pipeline in your project, it is recommended that you do not check the Universal Render Pipeline when creating a new scene but select the empty project by default. After creating the project, add and configure the Universal Render Pipeline in the PackageManager.
At the same time, it is also necessary to add ARFoundation related plug-ins with the same version on the PackageManager.
three. Description of the role of related plug-ins
ARFoundation AR loading and displaying the core
ARCoreXRPlugin released to the Android platform to use AR function dependencies needs to be consistent with the core version
ARKitXRPlugin preview.4-3.1.0 released to the ios platform to use the AR function dependency needs to be consistent with the core version
ARKitFaceTracking preview.4-3.1.0 ios platform face tracking dependency, need to be consistent with the core version
Since ARFoundation relies on Android's arcore and ios' arckit to realize the AR function, webcam cannot be used directly for development and debugging during the development process. The effect can only be seen after publishing to the mobile terminal, so you can develop as much as possible Debug output to locate the location where the bug may appear
four. Method calls and precompiled macro instructions
Android and ios can directly call the public methods of the C# public classes in Unity, but note that only void-type functions can be called, and return-type functions can be called, but different platforms will have different problems when obtaining values. It is recommended to use callback methods. To pass the value.
1. Android
You need to create a Plugins folder in Unity's Assert directory, and create an Android folder in it to store java class files. Unity can get the corresponding java class through the AndroidJavaClass method.
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;
}
}
After creating the java class, you need to check the platform corresponding to the plugin on the panel so that it can be accessed by the java class when the Android project file is generated.
In the code, use macros to determine the current platform and trigger the corresponding callback event, because the callback is declared with an abstract function, and the callback can be directly performed as long as the corresponding function is overwritten on the java side.
#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 edge
You need to create a Plugins folder in Unity's Assert directory, and create an IOS folder in it to store objectc class files. Unity can obtain the corresponding callback method by customizing the NativeAPI class.
After creating the objectc class, you need to check the platform corresponding to the plugin on the panel, so that it can be accessed by the objectc class when the ios project file is generated. Note that ios needs to create a corresponding .h header file with the same name The .mm category.
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];
}
}
In Unity, a NativeAPI class needs to be defined in advance. This class defines all the methods that have been known in .h before. NativeAPI can be created in precompiled macros.
#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
In this way, you can directly trigger the callback method directly in the pre-compiled macro
#elif UNITY_IOS || UNITY_TVOS
NativeAPI.function1();
#endif
It should be noted that, regardless of the ios or Android platform, the parameter passing in the callback method only supports string-type functions, because Unity is written in C# code, and the name of the callback is only defined in the C# format, but the corresponding java class In, the string name must be replaced by String; and in the corresponding .h and .mm classes, the string name must be replaced by (char*).
Fives. Mobile platform release configuration
1. Android
If the Android terminal is released as a project for Android packaging or application embedding, you need to check Export Project in BuildSettings.
PlayerSettings interface
There are a few points to note, because RealiboxShader is processed in Gamma space, you need to set ColorSpace to Gamma, GraphicsAPI only selects OpenGLES3 and cancels Auto. MinumApiLevel needs to select Android7.0'Nougat' (API level 24) that supports ARCore, and Target API Level selects Automatic (highest installed) and XRSettings does not need to check ARCore Supports
2. ios edge
Unity can only publish the XCode project file of ios, and then package and compile it by XCode
PlayerSettings interface
There are a few points to note when publishing ios. ColorSpace needs to be set to Gamma (because my shader is calculated in gamma space), Graphics APIs only select Metal by default, and uncheck AutoGraphicsAPI. ios will pop up when acquiring permissions, and the text of the popup needs to be manually set here. In Target minimun IOS Version, you need to set the ARKit support 11.0 or more. And check Require ARKit support. When the project package needs to be embedded in other ios applications, you need to uncheck the Strip Engine Code