Unity ARKit Plugin リファレンスまとめを試みる

この記事は [KLab Advent Calendar 2017](https://qiita.com/advent-calendar/2017/klab) 23日目の記事です。
Advent Calendar も大詰めですね。mizusawa-k です。よろしくお願いします。

# はじめに
[Unity](https://unity3d.com/jp) から提供されている [Unity ARKit Plugin](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-arkit-plugin-92515) を触っていたところ、API ドキュメントと思しきものが見当たらなく
「各ファイル、クラスごとのインターフェースをまとめた API リファレンス的なものが欲しいな。」
と思ったので本記事にてまとめていきたいと思います。

# Unity ARKit Plugin とは
Unity ARKit Plugin とは、[iOS 11](https://www.apple.com/jp/ios/ios-11/) から搭載された [ARKit](https://developer.apple.com/arkit/) の機能を Unity で使えるようにしたアセットのことです。

![Asset Store.png](https://qiita-image-store.s3.amazonaws.com/0/215740/926f4f27-0925-e168-6fba-649be03f3791.png)

## 対応バージョン
- Unity 5.6.2 以降
- Xcode 9 以降
- Mac OS X 10.13以降

# Unity ARKit Plugin リファレンスまとめ

## 本リファレンスの対象バージョン
- 1.0.12

## Plugins/iOS/UnityARKitEditor

### ファイル一覧
- UnityARBuildPostprocessor.cs

### UnityARBuildPostprocessor.cs

**Public**

```
	// Build postprocessor. Currently only needed on:
	// - iOS: no dynamic libraries, so plugin source files have to be copied into Xcode project
	[PostProcessBuild]
	public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject);
```

**Private**

```
	private static UnityARKitPluginSettings LoadSettings();

	// Replaces the first C++ macro with the given name in the source file. Only changes
	// single-line macro declarations, if multi-line macro declaration is detected, the
	// function returns without changing it. Macro name must be a valid C++ identifier.
	internal static bool ReplaceCppMacro(string[] lines, string name, string newValue);

	internal static void AddOrReplaceCppMacro(ref string[] lines, string name, string newValue);

	static void UpdateDefinesInFile(string file, Dictionary<string, bool> valuesToUpdate);

	private static void OnPostprocessBuildIOS(string pathToBuiltProject);
```

## Plugins/iOS/UnityARKit/Helper

### ファイル一覧
- AR3DOFCameraManager.cs
- ARPlaneAnchorGameObject.cs
- DontDestroyOnLoad.cs
- PointCloudParticleExample.cs
- UnityARAmbient.cs
- UnityARAnchorManager.cs
- UnityARCameraManager.cs
- UnityARCameraNearFar.cs
- UnityARGeneratePlane.cs
- UnityARHitTestExample.cs
- UnityARKitControl.cs
- UnityARKitLightManager.cs
- UnityARMatrixOps.cs
- UnityARUserAnchorComponent.cs
- UnityARUtility.cs
- UnityARVideo.cs
- UnityPointCloudExample.cs

### AR3DOFCameraManager.cs

```
public class AR3DOFCameraManager : MonoBehaviour {

    public Camera m_camera;
    private UnityARSessionNativeInterface m_session;
    private Material savedClearMaterial;

    // Use this for initialization
    void Start ();

    public void SetCamera(Camera newCamera);

    private void SetupNewCamera(Camera newCamera);

    // Update is called once per frame
#if !UNITY_EDITOR
    void Update ();
#endif

}
```
### ARPlaneAnchorGameObject.cs

**Public**

```
	public class ARPlaneAnchorGameObject
	{
		public GameObject gameObject;
		public ARPlaneAnchor planeAnchor;
	}
```

### DontDestroyOnLoad.cs

**Public**

```
public class DontDestroyOnLoad : MonoBehaviour {

	// Use this for initialization
	void Start ();
	
	// Update is called once per frame
	void Update ();
}
```
### PointCloudParticleExample.cs

**Public**

```
public class PointCloudParticleExample : MonoBehaviour {
    public ParticleSystem pointCloudParticlePrefab;
    public int maxPointsToShow;
    public float particleSize = 1.0f;
    private Vector3[] m_PointCloudData;
    private bool frameUpdated = false;
    private ParticleSystem currentPS;
    private ParticleSystem.Particle [] particles;

    // Use this for initialization
    void Start ();
	
    public void ARFrameUpdated(UnityARCamera camera);

    // Update is called once per frame
    void Update ();
}
```
### UnityARAmbient.cs

**Public**

```
    public class UnityARAmbient : MonoBehaviour
    {
        private Light l;

        public void Start();

        void UpdateLightEstimation(UnityARCamera camera);

        void OnDestroy();
    }
```
### UnityARAnchorManager.cs

**Public**

```
	public class UnityARAnchorManager 
	{
		private Dictionary<string, ARPlaneAnchorGameObject> planeAnchorMap;

		public UnityARAnchorManager ();

		public void AddAnchor(ARPlaneAnchor arPlaneAnchor);

		public void RemoveAnchor(ARPlaneAnchor arPlaneAnchor);

		public void UpdateAnchor(ARPlaneAnchor arPlaneAnchor);

		public void Destroy();

		planeAnchorMap.Clear ();

		public List<ARPlaneAnchorGameObject> GetCurrentPlaneAnchors();
	}
```
### UnityARCameraManager.cs

**Public**

```
public class UnityARCameraManager : MonoBehaviour {

	public Camera m_camera;
	private UnityARSessionNativeInterface m_session;
	private Material savedClearMaterial;

	[Header("AR Config Options")]
	public UnityARAlignment startAlignment = UnityARAlignment.UnityARAlignmentGravity;
	public UnityARPlaneDetection planeDetection = UnityARPlaneDetection.Horizontal;
	public bool getPointCloud = true;
	public bool enableLightEstimation = true;

	// Use this for initialization
	void Start ();

	public void SetCamera(Camera newCamera);

	private void SetupNewCamera(Camera newCamera);

	// Update is called once per frame
	void Update ();
}
```
### UnityARCameraNearFar.cs

**Public**

```
[RequireComponent(typeof(Camera))]
public class UnityARCameraNearFar : MonoBehaviour {

	private Camera attachedCamera;
	private float currentNearZ;
	private float currentFarZ;

	// Use this for initialization
	void Start ();

	void UpdateCameraClipPlanes();
	
	// Update is called once per frame
	void Update ();
}
```
### UnityARGeneratePlane.cs

**Public**

```
	public class UnityARGeneratePlane : MonoBehaviour
	{
		void OnDestroy();
		void OnGUI();
	}
```
### UnityARHitTestExample.cs

**Public**

```
	public class UnityARHitTestExample : MonoBehaviour
	{
		public Transform m_HitTransform;

        	bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes);

		// Update is called once per frame
		void Update ();
	}
```
### UnityARKitControl.cs

**Public**

```
    public class UnityARKitControl : MonoBehaviour {

        UnityARSessionRunOption [] runOptions = new UnityARSessionRunOption[4];
        UnityARAlignment [] alignmentOptions = new UnityARAlignment[3];
        UnityARPlaneDetection [] planeOptions = new UnityARPlaneDetection[4];

        int currentOptionIndex = 0;
        int currentAlignmentIndex = 0;
        int currentPlaneIndex = 0;

    	// Use this for initialization
    	void Start ();
    	
    	// Update is called once per frame
    	void Update ();
        void OnGUI();
    }
```
### UnityARKitLightManager.cs

**Public**

```
public class UnityARKitLightManager : MonoBehaviour {

	Light [] lightsInScene;
	SphericalHarmonicsL2 shl;

	// Use this for initialization
	void Start ();

	void OnDestroy();
	
	Light []  FindAllLights();

	void UpdateLightEstimations(UnityARCamera camera);

	void UpdateBasicLightEstimation(UnityARLightEstimate uarle);
	}

	void UpdateDirectionalLightEstimation(UnityARDirectionalLightEstimate uardle);
}

```
### UnityARMatrixOps.cs

**Public**

```
	public class UnityARMatrixOps
	{
		public static Vector3 GetPosition(Matrix4x4 matrix);

		public static Quaternion GetRotation(Matrix4x4 matrix);

		static Quaternion QuaternionFromMatrix(Matrix4x4 m);
	}
```
### UnityARUserAnchorComponent.cs

**Public**

```
    public class UnityARUserAnchorComponent : MonoBehaviour {

        private string m_AnchorId;

        public string AnchorId  { get { return m_AnchorId; } }

        void Awake();
        void Start ();

        public void AnchorRemoved(ARUserAnchor anchor);

        void OnDestroy();

        private void GameObjectAnchorUpdated(ARUserAnchor anchor);
    }
```
### UnityARUtility.cs

**Public**

```
	public class UnityARUtility
	{
		private MeshCollider meshCollider; //declared to avoid code stripping of class
		private MeshFilter meshFilter; //declared to avoid code stripping of class
		private static GameObject planePrefab = null;

		public static void InitializePlanePrefab(GameObject go);
		
		public static GameObject CreatePlaneInScene(ARPlaneAnchor arPlaneAnchor);

		public static GameObject UpdatePlaneWithAnchorTransform(GameObject plane, ARPlaneAnchor arPlaneAnchor);
	}
```
### UnityARVideo.cs

**Public**

```
    public class UnityARVideo : MonoBehaviour
    {
        public Material m_ClearMaterial;

        private CommandBuffer m_VideoCommandBuffer;
        private Texture2D _videoTextureY;
        private Texture2D _videoTextureCbCr;
	private Matrix4x4 _displayTransform;

	private bool bCommandBufferInitialized;

	public void Start();
	void UpdateFrame(UnityARCamera cam);

	void InitializeCommandBuffer();

	void OnDestroy();

#if !UNITY_EDITOR
        public void OnPreRender();
#else

	public void SetYTexure(Texture2D YTex);

	public void SetUVTexure(Texture2D UVTex);
	public void OnPreRender();
 
#endif
    }
```
### UnityPointCloudExample.cs

**Public**

```
public class UnityPointCloudExample : MonoBehaviour
{
    public uint numPointsToShow = 100;
    public GameObject PointCloudPrefab = null;
    private List<GameObject> pointCloudObjects;
    private Vector3[] m_PointCloudData;

    public void Start();

    public void ARFrameUpdated(UnityARCamera camera);

    public void Update();
}
```

## Plugins/iOS/UnityARKit/NativeInterface

### ファイル一覧
- ARAnchor.cs
- ARCamera.cs
- ARErrorCode.cs
- ARFaceAnchor.cs
- ARFrame.cs
- ARHitTestResult.cs
- ARHitTestResultType.cs
- ARLightEstimate.cs
- ARPlaneAnchor.cs
- ARPlaneAnchor.cs
- ARPlaneAnchorAlighment.cs
- ARPoint.cs
- ARRect.cs
- ARSize.cs
- ARTextureHandles.cs
- ARTrackingQuality.cs
- ARTrackingState.cs
- ARTrackingStateReason.cs
- ARUserAnchor.cs
- UnityARSessionNativeInterface.cs

### ARAnchor.cs

**Public**

```
	public struct ARAnchor
	{
		public string identifier;

		/**
 		The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
		 */
		public Matrix4x4 transform;
	}
```

### ARCamera

**Public**

```
	public struct ARCamera
	{
		/**
		 The transformation matrix that defines the camera's rotation and translation in world coordinates.
 		*/

		public Matrix4x4 worldTransform;

		/**
		 The camera's orientation defined as Euler angles.
		 
		 @dicussion The order of components in this vector matches the axes of rotation:
		               1. Pitch (the x component) is the rotation about the node's x-axis (in radians)
		               2. Yaw   (the y component) is the rotation about the node's y-axis (in radians)
		               3. Roll  (the z component) is the rotation about the node's z-axis (in radians)
		            ARKit applies these rotations in the reverse order of the components:
		               1. first roll
		               2. then yaw
		               3. then pitch
		 */

		public Vector3 eulerAngles;

		public ARTrackingQuality trackingQuality;

		/**
		 The camera intrinsics.
		 @discussion The matrix has the following contents:
		 fx 0   px
		 0  fy  py
		 0  0   1
		 fx and fy are the focal length in pixels.
		 px and py are the coordinates of the principal point in pixels.
		 The origin is at the center of the upper-left pixel.
		 */

		public Vector3 intrinsics_row1;
		public Vector3 intrinsics_row2;
		public Vector3 intrinsics_row3;

		public ARSize imageResolution;
	
	}
```

### ARErrorCode

**Public**

```
	public enum ARErrorCode : long
	{
		/** Unsupported session configuration. */
		ARErrorCodeUnsupportedConfiguration   = 100,

		/** A sensor required to run the session is not available. */
		ARErrorCodeSensorUnavailable          = 101,

		/** A sensor failed to provide the required input. */
		ARErrorCodeSensorFailed               = 102,

		/** World tracking has encountered a fatal error. */
		ARErrorCodeWorldTrackingFailed        = 200,

	}

```

### ARFaceAnchor.cs

**Public**

```
	public static class ARBlendShapeLocation
	{
		 public const string  BrowDownLeft        =   "browDown_L";
	 	 public const string  BrowDownRight       =   "browDown_R";
		 public const string  BrowInnerUp         =   "browInnerUp";
		 public const string  BrowOuterUpLeft     =   "browOuterUp_L";
		 public const string  BrowOuterUpRight    =   "browOuterUp_R";
		 public const string  CheekPuff           =   "cheekPuff";
		 public const string  CheekSquintLeft     =   "cheekSquint_L";
		 public const string  CheekSquintRight    =   "cheekSquint_R";
		 public const string  EyeBlinkLeft        =   "eyeBlink_L";
		 public const string  EyeBlinkRight       =   "eyeBlink_R";
		 public const string  EyeLookDownLeft     =   "eyeLookDown_L";
		 public const string  EyeLookDownRight    =   "eyeLookDown_R";
		 public const string  EyeLookInLeft       =   "eyeLookIn_L";
		 public const string  EyeLookInRight      =   "eyeLookIn_R";
		 public const string  EyeLookOutLeft      =   "eyeLookOut_L";
		 public const string  EyeLookOutRight     =   "eyeLookOut_R";
		 public const string  EyeLookUpLeft       =   "eyeLookUp_L";
		 public const string  EyeLookUpRight      =   "eyeLookUp_R";
		 public const string  EyeSquintLeft       =   "eyeSquint_L";
		 public const string  EyeSquintRight      =   "eyeSquint_R";
		 public const string  EyeWideLeft         =   "eyeWide_L";
		 public const string  EyeWideRight        =   "eyeWide_R";
		 public const string  JawForward          =   "jawForward";
		 public const string  JawLeft             =   "jawLeft";
		 public const string  JawOpen             =   "jawOpen";
		 public const string  JawRight            =   "jawRight";
		 public const string  MouthClose          =   "mouthClose";
		 public const string  MouthDimpleLeft     =   "mouthDimple_L";
		 public const string  MouthDimpleRight    =   "mouthDimple_R";
		 public const string  MouthFrownLeft      =   "mouthFrown_L";
		 public const string  MouthFrownRight     =   "mouthFrown_R";
		 public const string  MouthFunnel         =   "mouthFunnel";
		 public const string  MouthLeft           =   "mouthLeft";
		 public const string  MouthLowerDownLeft  =   "mouthLowerDown_L";
		 public const string  MouthLowerDownRight =   "mouthLowerDown_R";
		 public const string  MouthPressLeft      =   "mouthPress_L";
		 public const string  MouthPressRight     =   "mouthPress_R";
		 public const string  MouthPucker         =   "mouthPucker";
		 public const string  MouthRight          =   "mouthRight";
		 public const string  MouthRollLower      =   "mouthRollLower";
		 public const string  MouthRollUpper      =   "mouthRollUpper";
		 public const string  MouthShrugLower     =   "mouthShrugLower";
		 public const string  MouthShrugUpper     =   "mouthShrugUpper";
		 public const string  MouthSmileLeft      =   "mouthSmile_L";
		 public const string  MouthSmileRight     =   "mouthSmile_R";
		 public const string  MouthStretchLeft    =   "mouthStretch_L";
		 public const string  MouthStretchRight   =   "mouthStretch_R";
		 public const string  MouthUpperUpLeft    =   "mouthUpperUp_L";
		 public const string  MouthUpperUpRight   =   "mouthUpperUp_R";
		 public const string  NoseSneerLeft       =   "noseSneer_L";
		 public const string  NoseSneerRight      =   "noseSneer_R";
	}

	public struct UnityARFaceGeometry
	{
		public int vertexCount;
		public IntPtr vertices;
		public int textureCoordinateCount;
		public IntPtr textureCoordinates;
		public int triangleCount;
		public IntPtr triangleIndices;

	}

	public struct UnityARFaceAnchorData 
	{
		public IntPtr ptrIdentifier;

		/**
 		The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
		 */
		public UnityARMatrix4x4 transform;

		public string identifierStr { get { } }

		public UnityARFaceGeometry faceGeometry;
		public IntPtr blendShapes;

	};

	public class ARFaceGeometry
	{
		private UnityARFaceGeometry uFaceGeometry;

		public ARFaceGeometry (UnityARFaceGeometry ufg);
		public int vertexCount { get { } }
		public int triangleCount {  get  { } }
		public int textureCoordinateCount { get { } }

		public Vector3 [] vertices { get { } }

		public Vector2 [] textureCoordinates { get { } }

		public int [] triangleIndices { get { } }

		Vector3 [] MarshalVertices(IntPtr ptrFloatArray, int vertCount);

		int [] MarshalIndices(IntPtr ptrIndices, int triCount);

		Vector2 [] MarshalTexCoords(IntPtr ptrTexCoords, int texCoordCount);

	}

	public class ARFaceAnchor 
	{
		private UnityARFaceAnchorData faceAnchorData;
		private static Dictionary<string, float> blendshapesDictionary;

		public ARFaceAnchor (UnityARFaceAnchorData ufad);
		
		public string identifierStr { get { } }

		public Matrix4x4 transform { get { } }

		public ARFaceGeometry faceGeometry { get { } }

		public Dictionary<string, float> blendShapes { get { } }

		delegate void DictionaryVisitorHandler(IntPtr keyPtr, float value);

		[DllImport("__Internal")]
		private static extern void GetBlendShapesInfo(IntPtr ptrDic, DictionaryVisitorHandler handler);

		Dictionary<string, float> GetBlendShapesFromNative(IntPtr blendShapesPtr);

		[MonoPInvokeCallback(typeof(DictionaryVisitorHandler))]
		static void AddElementToManagedDictionary(IntPtr keyPtr, float value);
	}
```

### ARFrame

**Public**

```
public struct ARFrame
{
	/**
	 A timestamp identifying the frame.
	 */
	public double timestamp;

	/**
 	The frame's captured image.
 	*/
	public IntPtr capturedImage;

	/**
	 The camera used to capture the frame's image.
	 @discussion The camera provides the device's position and orientation as well as camera parameters.
	 */
	public ARCamera camera;

	/**
 	A list of anchors in the scene.
 	*/
	//List<ARAnchor> anchors;

	/**
 	A light estimate representing the light in the scene.
 	@discussion Returns nil if there is no light estimation.
	 */
	ARLightEstimate lightEstimate;

}
```

### ARHitTestResult

**Public**

```
public struct ARHitTestResult
{
	/**
	 The type of the hit-test result.
	*/
	public ARHitTestResultType type;

	/**
 	The distance from the camera to the intersection in meters.
	*/
	public double distance;

	/**
 	The transformation matrix that defines the intersection's rotation, translation and scale
 	relative to the anchor or nearest feature point.
 	*/
	public Matrix4x4 localTransform;

	/**
 	The transformation matrix that defines the intersection's rotation, translation and scale
 	relative to the world.
 	*/
	public Matrix4x4 worldTransform;

	/**
 	The anchor that the hit-test intersected.
 	*/
	public string anchorIdentifier;

	/**
	True if the test represents a valid hit test. Data is undefined otherwise.
	*/
	public bool isValid;
}
```

### ARHitTestResultType.cs

**Public**

```
[Flags]
public enum ARHitTestResultType : long
{
	/** Result type from intersecting the nearest feature point. */
	ARHitTestResultTypeFeaturePoint     = (1 << 0),

	/** Result type from detecting and intersecting a new horizontal plane. */
	ARHitTestResultTypeHorizontalPlane  = (1 << 1),

	/** Result type from detecting and intersecting a new vertical plane. */
	ARHitTestResultTypeVerticalPlane    = (1 << 2),

	/** Result type from intersecting with an existing plane anchor. */
	ARHitTestResultTypeExistingPlane    = (1 << 3),

	/** Result type from intersecting with an existing plane anchor, taking into account the plane's extent. */
	ARHitTestResultTypeExistingPlaneUsingExtent  = ( 1 << 4)
}
```

### ARLightEstimate.cs

**Public**

```
    public struct ARLightEstimate
    {
		public float ambientIntensity;
    }

    [Serializable]
    public struct UnityARLightEstimate
    {
		public float ambientIntensity;
		public float ambientColorTemperature;

		public UnityARLightEstimate(float intensity, float temperature);
    };

    public struct MarshalDirectionalLightEstimate
    {
		public Vector4 primaryDirAndIntensity;
		public IntPtr  sphericalHarmonicCoefficientsPtr;

		public float [] SphericalHarmonicCoefficients { get { } } 

		float [] MarshalCoefficients(IntPtr ptrFloats);

		void RotateForUnity(ref float[] shc, int startIndex);
    }

    public class UnityARDirectionalLightEstimate
    {
		public Vector3 primaryLightDirection;
		public float primaryLightIntensity;
		public float [] sphericalHarmonicsCoefficients;

		public UnityARDirectionalLightEstimate (float [] SHC, Vector3 direction, float intensity);
    };

    public enum LightDataType
    {
		LightEstimate,
		DirectionalLightEstimate
    }

    public struct UnityMarshalLightData
    {
		public LightDataType arLightingType;
		public UnityARLightEstimate arLightEstimate;
		public MarshalDirectionalLightEstimate arDirectonalLightEstimate;

		public UnityMarshalLightData(LightDataType ldt, UnityARLightEstimate ule, MarshalDirectionalLightEstimate mdle);

		public static implicit operator UnityARLightData(UnityMarshalLightData rValue);
    }

    public struct UnityARLightData
    {
		public LightDataType arLightingType;
		public UnityARLightEstimate arLightEstimate;
		public UnityARDirectionalLightEstimate arDirectonalLightEstimate;

		public UnityARLightData(LightDataType ldt, UnityARLightEstimate ule, UnityARDirectionalLightEstimate udle);
    }
```

### ARPlaneAnchor.cs

**Public**

```
	public struct ARPlaneAnchor 
	{
		public string identifier;

		/**
 		The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
		 */
		public Matrix4x4 transform;

		/**
		 The alignment of the plane.
		 */
		public ARPlaneAnchorAlignment alignment;

		/**
		The center of the plane in the anchor’s coordinate space.
		 */
		public Vector3 center;

		/**
		The extent of the plane in the anchor’s coordinate space.
		 */
		public Vector3 extent;
	}
```

### ARPlaneAnchorAlighment.cs

**Public**

```
	public enum ARPlaneAnchorAlignment : long
	{
		/** A plane that is horizontal with respect to gravity. */
		ARPlaneAnchorAlignmentHorizontal
	}
```

### ARPoint.cs

**Public**

```
	public struct ARPoint
	{
		public double x;
		public double y;
	}
```

### ARRect.cs

**Public**

```
	public struct ARRect
	{
		public ARPoint origin;
		public ARSize  size;
	}
```

### ARSize.cs

**Public**

```
	public struct ARSize
	{
		public double width;
		public double height;
	}
```

### ARTextureHandles.cs

**Public**

```
	public struct ARTextureHandles
	{
		// Native (Metal) texture handles for the device camera buffer
		public IntPtr textureY;
		public IntPtr textureCbCr;
	}
```

### ARTrackingQuality.cs

**Public**

```
public enum ARTrackingQuality : long
{
	/** The tracking quality is not available. */
	ARTrackingQualityNotAvailable,

	/** The tracking quality is limited, relying only on the device's motion. */
	ARTrackingQualityLimited,

	/** The tracking quality is poor. */
	ARTrackingQualityPoor,

	/** The tracking quality is good. */
	ARTrackingQualityGood

}
```

### ARTrackingState.cs

**Public**

```
public enum ARTrackingState
{
	/** Tracking is not available. */
	ARTrackingStateNotAvailable,

	/** Tracking is limited. See tracking reason for details. */
	ARTrackingStateLimited,

	/** Tracking is Normal. */
	ARTrackingStateNormal,
}
```

### ARTrackingStateReason.cs

**Public**

```
public enum ARTrackingStateReason
{
	/** Tracking is not limited. */
	ARTrackingStateReasonNone,

	/** Tracking is limited due to initialization in progress. */
	ARTrackingStateReasonInitializing,

	/** Tracking is limited due to a excessive motion of the camera. */
	ARTrackingStateReasonExcessiveMotion,

	/** Tracking is limited due to a lack of features visible to the camera. */
	ARTrackingStateReasonInsufficientFeatures,
}
```

### ARUserAnchor.cs

**Public**

```
public struct ARUserAnchor 
{
	public string identifier;

	/**
	The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
	*/
	public Matrix4x4 transform;
}
```

### UnityARSessionNativeInterface.cs

**Public**

```
    /// <summary>
    /// A struct that allows us go from native Matrix4x4 to managed
    /// </summary>
    public struct UnityARMatrix4x4
    {
        public Vector4 column0;
        public Vector4 column1;
        public Vector4 column2;
        public Vector4 column3;

        public UnityARMatrix4x4(Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3);
    };

    [Serializable]
    public struct UnityVideoParams
    {
        public int yWidth;
        public int yHeight;
        public int screenOrientation;
        public float texCoordScale;
        public IntPtr cvPixelBufferPtr;
    };

    public struct UnityARCamera
    {
        public UnityARMatrix4x4 worldTransform;
        public UnityARMatrix4x4 projectionMatrix;
        public ARTrackingState trackingState;
        public ARTrackingStateReason trackingReason;
        public UnityVideoParams videoParams;
        public UnityARLightData lightData;
        public UnityARMatrix4x4 displayTransform;
        public Vector3[] pointCloudData;

        public UnityARCamera(UnityARMatrix4x4 wt, UnityARMatrix4x4 pm, ARTrackingState ats, ARTrackingStateReason atsr, UnityVideoParams uvp, UnityARLightData lightDat, UnityARMatrix4x4 dt, Vector3[] pointCloud);
    };

    public struct UnityARAnchorData {
        public IntPtr ptrIdentifier;

        /**
        The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
        */
        public UnityARMatrix4x4 transform;

        /**
        The alignment of the plane.
        */
        public ARPlaneAnchorAlignment alignment;

        /**
        The center of the plane in the anchor’s coordinate space.
        */
        public Vector4 center;

        /**
        The extent of the plane in the anchor’s coordinate space.
        */
        public Vector4 extent;

        public string identifierStr { get { } }

        public static UnityARAnchorData UnityARAnchorDataFromGameObject(GameObject go);
    };

    public struct UnityARUserAnchorData 
    {
        public IntPtr ptrIdentifier;

        /**
        The transformation matrix that defines the anchor's rotation, translation and scale in world coordinates.
         */
        public UnityARMatrix4x4 transform;

        public string identifierStr { get { } }

        public static UnityARUserAnchorData UnityARUserAnchorDataFromGameObject(GameObject go);
    };

    public struct UnityARHitTestResult
    {
        /**
         The type of the hit-test result.
         */
        public ARHitTestResultType type;

        /**
        The distance from the camera to the intersection in meters.
        */
        public double distance;

        /**
        The transformation matrix that defines the intersection's rotation, translation and scale
        relative to the anchor or nearest feature point.
        */
        public Matrix4x4 localTransform;

        /**
        The transformation matrix that defines the intersection's rotation, translation and scale
        relative to the world.
        */
        public Matrix4x4 worldTransform;

        /**
        The anchor that the hit-test intersected.
        */
        public IntPtr anchor;

        /**
        True if the test represents a valid hit test. Data is undefined otherwise.
        */
        public bool isValid;

    };

    public enum UnityARAlignment
    {
        UnityARAlignmentGravity,
        UnityARAlignmentGravityAndHeading,
        UnityARAlignmentCamera
    }

    public enum UnityARPlaneDetection
    {
        None = 0,
        Horizontal = (1 << 0)
    }

    public struct ARKitSessionConfiguration
    {
        public UnityARAlignment alignment; 
        public bool getPointCloudData;
        public bool enableLightEstimation;
        public bool IsSupported { get { } private set {} }

        public ARKitSessionConfiguration(UnityARAlignment alignment = UnityARAlignment.UnityARAlignmentGravity,
                                            bool getPointCloudData = false, 
                                            bool enableLightEstimation = false);
        
        [DllImport("__Internal")]
        private static extern bool IsARKitSessionConfigurationSupported();
    }

    public struct ARKitWorldTrackingSessionConfiguration
    {
        public UnityARAlignment alignment; 
        public UnityARPlaneDetection planeDetection;
        public bool getPointCloudData;
        public bool enableLightEstimation;
        public bool IsSupported { get { } private set { } }

        public ARKitWorldTrackingSessionConfiguration(UnityARAlignment alignment = UnityARAlignment.UnityARAlignmentGravity,
	            UnityARPlaneDetection planeDetection = UnityARPlaneDetection.Horizontal,
        bool getPointCloudData = false, 
        bool enableLightEstimation = false);

        [DllImport("__Internal")]
        private static extern bool IsARKitWorldTrackingSessionConfigurationSupported();
    }

	public struct ARKitFaceTrackingConfiguration
	{
		public UnityARAlignment alignment; 
		public bool enableLightEstimation;
		public bool IsSupported { get { } private set {} }

		public ARKitFaceTrackingConfiguration(UnityARAlignment alignment = UnityARAlignment.UnityARAlignmentGravity,
			bool enableLightEstimation = false);

#if UNITY_EDITOR
		private bool IsARKitFaceTrackingConfigurationSupported();
#else
		[DllImport("__Internal")]
		private static extern bool IsARKitFaceTrackingConfigurationSupported();
#endif

	}

	public enum UnityARSessionRunOption {
		/** The session will reset tracking. */
		ARSessionRunOptionResetTracking           = (1 << 0),

		/** The session will remove existing anchors. */
		ARSessionRunOptionRemoveExistingAnchors   = (1 << 1)
	}

	public class UnityARSessionNativeInterface {

		// Plane Anchors
		public delegate void ARFrameUpdate(UnityARCamera camera);
		public static event ARFrameUpdate ARFrameUpdatedEvent;

		public delegate void ARAnchorAdded(ARPlaneAnchor anchorData);
		public static event ARAnchorAdded ARAnchorAddedEvent;

		public delegate void ARAnchorUpdated(ARPlaneAnchor anchorData);
		public static event ARAnchorUpdated ARAnchorUpdatedEvent;

		public delegate void ARAnchorRemoved(ARPlaneAnchor anchorData);
		public static event ARAnchorRemoved ARAnchorRemovedEvent;

		// User Anchors
		public delegate void ARUserAnchorAdded(ARUserAnchor anchorData);
		public static event ARUserAnchorAdded ARUserAnchorAddedEvent;

		public delegate void ARUserAnchorUpdated(ARUserAnchor anchorData);
		public static event ARUserAnchorUpdated ARUserAnchorUpdatedEvent;

		public delegate void ARUserAnchorRemoved(ARUserAnchor anchorData);
		public static event ARUserAnchorRemoved ARUserAnchorRemovedEvent;

		// Face Anchors
		public delegate void ARFaceAnchorAdded(ARFaceAnchor anchorData);
		public static event ARFaceAnchorAdded ARFaceAnchorAddedEvent;

		public delegate void ARFaceAnchorUpdated(ARFaceAnchor anchorData);
		public static event ARFaceAnchorUpdated ARFaceAnchorUpdatedEvent;

		public delegate void ARFaceAnchorRemoved(ARFaceAnchor anchorData);
		public static event ARFaceAnchorRemoved ARFaceAnchorRemovedEvent;

		public delegate void ARSessionFailed(string error);
		public static event ARSessionFailed ARSessionFailedEvent;

		public delegate void ARSessionCallback();
		public static event ARSessionCallback ARSessionInterruptedEvent;
		public static event ARSessionCallback ARSessioninterruptionEndedEvent;
		public delegate void ARSessionTrackingChanged(UnityARCamera camera);
		public static event ARSessionTrackingChanged ARSessionTrackingChangedEvent;

		delegate void internal_ARFrameUpdate(internal_UnityARCamera camera);
		public delegate void internal_ARAnchorAdded(UnityARAnchorData anchorData);
		public delegate void internal_ARAnchorUpdated(UnityARAnchorData anchorData);
		public delegate void internal_ARAnchorRemoved(UnityARAnchorData anchorData);
		public delegate void internal_ARUserAnchorAdded(UnityARUserAnchorData anchorData);
		public delegate void internal_ARUserAnchorUpdated(UnityARUserAnchorData anchorData);
		public delegate void internal_ARUserAnchorRemoved(UnityARUserAnchorData anchorData);
		public delegate void internal_ARFaceAnchorAdded(UnityARFaceAnchorData anchorData);
		public delegate void internal_ARFaceAnchorUpdated(UnityARFaceAnchorData anchorData);
		public delegate void internal_ARFaceAnchorRemoved(UnityARFaceAnchorData anchorData);
		delegate void internal_ARSessionTrackingChanged(internal_UnityARCamera camera);

		private static UnityARCamera s_Camera;
		
		[DllImport("__Internal")]
		private static extern IntPtr unity_CreateNativeARSession();

		[DllImport("__Internal")]
		private static extern void session_SetSessionCallbacks(IntPtr nativeSession, internal_ARFrameUpdate frameCallback,
                                            ARSessionFailed sessionFailed,
                                            ARSessionCallback sessionInterrupted,
                                            ARSessionCallback sessionInterruptionEnded,
                                            internal_ARSessionTrackingChanged trackingChanged);

		[DllImport("__Internal")]
		private static extern void session_SetPlaneAnchorCallbacks(IntPtr nativeSession, internal_ARAnchorAdded anchorAddedCallback, 
                                            internal_ARAnchorUpdated anchorUpdatedCallback, 
                                            internal_ARAnchorRemoved anchorRemovedCallback);

		[DllImport("__Internal")]
		private static extern void session_SetUserAnchorCallbacks(IntPtr nativeSession, internal_ARUserAnchorAdded userAnchorAddedCallback, 
                                            internal_ARUserAnchorUpdated userAnchorUpdatedCallback, 
                                            internal_ARUserAnchorRemoved userAnchorRemovedCallback);

		[DllImport("__Internal")]
		private static extern void session_SetFaceAnchorCallbacks(IntPtr nativeSession, internal_ARFaceAnchorAdded faceAnchorAddedCallback, 
                                            internal_ARFaceAnchorUpdated faceAnchorUpdatedCallback, 
                                            internal_ARFaceAnchorRemoved faceAnchorRemovedCallback);

		[DllImport("__Internal")]
		private static extern void StartWorldTrackingSession(IntPtr nativeSession, ARKitWorldTrackingSessionConfiguration configuration);

		[DllImport("__Internal")]
		private static extern void StartWorldTrackingSessionWithOptions(IntPtr nativeSession, ARKitWorldTrackingSessionConfiguration configuration, UnityARSessionRunOption runOptions);

		[DllImport("__Internal")]
		private static extern void StartSession(IntPtr nativeSession, ARKitSessionConfiguration configuration);

		[DllImport("__Internal")]
		private static extern void StartSessionWithOptions(IntPtr nativeSession, ARKitSessionConfiguration configuration, UnityARSessionRunOption runOptions);

		[DllImport("__Internal")]
		private static extern void StartFaceTrackingSession(IntPtr nativeSession, ARKitFaceTrackingConfiguration configuration);

		[DllImport("__Internal")]
		private static extern void StartFaceTrackingSessionWithOptions(IntPtr nativeSession, ARKitFaceTrackingConfiguration configuration, UnityARSessionRunOption runOptions);

		[DllImport("__Internal")]
		private static extern void PauseSession(IntPtr nativeSession);

		[DllImport("__Internal")]
		private static extern int HitTest(IntPtr nativeSession, ARPoint point, ARHitTestResultType types);

		[DllImport("__Internal")]
		private static extern UnityARHitTestResult GetLastHitTestResult(int index);

		[DllImport("__Internal")]
		private static extern ARTextureHandles GetVideoTextureHandles();

		[DllImport("__Internal")]
		private static extern float GetAmbientIntensity();

		[DllImport("__Internal")]
		private static extern int GetTrackingQuality();

		[DllImport("__Internal")]
		private static extern bool GetARPointCloud (ref IntPtr verts, ref uint vertLength);

		[DllImport("__Internal")]
		private static extern void SetCameraNearFar (float nearZ, float farZ);

		[DllImport("__Internal")]
		private static extern void CapturePixelData (int enable, IntPtr  pYPixelBytes, IntPtr pUVPixelBytes);

		[DllImport("__Internal")]
		private static extern UnityARUserAnchorData SessionAddUserAnchor (IntPtr nativeSession, UnityARUserAnchorData anchorData);

		[DllImport("__Internal")]
		private static extern void SessionRemoveUserAnchor (IntPtr nativeSession, [MarshalAs(UnmanagedType.LPStr)] string anchorIdentifier);

		public UnityARSessionNativeInterface();

		static UnityARSessionNativeInterface s_UnityARSessionNativeInterface = null;

		public static UnityARSessionNativeInterface GetARSessionNativeInterface();

#if UNITY_EDITOR
		public static void SetStaticCamera(UnityARCamera scamera);
		public static void RunFrameUpdateCallbacks();
		public static void RunAddAnchorCallbacks(ARPlaneAnchor arPlaneAnchor);
		public static void RunUpdateAnchorCallbacks(ARPlaneAnchor arPlaneAnchor);
		public static void RunRemoveAnchorCallbacks(ARPlaneAnchor arPlaneAnchor);

#endif

		public Matrix4x4 GetCameraPose();
		public Matrix4x4 GetCameraProjection();
		public void SetCameraClipPlanes(float nearZ, float farZ);
		public void SetCapturePixelData(bool enable, IntPtr pYByteArray, IntPtr pUVByteArray);

		[MonoPInvokeCallback(typeof(internal_ARFrameUpdate))]
		static void _frame_update(internal_UnityARCamera camera);

		[MonoPInvokeCallback(typeof(internal_ARSessionTrackingChanged))]
		static void _ar_tracking_changed(internal_UnityARCamera camera);


		static void UpdatePointCloudData(ref UnityARCamera camera);

		static ARPlaneAnchor GetPlaneAnchorFromAnchorData(UnityARAnchorData anchor);

		static ARUserAnchor GetUserAnchorFromAnchorData(UnityARUserAnchorData anchor);

		static ARHitTestResult GetHitTestResultFromResultData(UnityARHitTestResult resultData);

#region Plane Anchors
		[MonoPInvokeCallback(typeof(internal_ARAnchorAdded))]
		static void _anchor_added(UnityARAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARAnchorUpdated))]
		static void _anchor_updated(UnityARAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARAnchorRemoved))]
		static void _anchor_removed(UnityARAnchorData anchor);
#endregion

#region User Anchors
		[MonoPInvokeCallback(typeof(internal_ARUserAnchorAdded))]
		static void _user_anchor_added(UnityARUserAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARUserAnchorUpdated))]
		static void _user_anchor_updated(UnityARUserAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARUserAnchorRemoved))]
		static void _user_anchor_removed(UnityARUserAnchorData anchor);
#endregion

#region Face Anchors
		[MonoPInvokeCallback(typeof(internal_ARFaceAnchorAdded))]
		static void _face_anchor_added(UnityARFaceAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARFaceAnchorUpdated))]
		static void _face_anchor_updated(UnityARFaceAnchorData anchor);

		[MonoPInvokeCallback(typeof(internal_ARFaceAnchorRemoved))]
		static void _face_anchor_removed(UnityARFaceAnchorData anchor);
#endregion

		[MonoPInvokeCallback(typeof(ARSessionFailed))]
		static void _ar_session_failed(string error);

		[MonoPInvokeCallback(typeof(ARSessionCallback))]
		static void _ar_session_interrupted();

		[MonoPInvokeCallback(typeof(ARSessionCallback))]
		static void _ar_session_interruption_ended();

		public void RunWithConfigAndOptions(ARKitWorldTrackingSessionConfiguration config, UnityARSessionRunOption runOptions);

		public void RunWithConfig(ARKitWorldTrackingSessionConfiguration config);

		public void Run();

		public void RunWithConfigAndOptions(ARKitSessionConfiguration config, UnityARSessionRunOption runOptions);

		public void RunWithConfig(ARKitSessionConfiguration config);

		public void RunWithConfigAndOptions(ARKitFaceTrackingConfiguration config, UnityARSessionRunOption runOptions);
		public void RunWithConfig(ARKitFaceTrackingConfiguration config);
		public void Pause;

		public List<ARHitTestResult> HitTest(ARPoint point, ARHitTestResultType types);
		public ARTextureHandles GetARVideoTextureHandles();

		[Obsolete("Hook ARFrameUpdatedEvent instead and get UnityARCamera.ambientIntensity")]
		public float GetARAmbientIntensity();

		[Obsolete("Hook ARFrameUpdatedEvent instead and get UnityARCamera.trackingState")]
		public int GetARTrackingQuality();

		public UnityARUserAnchorData AddUserAnchor(UnityARUserAnchorData anchorData);
		public UnityARUserAnchorData AddUserAnchorFromGameObject(GameObject go);
		public void RemoveUserAnchor(string anchorIdentifier);
    }
```

**Private**

```
    struct internal_UnityARCamera
    {
        public UnityARMatrix4x4 worldTransform;
        public UnityARMatrix4x4 projectionMatrix;
        public ARTrackingState trackingState;
        public ARTrackingStateReason trackingReason;
        public UnityVideoParams videoParams;
        public UnityMarshalLightData lightData;
        public UnityARMatrix4x4 displayTransform;
        public uint getPointCloudData;
    };

#if !UNITY_EDITOR
    private IntPtr m_NativeARSession;
#endif
```

# おわりに

本記事では、Unity ARKit Plugin のクラスを紹介していきました。

今回 [Doxygen](http://www.doxygen.jp/) などのドキュメント自動生成ツールは特に使わず、あえて手作業でまとめていったのですが、
リファレンスをまとめるのに半日程度の時間を要しました。
 [Unity ARKit Plugin](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-arkit-plugin-92515) はそこまで大きな構成のアセットではありませんが、
改めてスクリプト、ツールによる省力化のありがたみを感じます。

年末年始は本記事とアセットストアを眺めながら、ちょっとした AR コンテンツを作りたいなと思っています。
[KLab Advent Calendar 2017](https://qiita.com/advent-calendar/2017/klab) 24日目は yasu0000 さんです。お楽しみに。