Android
C#
Unity
AndroidStudio
ARCore

【更新情報】

更新日時 内容
2018/2/25 ARCore 1.0がリリースされましたので、合わせて内容を更新しました。
2018/4/2 ARCore 1.1.0がリリースされましたので、合わせて内容を更新しました。
2018/5/22 ARCore 1.2.0がリリースされましたので、合わせて内容を更新しました。
2018/6/1 ARCore 1.2.1がリリースされました。特に更新はないのですがタイトルの方を変更しました

ARCoreとは?

概要

ARCoreはデジタルと物理の世界をシームレスに融合させた新しい経験を形作ることができる、Googleが提供する新しいAR(拡張現実)プラットフォームです。
以下が実際に実装して、実行してみたものになります。
ezgif-3-c10ddc3c08.gif

Tangoってなかったっけ?

ARCoreはいわばTangoの一般向け汎用デバイスに向けたARプラットフォームにあたります。
Tangoはモーショントラッキングカメラや深度センサーなど追加のハードウェアを必要とするのに対し、ARCoreはそういった特別なハードウェアなしでTangoのようなものを開発することができるようにしたものです。

※2018/3/1をもってTangoのサポートは終了しました。これからは、ARCoreの開発に注力します。
【参考】 Google、「Project Tango」の終了を正式発表 「ARCore」開発者プレビュー2公開

ARKitと何が違うの?

ARCoreARKitのAndroid版です。
ARKitでできることのほとんど同じことはARCoreでもできます。

何ができるの?

  • モーショントラッキング
  • 水平・垂直面の検出(認識)
  • 光源の推測(環境光)
  • 特徴点抽出(PointCloud)
  • 空間共有
  • マーカー画像検知

ARCore 1.2.0での主な変更点

  • ARCore 1.1.0で発生していた各種バグの修正
  • AugmentedImage(マーカー画像検知)の機能とサンプルプロジェクトとの追加(後述)
  • CloudAnchor(空間共有)の機能とサンプルプロジェクトの追加
  • 垂直平面(壁)も検出できるようになった
  • 対応端末の整備+追加
  • 一部機能のiOS(ARKit他)との親和性、開発効率向上のためのものの追加

【参考】

対応端末(2018/5/22現在)

メーカー 機種名 備考
Asus Zenone AR
Google Nexus 5X Android 8.0以上のみ
Nexus 6P Android 8.0以上のみ
Pixel, Pixel XL
Pixel 2, Pixel 2 XL
HMD Global Nokia 6 (2018) 一般的にはNokia 6.1と言われているもの
Nokia 8 Sirocco
Huawei P20, P20 Pro
Mate RS Porsche Design
LG G6 Android 8.0以上のみ
G7 ThinQ
Motorola Moto G6 Plus
Moto Z2 Force
OnePlus OnePlus 3T Android 8.0以上のみ
OnePlus 5
Samsung Galaxy A5 (2017) Samsung devices with a model number ending in 0 or 8 are not supported, e.g. SM-G9600.
Galaxy A7 (2017)
Galaxy A8, Galaxy A8+ (2018)
Galaxy Note8
Galaxy S7, Galaxy S7 edge
Galaxy S8, Galaxy S8+
Galaxy S9, Galaxy S9+
Sony Xperia XZ Premium Android 8.0以上のみ
Xperia XZ1, Xperia XZ1 Compact Android 8.0以上のみ
Xiaomi Mi Mix 2S

一応、裏技でこれら以外の端末で動かすことはできますが、現状動作がかなり怪しいのでそのつもりで開発してください。
【参考】 ARCoreをPixelやS8以外の端末で動かす

端末状況について詳しくはこちら

【2018/2/25更新】
上記端末のほか、現在、Samsung, Huawei, LGE, Motorola, ASUS, Xiaomi, HMD/Nokia, ZTE, Sony Mobile, Vivoの端末メーカーの次の新機種にはARCoreを載せようとしていいます。そのため、これらのメーカーから販売される新機種の端末にはいずれもARCoreが搭載されている可能性が高いと思われます。

【参考】

開発可能環境とライブラリのダウンロード先

開発環境 ライブラリ
Android(Java) arcore-android-sdk
Android NDK(C/C++) arcore-android-sdk
Unity arcore-unity-sdk
Unreal Engine4 arcore-unreal-sdk
web three.ar.js(SDKではなくthree.jsのAR対応したものになります。サンプルなどは別途あります。)

で?おすすめの開発環境は?

Unityです!!
実装には3Dの技術や知識が必要になります。
3Dについてのはじめの一歩としてこちらに紹介しています。
3D入門

Android JavaのサンプルではOBJファイルを読みこんでいますが、それ以外のファイル(FBX等)を読みたい場合は自力で読み込むしかないです。(またはRajawaliをうまく使いこなすことができたらもしかしたら...)
3Dの処理を自力で書くのは相当大変なのでUnityまたはUnreal Engine、(web)を使って開発することをおすすめします。(※webの場合、three.jsの練度や対応状況、端末依存などの影響を大きく受ける可能性があります。そのため安定した動作が期待できない可能性があります)

【2018/5/22追記】
Sceneformが新しくリリースされました。これはAndroid Javaをメインに開発している人でも3Dの開発をしやすいようにしたエディタツール(Android Studio Plugin)です。つまりUnityやUE4のエディタ機能をAndroid Studioでも利用できるようにしたものになります。Sceneformを使って開発していけば、開発も捗ると思います。(Sceneformの使い方などについては本稿の趣旨と離れるので割愛します)

【参考】
* Sceneform Overview

サンプルを動かす

Android Studioで

公式ドキュメントはこちら。Getting Started with Android Studio

  1. Android Studioを起動し、 arcore-android-sdk/samples/hello_ar_javaを選択し、Androidのprojectを開きます。
  2. ▶のボタンを押す。 AndroidStudio.png

これで、ビルドされ、端末にサンプルがインストールされます。
※今回はhello_ar_javaのプロジェクトを開いて実行しましたがこれ以外のプロジェクトを開いた場合でも同様に▶ボタンを押すことでビルド、インストールすることができます。

それぞれのプロジェクトについて

  • hello_ar_java: AndroidSDKを用いて水平・垂直平面検出のサンプルプロジェクト
  • hello_ar_c: C++(AndroidNDK)を用いて水平・垂直平面検出のサンプルプロジェクト
  • computervision_java: カメラ画面とSobalエッジフィルターを適用させた画面の2面を表示しているプロジェクト。カメラのPreview画像の取得や検出処理などを自力でやりたい人向けのもの。
  • computervision_c: computervision_javaのC++(AndroidNDK)版
  • cloud_anchor_java: 空間共有(AR空間上に3Dモデルを置いた場合、違う端末から見ても同じ場所に置かれている)のサンプルプロジェクト
  • cloud_anchor_c: cloud_anchor_javaのC++(AndroidNDK)版
  • augmented_image_java: マーカー画像を検知する(特定の画像をデータベースとして登録し、カメラでその画像を検知する)とARの3D空間上にオブジェクトが出現するサンプルプロジェクト
  • augmented_image_c: augmented_image_javaのC++(AndroidNDK)版

Unityで

公式ドキュメントはこちら。Getting Started with Unity
Unityで動かすためには少し特殊な設定を行う必要があります。
※ARCore用の設定のままARCore以外のUnityプロジェクトをビルドすると正常に起動しませんので気をつけてください
ARCoreではInstant Previewという、Unity Editor上でARCoreを実行している様子を表示することができる機能があります。通常のBuildの他に、この機能の使い方も一緒に紹介します。

  1. UnityのARCoreのSDKをダウンロードしてきて展開する。
  2. 展開後、Assets/GoogleARCore/Examples/HelloAR/Scenes/HelloAR.unityを開き、Sceneを表示する。 import_arcore.png
  3. File->Build Settingsを選択して、Build Settingsを開く 

BuildSettings.png
4. 「Add Open Scenes」ボタンを押して現在のSceneを追加する。
5. Platformの中の「Android」を選択して、「Switch Platform」ボタンを押す。
6. しばらくすると、AndroidでBuild可能な環境となります。

Unity Editor上で実行する場合(要ARCore 1.1.0以上 + 実行可能な実機端末)

  1. ARCoreを実行可能な実機端末とUnityで開発しているマシンをつなげる
  2. ▶のボタンを押す。

UnityEditorPlay.png

これにより、実機端末の方でInstant Previewモードで実行され、実機端末でARカメラで撮影、実行されている様子が「Game」画面の中に表示されます。
UnityInstantPreview.png
また、この状態で「Hierarchy」内に3Dモデルなどを挿入すると実機端末内に挿入したものが出現します。
Instant Previewモードでの注意点として、このとき、起動するSceneでは以下の内容を記述しないと、実行中の間の実機でのタッチ判定を取得する事はできないので注意が必要です。(サンプルには記述されているので、主にversion upする場合の話になります。)

#if UNITY_EDITOR
  using Input = InstantPreviewInput;
#endif

詳しくはこちらをご覧ください

Buildする場合

  1. Platformが「Android」に変更されたら、「Player Settings...」ボタンを押してPlayerSettingsを開く BuildSettingWindow.png

2. Other Settingsのタブを開き、以下の設定を行う

  • Multithreaded Rendering のチェックを外す
  • Package Name の部分を適当な名前にする com.example.helloARのような感じで
  • Minimum API Level をAndroid 7.0 またはそれ以上にする
  • Target API Level をAndroid 7.0 またはそれ以上にする(Minimum API Level以上)

PlayerSettings.png
3. XR Settingsのタブを開き、 ARCore Supported のチェックをつける
ARCoreSupported.png
4. 再びFile->Build Settingsを選択して、BUild Settingsを開く
5. 「Build」ボタンを押してBuildする。ビルド結果を端末に直接インストールしたい場合は「Build And Run」ボタンを押して直接インストールする。
Build.png

これでサンプルアプリを実機にBuildして動かすことができます。

Unreal Engineで

すみません、試していません。しかし、公式ドキュメントはこちらにありますのでこちらをご参照ください。Getting Started with Unreal

開発する(Unityで)

開発環境と開発の制約

  • 検証端末: Pixel2
  • Unity 2017.3.0f2以降 (※ARCore 1.2.0ではUnity 2017.3.0以降でビルドしないと動いてくれません)

Pixel2購入したい

正規の方法ではPixel2は日本では購入できません。
私はここの記事を参考に購入しました。
【実験済】日本国内から米国版GoogleストアのPixel 2を購入する方法!

Android以外の環境の開発もできるの?

できません。開発するときは必ずPlatformを「Android」に指定して開発してください。
AndroidPratform.png
【2018/5/22追記】
ARCore1.2.0以降ではARCore内に一部、iOSでも使われる機能が内包されています。(実態はARKitの一部機能を用いています)そのため、ARCore内でもARKitの一部の機能を使うことができますが、本格的にARKitと共同で開発する場合はUnity-ARKit-Pluginを利用してください。また、ARKitとARCoreを共通のソースコードで開発する場合はこちらもご活用ください。
Unity で ARKit & ARCore AR開発環境のマルチプラットーフォーム(iOS & Android)対応
【参考】
* Welcome to the ARCore SDK for iOS

表示されるものをドロイド君から変えたい

ひとまず、既存のSceneにあるExampleControllerの中のAndy Android Prefabを別のものに差し替えたら表示されるものが変わります。
ChangeAndy.png

検知した平面上にものを出現させる場合

検知した平面上にものを出現させる場合、Anchorと呼ばれるものを作成し、その子供に出現させる必要があります。Anchorを作る理由として、ARCoreでは時々、位置の調整を行なっており、Anchorの子供に出現させないとだんだん位置がずれていきます。(問い合わせてご回答いただけました。The camera often seems to teleport.)
具体的なやり方は以下のとおりです。

Trackable trackable.CreateAnchor(Pose)
//または
Session.CreateAnchor(Pose);

でAnchor(クラス)を取得できます。
上記のPoseは出現させたいPosition(座標)とRotate(向き)を指定することで作成できます。

new Pose(Vector3 position, Quaternion rotate)
または初期値(position = Vector3.zero, rotate = Quaternion.identity)を入れたい場合
Pose.identity

また、TrackableとはTrackedPlane(検出できた面)やTrackedPoint(検出できた特徴点)の基底クラスとなります。

他にも3Dモデルないの?

3Dモデルを公開してくれているサービスはいくつもあるのでここらへんから3Dモデルを持ってくることをおすすめします。

3Dモデルをいっぱい使いたい、なんか便利なツールないの?

そのためのツールを作成しましたのでこちらを参考にしてください。
Unity 開発者があると便利だと思うツールを色々と作成したので公開

検知した平面に物理演算を適用したい

以下記事が非常に参考になります。
ARCoreで検出した水平面にオブジェクトを落とす

以下に該当のソースコードを記します。

DetectedPlaneVisualizer.cs
//もともとあったコード。m_meshに頂点情報(座標と順番)や色情報を渡している |
m_Mesh.Clear();
m_Mesh.SetVertices(m_MeshVertices);
m_Mesh.SetIndices(m_MeshIndices.ToArray(), MeshTopology.Triangles, 0);
m_Mesh.SetColors(m_MeshColors);
//下記の2行を新たに追加。上記で作成した三角形の集合をコライダーに反映
//Add following 2 lines. This cord attaches triangular mesh information to collider.
GetComponent<MeshCollider>().sharedMesh = null;
GetComponent<MeshCollider>().sharedMesh = m_Mesh;

そして、検出した面に当たり判定が適用されるようにします。
DetectedPlaneVisualizer.prefabにMeshColliderをつけることで、検出した面に当たり判定がつき、物を置くことができるようになります。
AttachMeshCollider.png

該当箇所を以上のように修正すると検出面にCollider(あたり判定を検出する膜)をつけることができます。
その後、物理演算をしたい3Dモデルに以下のようにRigidBodyという要素をつければ、物理演算をしてくれるようになります。
RigidBody.png
またこの時、Use Gravityにチェックを入れると、重力が有効になり、検出した平面に上に乗せることができます。

検知した平面についてもう少し詳しく知りたい

サンプルの平面の検出にあたる部分の処理を以下に表示します。

HelloARController.cs
List<DetectedPlane> m_NewPlanes = new List<DetectedPlane>();
if (Session.Status != SessionStatus.Tracking)
{
    return;
}
Session.GetTrackables<DetectedPlane>(m_NewPlanes, TrackableQueryFilter.New);

これで、新たに検出できた平面を取得し、

HelloARController.cs
List<DetectedPlane> m_AllPlanes = new List<DetectedPlane>();
Session.GetTrackables<DetectedPlane>(m_AllPlanes, TrackableQueryFilter.All);

これで検出できている平面全ての情報を取得することができます。
Session.GetTrackablesの第2引数は省略可能でTrackableQueryFilter.Allを使うので十分に事足ります。
この、DetectedPlaneが検出できた平面で、水平・垂直の両方の平面を共通して扱います。
このDetectedPlaneは検出面が広がることで各種値が更新されていきます。(以降の項目を参照)

DetectedPlaneについて

検出できた面はDetectedPlaneというstructとして取得することができます。
この、DetectedPlaneですが面の座標や広さの情報を保持しています。それぞれの座標系の情報以下の通りです。

フィールド(メソッド)名 意味
CenterPose 面の中心にあたる部分のPose(座標や角度などを保持しているStruct)
ExtentX 面の中心からの広さ(距離)のX軸の値
ExtentZ 面の中心からの広さ(距離)のZ軸の値

DetectedPlaneは基本的に水平面を基準とした値が取得できます。垂直面などは平面の向いている角度に違いによって表現されています。(上記メソッドではCenterPoseで取得できたPoseの内のrotateの値の違いです。

詳しく説明はこちらを参照。
GoogleARCore.DetectedPlane

カメラってどうなってんの?

First Person CameraがAR上のカメラにあたります。
アプリを起動した場所を原点として、移動、回転した分がこの値になります。
現在カメラに写っているかどうかで制御したい場合は以下のようにOnBecameVisibleまたはOnBecameInvisibleを使用することで判定できます。
※ただしこれらのCallbackはRenderer Classがついている場合のみ呼ばれます

SomthingRendererBehaviour.cs
public class SomthingRendererBehaviour : MonoBehaviour {
    void OnBecameVisible(){

    }

    void OnBecameInvisible(){

    }
}

【参考】カメラに写っているかで処理を分岐する

壁は検出できないの?

ARCore 1.2.0以降では壁も検出できるようになりました。ARKitではVersion 1.5から壁を検出できます。(iOS 11.3以上にする必要があります)
実際に検出する方法は
ARCoreDevice.png

  • ARCore Deviceの中にセットされている、Session Configの参照先をみる

SessionConfig.png

  • Session Configの中にセットされているもの(DefaultSessionConfig)の中にある、Plane Finding Modeの値が、Horizontal And VerticalまたはVerticalになっている。(水平面の場合はHorizontal And VerticalまたはHorizontalになっている)

この状態で、壁を検出すると、上記、DetectedPlaneについてと同様に、DetectedPlaneを取得することができます。(上記のようにCenterPoseで取得できたPoserotateの値から壁であると判別できます)

この他、ARCoreSessionConfig(今回の場合、DefaultSessionConfig)にてARCoreで利用できる機能のON/OFFの設定ができます。

なお、独自に実装することも可能です。その場合はこちらを参考にしてください。
ARKitで任意の方向の平面を検出する

AugmentedImageについて教えて

AugmentedImageとは事前に画像の情報を指定し、その画像をARCoreのカメラにかざすと検出できるという機能です。(一般的にはマーカー画像と呼ばれます) Vuforiaで使われている機能と類似の機能になります。
なおARCore1.2.0ではARCore起動中に検出可能画像を追加することはUnityEditor上では可能ですが、実機ではできません。

マーカー画像の設定について

  • ARCore Deviceの中にセットさせる、Session Configを変更する

AugmentedImageSessionConfig.png

  • Session Configの中にセットされているもの(この場合AugmentedImagesSessionConfig)の中にある、AugmentedImageDatabaseに認識する画像情報のデータベースをセットする。

ImageDatabase.png

  • データベースにある画像を更新、削除、追加することで認識可能画像を変更することができます。

プログラム上で行う場合、以下のようにAugmentedImageDatabaseEntryを操作することで更新できます。

ARCoreSessionConfig.cs
AugmentedImageDatabaseEntry entry = new AugmentedImageDatabaseEntry(Texture2D image);
AugmentedImageDatabase.Add(entry);

設定したマーカー画像を検知した時の処理について

以下のようにすることでマーカー画像を検出した情報を取得することができます。

AugmentedImageExampleController.cs
public void Update(){
  List<AugmentedImage> m_TempAugmentedImages = new List<AugmentedImage>();
  Session.GetTrackables<AugmentedImage>(m_TempAugmentedImages, TrackableQueryFilter.Updated);
}

ここで取得できた、AugmentedImage上記のTrackableでもあるので、AugmentedImageからCreateAnchorを呼び出すことでARCoreの空間に出現させることができます。

CloudAnchorについて教えて

CloudAnchorとは、複数の端末において共通の空間を共有する機能です。iOS(ARKit)で検出している空間とも共有することができます。
以下がデモの様子です。
CroudAnchors

CroudAnchorsを試してみる。

CroudAnchorsを実際に利用できるようにするには、まずEditor→Project Settings→ARCoreを選択し、ダイアログを開きます。
editor_arcore.png

以下のように「Cloud Server API Key」の項目にAPIキーを入力します。(APIキーの取得については以下参照)
ARCoreKeySetting.png

APIキーとは?(設定方法)

Google API Consoleを開き、ARCoreのCloud Anchorを使えるようにします。
SearchARCore.png
Google API ConsoleからARCoreの検索します。
ARCoreSettings.png
検索してでてきた、ARCoreの設定を「有効」にします。
APIKey.png
Google API Consoleの中の「認証情報」を選択し、上記のようにARCoreが有効になっているプロジェクトのAPIキーの内容をUnityのAPIキーの項目にのところに入力します。

この状態でAssets/GoogleARCore/Examples/CloudAnchor/Scenes/CloudAnchor.unityを開き、プロジェクトこのSceneをビルドすることで、CloudAnchorsについて、試してみることができます。
※UnityのExamplesでのCloudAnchorsは接続がかなりシビアになっており、なかなか端末と繋げることができません。UnityではなくAndroid NaitiveではNearByを利用しているためか、割と繋がりやすいです。

また、上記でデモ動画で行われているアプリやソースコードは以下になりますので、実装の際にはこちらも参考にしてください。

【その他参考記事】

まとめ

  • ARCoreの導入の仕方と一部ソースコードなどで解説、紹介しました
  • Unreal Engine4での導入については後ほど記事を更新したいと思います。
  • その他、気になることなどありましたらコメントいただけると幸いです

関連記事