9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Androidスマホで自由に動き回れるVRアプリを作る方法(Unity・ARCore・Google VR(Cardboard))

Posted at

こんな感じに部屋の中を動き回れるものを作ることができます。

ARCoreVR_drop16.gif
© Unity Technologies Japan/UCL

いわゆる、6DoFっていうやつです。
ARCoreに対応しているスマホと、スマホ装着型のVRゴーグルを用意すれば誰でも試せます。
スマホ内蔵のカメラを使いますが、マーカーなどは必要ありません。

補足

  • 古い機種やiPhoneといったARCore非対応の端末には使えません。(iPhoneの場合は、ARKitを使えばいけるかもしれないけど、試したことはありません)
  • ARCoreを使っていますが、ARアプリではありません。(カメラ画像とモデル表示の位置がずれてしまうため、そのままではARでは使えないです)
  • 自分の足で動きまわることができますが、なるべく広い部屋で行い、壁などにぶつからないように注意してください。
  • 起動時にはカメラ画像が表示されますが、その時は床を映してください。床を認識次第、VRの画面に移行します。

用意するもの

手順

  1. 新しいプロジェクトを作成
  2. File→Build Settings...から設定画面を開き、Androidをクリック、その後Switch Platformボタンを押して、設定を切り替える
  3. arcore-unity-sdk-v1.9.0.unitypackageをUnityエディタ上のAssetsフォルダにドラッグアンドドロップし、インポートする
  4. GoogleVRForUnity_1.200.0.unitypackageも同様にインポートする
  5. シーン上にあるカメラを削除する
  6. Assets/GoogleARCore/Prefabsにある、「ARCore Device」プレハブをHierarchyにドラッグアンドドロップし、シーンに追加
  7. 空のゲームオブジェクトを追加
  8. 以下のスクリプトを作成
TrackingObjects.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleARCore;

public class TrackingObjects : MonoBehaviour
{
    // 非表示のままにしておくオブジェクト
    List<GameObject> hideObjs_ = new List<GameObject>();
    // 認識した床
    DetectedPlane plane_ = null;
    // カメラ画像のRenderer
    ARCoreBackgroundRenderer backgroundRenderer_;

    void Start()
    {
        // 子オブジェクトを全て非表示に
        foreach (Transform trans in transform)
        {
            if (trans.gameObject.activeSelf)
            {
                trans.gameObject.SetActive(false);
            }
            else
            {
                // すでに非表示にしているものは除外
                hideObjs_.Add(trans.gameObject);
            }
        }

        backgroundRenderer_ = FindObjectOfType<ARCoreBackgroundRenderer>();
    }

    void Update()
    {
        // タッチされていたら位置をリセット
        if (Input.touchCount > 0)
        {
            ResetPosition();
        }

        if (Session.Status != SessionStatus.Tracking)
        {
            return;
        }

        if (plane_ == null || plane_.TrackingState == TrackingState.Stopped)
        {
            // 新しい床の取得
            plane_ = null;
            List<DetectedPlane> planes = new List<DetectedPlane>();
            Session.GetTrackables<DetectedPlane>(planes, TrackableQueryFilter.All);
            foreach (DetectedPlane plane in planes)
            {
                if (plane.PlaneType != DetectedPlaneType.Vertical)
                {
                    plane_ = plane;

                    transform.position = new Vector3(transform.position.x, plane_.CenterPose.position.y, transform.position.z);

                    // 子オブジェクトを表示
                    foreach (Transform trans in transform)
                    {
                        if (!hideObjs_.Contains(trans.gameObject))
                        {
                            trans.gameObject.SetActive(true);
                        }
                    }

                    // カメラ画像を非表示
                    backgroundRenderer_.enabled = false;

                    break;
                }
            }
            
            if (plane_ == null)
            {
                // 子オブジェクトを非表示
                foreach (Transform trans in transform)
                {
                    if (!hideObjs_.Contains(trans.gameObject))
                    {
                        trans.gameObject.SetActive(false);
                    }
                }

                // カメラ画像を表示
                backgroundRenderer_.enabled = true;
            }
        }
    }

    // 位置のリセット
    public void ResetPosition()
    {
        Transform transCamera = Camera.main.transform;
        if (plane_ != null)
        {
            transform.position = new Vector3(transCamera.position.x, plane_.CenterPose.position.y, transCamera.position.z);
        }
        else
        {
            transform.position = transCamera.position;
        }
    }
}
  1. 7)のオブジェクトに8)のスクリプトをアタッチ
  2. VR画面上に表示させたいゲームオブジェクトを、7)のオブジェクトの子オブジェクトに設定
  3. シーンを保存
  4. File→Build Settings...→Player Settings...から、以下の設定を変更
  • Other Settings→Identification→Package Name:適当に変更
  • Other Settings→Identification→Minimum API Level:Android 7.0 'Nougat' (API Level 24)
  • XR Settings→Virtual Reality Supported:オン
  • XR Settings→Virtual Reality SDKs:Cardboardを追加
  • XR Settings→ARCore Supported:オン

あとがき

この内容はすでにやった人がいるようでしたが、私でも試してみたところ、スクリプト1枚で済んでしまったので、それを記事として作ってみました。
これだけだと、いろいろ不都合な点がありますが、等身大のキャラクターが見れるだけでも結構面白いですので、試してみてください。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?