【Unity】ARCoreのTips

f:id:tm8r:20171005123647p:plain

カメラの親子関係

サンプルのHelloARControllerではFirst Person CameraはARCore Deviceの子になっています。
f:id:tm8r:20171005123826p:plain
ARCore Deviceのコンポーネントの状態はこんな感じ。

で、SessionComponentはどのオブジェクトにくっついててもいいんですが、TrackedPoseDriverはカメラかカメラの親にくっついてる必要があるようです。
具体的にはTrackedPoseDriverがくっついてるオブジェクトはデバイスを移動した際に連動してTransformの値が変わるので、TrackedPoseDriverがカメラもしくはその親についていない場合、デバイスの移動に連動できなくなってしまいます。

ARCore Deviceのプレハブを使ってる限り特に問題は起きませんが、自前で組み立てる場合はこのあたりの注意が必要そうです。

エディタでデバッグしたい

残念ながら現状エディタ上でのARCoreの実行はサポートされていません。
とはいえARCoreと連動する以外の部分くらいはエディタ上でテストしたいところ。

というわけでこんな感じでHelloARController.csとPlaneAttachement.csを書き換えて、やるととりあえずエディタでもARCore以外の部分がテストできます。

とはいえこれだと「DllNotFoundException: tango_client_api2」というエラーが出てしまうので、こちらも気になるようであれば

  • ARCore Deviceはデフォルトで非アクティブに
  • エディタ用のカメラを用意し、デフォルトで非アクティブに
  • Android実機実行時はStartでARCore Deviceをアクティブに
  • エディタ実行時はエディタ用カメラをアクティブに

みたいなことをすればそのエラーも出ずに実行できるかなと思います。

ARCoreのライト推定を自前のシェーダーに適用したい

ライト推定はEnvironmentalLight.csが以下のようなコードでShaderの変数をセットしてます。

Shader.SetGlobalFloat("_GlobalLightEstimation", colorScale);

なので、最終的なカラーに「_GlobalLightEstimation」をかけてやればライト推定の値を適用できます。

ARCore同梱のMobileDiffuseWithLightEstimationではSurfaceShaderを使っており、こちらではFinalColorModifierで以下のようにこの処理をしてます。

CGPROGRAM
#pragma surface surf MobileBlinnPhong exclude_path:prepass nolightmap noforwardadd halfasview interpolateview finalcolor:lightEstimation
(略)
fixed _GlobalLightEstimation;

struct Input
{
    float2 uv_MainTex;
};

void lightEstimation(Input IN, SurfaceOutput o, inout fixed4 color)
{
    color *= _GlobalLightEstimation;
}

同一プロジェクトでARCoreとARKitを両方使う

上に書いた階層構造を考慮しつつプラットフォーム依存コンパイルを駆使すればとりあえず同一プロジェクトでAndroidはARCore、iOSはARKitを使うようなものが作れました。
ちなみにARKitはカメラの親としてCameraParentというGameObjectがありますが、実際に移動してるのはカメラなので、このあたりを覚えておくとカメラの位置に連動する何かも作れそうです。

あとは8th Wall XRというクロスプラットフォームでARを実現するものもあるので、こちらを活用する手もあると思います。
8th Wall XR: Cross-Platform Mobile AR
まだちゃんと触ってないですけど、別途ARCoreとARKitのSDKを入れたりする必要はなく、こちらのライブラリ単体でARCoreとARKit対応しているようです。
ライセンスは各自ご確認くださいませ。

スポンサーリンク