はじめに
※ Unity 向けの SDK についての記事です。
先日、 ARCore の ver1.9がリリースされました。今回は、2019年に入ってから ver1.9までのバージョンアップで追加された新機能や、変更点について調べてみました。
ARCore とは
これまでギャップロでは、iOS 向けの AR 開発フレームワークである ARKit について何度か記事にしてきました。
ARCore は、Android 向けの AR 開発フレームワークになります。
ARCore の初期設定
ARCore についての記事は今回が初めてなので、 Unity に ARCore を導入する方法から解説していきます。
1. Unity プロジェクトを作成
Unity 2017.3.9f2以降のバージョンでプロジェクトを作成します。(※今回は Unity 2019.1.0f2を使用しました。)
2. Android 向けに Switch Platform
ARCore は基本 Android デバイス向けなのでプラットフォームを切り替えます。

3. PackageManager から必要なパッケージをインストール
Window -> Package Manager -> Multiplayer HLAPIとXR Legacy Input Helpersをインストールします。

4. ARCore SDK を Unity にインストール
ARCore の UnityPackage をダウンロード
ARCore の公式サイトからarcore-unity-sdk-x.x.x.unitypackageをダウンロードします。

Unity にインポート
Unity エディタの Assets -> Import Package -> Custom Package から今ダウンロードしてきたarcore-unity-sdk-x.x.x.unitypackageをインポートします。

5. Project Settings を設定
Player -> XR Settings -> ARCore Supportedにチェック

警告が出るのでPlayer -> Other Settings -> Rendering -> Graphics APIs -> Vulkanを取り除く

Player -> Other Settings -> Rendering -> Multithreaded Renderingのチェックを外す

Player -> Other Settings -> Identification -> Minimum API Levelを7.0に変更する

以上で ARCore の設定が完了しました。
新機能・変更点
2019年に入ってから ver1.9までの主な新機能、変更点は以下の3つになります。
- 正面カメラ(Front Facing Camera)
- 顔認識(Augmented Faces)
- マーカー認識(Augmented Images)
正面カメラ(Front Facing Camera)

ARCore1.7から正面カメラ(内カメ)が選択可能になりました。
AR Core SessionコンポーネントのDevice Camera DirectionをFront Facingにすると正面カメラモードに切り替えることができます。
注意点として、正面カメラ使用中は、モーショントラッキング、全ての種類のアンカー、マーカー認識、平面検出が使用できなくなります。
顔認識(Augmented Faces)
認識範囲をわかりやすくするためにマテリアルを変更してあります。
- 正面カメラを使用できるようになったことで、顔認証の機能も同時に追加されました。
- 新たに実装されたAugmentedFaceクラス(Trackable の派生クラス)を通して検出した顔の情報を利用することができます。 このクラスにアクセスすることで、検出した顔の3 D メッシュとメッシュの中央の座標と向きを取得することができます。
- また、顔パーツの位置も取得することができます。 enum AugmentedFaceRegionで定義されている、鼻、右額、左額の3点を取得できます。 Sphere のある位置が定義されている3点です。サンプルプロジェクトのような、動物の耳や鼻をかぶせる様なアプリが作りやすくなっています。 反面、 Augmented Faces のデモ映像の、目と口を除いた顔全体を金色にコーティングする様なアプリは、少し工夫が必要になりそうです。
- 上下左右に動かしても綺麗に認識してくれました。
それでは Augmented Faces のサンプルシーンを見ていきましょう。
Assets/GoogleARCore/Examples/AugmentedFaces/Scenes/AugmentedFaces.unity
ARCore Device

Assets/GoogleARCore/Prefabs/ARCore Device.prefab
AR 用のカメラです。 ARCore を利用したシーンを作る時は、元からあるカメラの代わりにこちらのカメラを使います。
上記の正面カメラの設定や使用する機能の設定もこのオブジェクトから指定できます。
AugmentedFaceExampleController

Augmented Face Example Controllerコンポーネント
このサンプルでは、検出した顔の有無に合わせて、Face Attachmentに設定した GameObject のアクティブ/非アクティブを切り替えています。
サンプル用のスクリプトですが、アプリの終了処理やパーミッションなどの処理も含まれているので、そのまま自分のプロジェクトに流用しても良いかもしれません。
FaceAttachment

AR Core Augmented Face Mesh Filterコンポーネント
このサンプルでは、検出した顔全体に沿うようにメッシュを作成しています。
下記コードはAssets/GoogleARCore/Exsamples/AugmentedFaces/Scripts/ARCoreAugmentedFaceMeshFilter.csにコメントを追記したものです。
/// <summary>
/// The Unity Awake() method.
/// </summary>
public void Awake()
{
m_Mesh = new Mesh();
GetComponent<MeshFilter>().mesh = m_Mesh;
m_AugmentedFaceList = new List<AugmentedFace>();
}
/// <summary>
/// The Unity Update() method.
/// </summary>
public void Update()
{
if (AutoBind && m_AugmentedFace == null)
{
m_AugmentedFaceList.Clear();
// AugmentedFace から検出した顔のリストを取得する
Session.GetTrackables<AugmentedFace>(m_AugmentedFaceList, TrackableQueryFilter.All);
// 顔を1つ以上取得できている場合、先頭要素を取り出す
if (m_AugmentedFaceList.Count != 0)
{
m_AugmentedFace = m_AugmentedFaceList[0];
}
}
// 顔を1つも取得していなければ終了
if (m_AugmentedFace == null)
{
return;
}
// メッシュの親オブジェクトの位置と向きを顔に合わせる
transform.position = m_AugmentedFace.CenterPose.position;
transform.rotation = m_AugmentedFace.CenterPose.rotation;
_UpdateMesh();
}
/// <summary>
/// Update mesh with a face mesh vertices, texture coordinates and indices.
/// </summary>
private void _UpdateMesh()
{
// メッシュの情報をそれぞれ取得する
m_AugmentedFace.GetVertices(m_MeshVertices);
m_AugmentedFace.GetNormals(m_MeshNormals);
// 初回のみ
if (!m_MeshInitialized)
{
m_AugmentedFace.GetTextureCoordinates(m_MeshUVs);
m_AugmentedFace.GetTriangleIndices(m_MeshIndices);
// Only update mesh indices and uvs once as they don't change every frame.
m_MeshInitialized = true;
}
// 取得した情報をメッシュに設定する
m_Mesh.Clear();
m_Mesh.SetVertices(m_MeshVertices);
m_Mesh.SetNormals(m_MeshNormals);
m_Mesh.SetTriangles(m_MeshIndices, 0);
m_Mesh.SetUVs(0, m_MeshUVs);
m_Mesh.RecalculateBounds();
}
fox_sample
このサンプルでは、fox_sample/root以下の Rig を AugmentedFace から取得した顔パーツの座標を元に配置しています。
Pose pose = AugmentedFace.GetRegionPose(AugmentedFaceRegion region);とすることで引数の region で指定したパーツの Pose を取得することができます。
おまけ
公式のリファレンスで顔認識は「正面カメラのみ」と書かれていますが、デプスセンサーなしで出来ているのなら「背面カメラ」でも実は使えるんじゃ、ということで一応試してみました。

アプリ起動の段階で警告が出て終了してしまいました。
マーカー認識(Augmented Images)
ver1.9から移動するマーカーを滑らかに追跡できるようになりました。
ver1.8
ver1.9
ver1.8と比較すると、現実の動きに対してやや遅れて画面が動いているようです。※今後検証の必要があります。
- Galaxy S8(Android バージョン 8.0)、 Pixel 3a XL(Android バージョン 9.0)で確認。
普通に使う分には気にならない程度ですが、動くマーカーを狙うゲームなどのタイミングが重要なアプリを作る時などにはネックになってきそうです。
その他の変更点
- ver1.8から、すでに ARCore が有効になっているプロジェクトを開いた時、または、 SDK をインポートした時に Google に SDK の使用状況が送信されるようになりました。
Preferences -> Google ARCore -> Enable Google ARCore SDK Analyticsをオフにすることで無効化することができます。

この設定は、1つのプロジェクトで変更すると、同じコンピュータ上の ver1.8以降の全てのプロジェクトに反映されるようです。
- ver1.8から、 ARCoreSession コンポーネントの無効/有効で ARCore を一時停止/再開できるようになりました。
- ver1.9から、 Augmented Image で、ポスターなどの動かない画像に対して、追跡の安定性を高めるためにグローバルアンカーをつけることができるようになりました。また、現在カメラビューで認識された画像を追跡しているのか、最後に画像を認識した位置を追跡しているのかも取得できるようになりました。
フレームが赤くなっている時は、最後に認識された位置を追跡している状態です。
さいごに
2019年になってから半年で ARCore は大きく進化しました。
2019年夏にも、 Light estimation に新モード「 Environmental HDR 」の追加、 Augmented Faces の iOS 対応など、まだまだバージョンアップが控えています。
ついでにオクルージョンが簡単に実装できる API が追加されるといいなー、と思ってます。









