じゅころぐAR

AR/VRメインのブログ。時々ドローン。

ARCore版ARモグラ叩きを作る

Tango、ARKitで作ったARモグラ叩きをARCoreで実装します。

作り方

ARCoreでシーンを構成する手順は前回の記事を参照ください。

床や壁からキャラクターが生えてくる仕組みはARCore版と一緒です。

jyuko49.hatenablog.com

  • 透明な箱にキャラクターを隠す
  • キャラクターが箱から出てくるスクリプトを書く
  • HitTestを行い、衝突面に箱を置く

HitTest以外のスクリプトはARKit/ARCoreを問わず使えるので、そのまま流用します。

HitTestをARCoreに対応させる

以下のスクリプトで実現できます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleARCore; // 追加

public class GameController : MonoBehaviour {

    public GameObject moguraPrefab;

    private float timeInterval = 2.0f; // モグラの出現間隔(秒)
    private float timeElapsed; // 経過時間を保存する変数

    void Update () {
        // 一定時間が経過したらHitTestを実行する
        timeElapsed += Time.deltaTime;
        if (timeElapsed >= timeInterval) {
            _executeHitTest ();
            timeElapsed = 0.0f;
        }
    }

    private void _executeHitTest () {
        TrackableHit hitResult;

        // HitTestの対象にFeaturePointWithSurfaceNormalを含める
        TrackableHitFlags raycastFilter = TrackableHitFlags.FeaturePointWithSurfaceNormal;

        // touch.positionの代わりにランダムな座標を与える
        if (Frame.Raycast(Screen.width * Random.value, Screen.height * Random.value, raycastFilter, out hitResult))
        {
            // 衝突点のPoseから位置と向きを取得して使う
            _createMogura(hitResult.Pose.position, hitResult.Pose.rotation);
        }
    }

    // モグラの生成
    private void _createMogura(Vector3 position, Quaternion rotation) {
        GameObject mogura = Instantiate (moguraPrefab, position, rotation);  
    }
}

要点だけ簡単に説明すると、

まず、ARCore SDKAPIを使うため、GoogleARCoreをincludeします。

using GoogleARCore;

Raycast(HitTest)を行う前に、衝突判定を行う対象をraycastFilterに設定します。

TrackableHitFlags raycastFilter = TrackableHitFlags.FeaturePointWithSurfaceNormal;

TrackableHitFlags.FeaturePointWithSurfaceNormalは現在のフレームに格納されているPointCloudに対してHitTestを行い、衝突面の法線ベクトル(Normal)から推定したPoseを返します。

HitTestの実行はFrame.Raycast()になります。

if (Frame.Raycast(Screen.width * Random.value, Screen.height * Random.value, raycastFilter, out hit))
{
    _createMogura(hitResult.Pose.position, hitResult.Pose.rotation);
}

HitTestを行うスクリーン上のx座標、y座標、raycastFilterを渡すとhitResultに結果が返ります。
hitResult.PoseにUnityの座標系で衝突点の姿勢データが入っています。

この姿勢を使ってキャラクターを配置すれば、床以外の平面に立たせることができます。

Tips

白い壁など、特徴のない平面にはPoint Cloudができにくく、HitTestに失敗しやすいです。
ポスターを貼ったりすると検知しやすくなります。