【更新情報】

更新日時 内容
2018/2/25 ARCore 1.0がリリースされましたので、合わせて内容を更新しました。
2018/4/2 ARCore 1.1.0がリリースされましたので、合わせて内容を更新しました。

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でもできます。

何ができるの?

  • モーショントラッキング
  • 水平面の検出(認識)
  • 光源の推測(環境光)

ARCore Developer Preview2での変更点

  • ARの検出元となるカメラ画像を取得できる(ComputerVisionのプロジェクトを参考)

    • 起動中のカメラの毎フレームの画像を取得できる
    • 起動中のカメラの毎フレームのグレースケール画像を取得できる
    • カメラの毎フレームをSobalエッジフィルターした画像を取得できる。
  • C++(Android NDK)でARCoreの機能を使って開発することができる。

  • ARの検出器を切ったり、スタートしたり、と言った切り替えをすることができる。

  • 各種検出精度の向上

【参考】ARCore Developer Preview 2

ARCore 1.0での主な変更点

  • ARCore Developer Preview 2で発生していた各種バグの修正
  • ソースコードのリファクタリング
  • AR検出機能のON/OFFの切り替え(ARCore Developer Preview 2で実装されていたがバグのため、うまく機能していなかったようです)
  • 対応端末の増加
  • (サンプルや紹介例にはないため調査が必要だが)このほか何らかの機能追加

【参考】Announcing ARCore 1.0 and new updates to Google Lens

ARCore 1.1.0での主な変更点

  • ARCore 1.0で発生していた各種バグの修正
  • Unity上ではARCoreを実行させることができる端末とつないでいる状態でUnity Editorを実行することでUnity Editor上でのARCoreの動作確認ができる機能の追加(後述)
  • 対応端末の整備
  • カメラのプレビュー画面の情報(平面などを検出する前の画面の情報)を毎フレーム取得することができる機能の追加(これまではグレースケールのみだった)
  • カメラで撮影した画像の色補正情報を取得する機能の追加
  • (サンプルや紹介例にはないため調査が必要だが)このほか何らかの機能追加

【参考】

対応端末(2018/4/2現在)

機種名 対応モデル
Asus Zenfone AR ASUS_A002, JP_ASUS_A002, VZW_ASUS_A002A
Asus ZenFone Ares ASUS_A002_2
Google Pixel 2 All models
Google Pixel 2 XL All models
Google Pixel All models
Google Pixel XL All models
Huawei P20 EML-L29, EML-L09, EML-AL00, EML-TL00
Moto Z2 Force nash
OnePlus 5 ONEPLUS A5000
Samsung A5 SM-A520F, SM-A520X, SM-A520F, SM-A520W, SM-A520K, SM-A520L, SM-A520S
Samsung A7 SM-A720F, SM-A720F, SM-A720X, SM-A720S
Samsung A8 SM-A530W, SM-A530X, SM-A530F, SM-A530N
Samsung A8+ SM-A730F, SM-A730X
Samsung Note8 SM-N9508, SM-N950F, SM-N950N, SM-N950U, SM-N950W, SM-SC01K, SM-SCV37
Samsung S7 SM-G930A, SM-G930F, SM-G930K, SM-G930L, SM-G930P, SM-G930R, SM-G930S, SM-G930T, SM-G930U, SM-G930V, SM-G930W
Samsung S7 Edge SM-G935A, SM-G935F, SM-G935K, SM-G935L, SM-G935P, SM-G935R, SM-G935S, SM-G935T, SM-G935U, SM-G935V, SM-G935W, SM-SCV33, SM-SC02H
Samsung S8 SM-G950U, SM-G950N, SM-G950F, SM-G950W, SM-G9508, SM-SCV36, SM-SC02J
Samsung S8+ SM-G955F, SM-G955N, SM-G955U, SM-G955W, SM-SC03J, SM-SCV35

以前は対応していると公表していたが、(おそらく大人の事情により)公式では公表しなくなったもの

機種名 対応モデル
LG V30 (要Android 8.0以上) L-01K, L-02K, LG-H930, LG-H930DS, LG-H931, LG-H932, LG-H933, LG-VS996
LG V30+ (要Android 8.0以上) LG-LS998U, LG-US998

一応、裏技でこれら以外の端末で動かすことはできますが、現状動作がかなり怪しいのでそのつもりで開発してください。
【参考】 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の技術や知識が必要になります。
Android JavaのサンプルではOBJファイルを読みこんでいますが、それ以外のファイル(FBX等)を読みたい場合は自力で読み込むしかないです。(またはRajawaliをうまく使いこなすことができたらもしかしたら...)
3Dの処理を自力で書くのは相当大変なのでUnityまたはUnreal Engine、(web)を使って開発することをおすすめします。(※webの場合、three.jsの練度や対応状況、端末依存などの影響を大きく受ける可能性があります。そのため安定した動作が期待できない可能性があります。)

サンプルを動かす

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_c
  • computervision

のプロジェクトを開いた場合でも、同様に▶ボタンを押すことでビルド、インストールすることができます。

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

  • hello_ar_java: AndroidSDKを用いて開発しているプロジェクト
  • hello_ar_c: C++(AndroidNDK)を用いて開発しているプロジェクト
  • computervision: カメラ画面とSobalエッジフィルターを適用させた画面の2面を表示しているプロジェクト

Unityで

公式ドキュメントはこちら。Getting Started with Unity
Unityで動かすためには少し特殊な設定を行う必要があります。
※ARCore用の設定のままARCore以外のUnityプロジェクトをビルドするとビルドはできますが、カメラなどの機能は利用できませんので、気をつけてください
(ARCore 1.1.0では修正されている可能性がありますので要確認)
また、ARCore 1.1.0では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モデルなどを挿入すると挿入したものも実機端末内に出現します。
また、このとき、起動する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

これでサンプルアプリを動かすことができます。

Unreal Engineで

すみません、試していません。しかし、公式ドキュメントはこちらにありますのでこちらをご参照ください。Getting Started with Unreal
なお、Unreal Engine 4.18とそれ以外とでは導入手順が異なるようなので注意してください

開発する(Unityで)

開発環境と開発の制約

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

Pixel2購入したい

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

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

できません。開発するときは必ずPlatformを「Android」に指定して開発してください。
AndroidPratform.png

Unity Editorで動かすことできるの?

ARCoreの機能やカメラは以下のようなエラーが出て、動きません。それ以外のものはエラーは出ますが動きます。
DllLoadError.png

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

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

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

検知した平面上にものを出現させる場合、Anchorと呼ばれるものを作成し、そこの子供に出現させる必要がある用です。Anchorのは以下のとおりです。

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で検出した水平面にオブジェクトを落とす

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

TrackedPlaneVisualizer.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;

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

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

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

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

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

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

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

これで検出できている平面全ての情報を取得することができます。
この、TrackedPlaneが検出できている面で、この面は基本的に高さ(座標のyの値)が異なり、検出面が広がっていくとこの値が変更されます。

TrackedPlaneについて

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

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

詳しくはこちらを参照。
GoogleARCore.TrackedPlane

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

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

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

    }

    void OnBecameInvisible(){

    }
}

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

壁は検出できないの?

ARCoreの中に検出する機能は現状ありません。ARKitではVersion 1.5から検出できる機能が備わっています。(iOS 11.3以上にする必要があります。)
【参考】 ARKit 1.5提供開始。垂直の壁や画像認識に対応、カメラ映像の解像度向上

この他、既存の処理を使い、ARCore、ARKit双方において壁の検出処理を独自に実装することは可能です。
【参考】 ARKitで任意の方向の平面を検出する

まとめ

  • ARCoreの導入の仕方と一部ソースコードなどで解説、紹介しました
  • Unreal Engine4での導入については後ほど記事を更新したいと思います。
  • その他、気になることなどありましたらコメントいただけると幸いです
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.