Unity
Oculus
OculusGo

Unityの玉転がしチュートリアルを#OculusGoに対応させる

OculusGoを買いました。
気分が上がってきたのでUnityで遊びたくなりましたがコントローラー周りで詰まり解決方法を探ったまとめです。
なお、昨日からUnityに入門するため間違い等ありましたらご指摘&修正リクをお願い致します。m(_ _)m

Unity入門を遊んだ後に

https://unity3d.com/jp/learn/tutorials/projects/hajiuni-jp
この玉転がしのチュートリアルの後にこのゲームをOculusGoに対応させます。
上記チュートリアルを終わった後に追加作業でOculusGoに対応します。

OculusGoを開発者モードにしてAndroid開発環境を入れる

これは以下に情報があります。
https://qiita.com/Hirai0827/items/f62588cc7d5c6c17e364

アプリのVR対応

まずメニューからFile->BuildSettingに行きます

Build_Settings_と_Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png
PlatformでAndroidを選んだ後に switch platformを選びます。
switch platformボタンの隣りにあるPlayer SettingをクリックしてPlayerSettingを表示します

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png
Other setting内の
Package nameに任意の識別子を設定します。(他のアプリとかぶらないような)
Minimum API Levelはとりあえず 5.1にしました。 (でもGoは7.1なので7.1でよかったかもです。)

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png

次はXR Settingsの項目です。
Virtual Rearity Suppoertedを有効化し
Vertula Rearity SDKsOculusを追加します
Stereo Rendering MethodsをSingleに設定します。

この状態でFile -> Build & Runを実行すると見た目だけVRに対応します。

コントローラー側の対応

でも肝心の操作が効きません。

https://qiita-image-store.s3.amazonaws.com/0/3844/a22b6ef7-80ea-f443-b7da-ba2a5b141d22.jpeg

ピクリとも動かない。

Oculus Integrationを導入します。
メニューのwindow -> Asset Storeを選びOculus Integrationで検索します

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_.png

importをクリックし
Import_Unity_Package_と_Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_.png

importします。
Oculus Integration内にて提供されるOVRInputを用いて入力の取得をおこないます。

PlayerControllerのコード修正

PlayerController.csを修正します。

現状は以下のようになっています。

PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour {
    public float speed = 10;


    void FixedUpdate(){

        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Rigidbody rigidbody = GetComponent<Rigidbody>();
        rigidbody.AddForce(x * speed, 0, z * speed);
    }
}

先ず上記クラス名とファイル名を修正します。なんでかというとOculus Integration内のクラスと名前衝突しているからです。

PlayerBallControllerとかにしておきます。

ここにOVRInputを利用するコードを追加します

PlayerBallController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerBallController : MonoBehaviour {
    public float speed = 10;

    private void Start()
    {
    }
    void Update() {
        OVRInput.Update();
    }
    void FixedUpdate(){

#if UNITY_ANDROID && !UNITY_EDITOR
        OVRInput.FixedUpdate();
        //右手持ち決め打ちで実装
        Vector2 vector =  OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad, OVRInput.Controller.RTrackedRemote);
        float x = vector.x;
        float z = vector.y;

#else 
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
#endif

        Rigidbody rigidbody = GetComponent<Rigidbody>();
        rigidbody.AddForce(x * speed, 0, z * speed);
    }
}

今回は、OVRInputを使うために呪いとしてFixedUpdate内で OVRInput.FixedUpdate()、Update内でOVRInput.Update()を呼ぶ必要があります。
(OVRManagerがシーン内に一つだけ存在する場合はこの呪いは不要です。)

更に、右手持ち前提でタッチパッド操作情報を拾うようにしました。いろいろ手を抜いています。

参考情報:
https://taiyaq.com/contents/jJMNL163YkNy1HQ1eN0G7pG9v

ですが得点表示とか全部のアイテムを取り終わったらYou Winと出るはずですがでません。
ここを次に対応させます。

得点表示できるようにする

今あるカメラの代わりに、OVRCameraRigを使います。
以下のようにOculus/VR/Prefabs内にあるOVRCameraRigをシーンにドラッグして新しいカメラを作ります。更に元々あったMain Cameraを削除します。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal__と_Assembly-CSharp_–_Assets_Script_PlayerBallController_cs__–_Visual_Studio_Community_2017_for_Mac.png

Main Cameraと同じ設定をOVRCameraRigに対して行います。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_2.png

Transformに同じようにPositionを(0,9,-5)とRotationを(60,0,0)に設定します。
更にAdd Componentでチュートリアルで作成したFollowPlayerスクリプトを取り込みます。
忘れずにTargetにPlayerをドラックして設定します。
ここまで行うとボールの動きに従って視線も動くようになります。

OVRCameraRig 追加に伴うコードの変更

OVRCameraRig内にはOVR Managerが入っています。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_9.png

これに伴いPlayerのコードを変更します

PlayerBallController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerBallController : MonoBehaviour {
    public float speed = 10;

    void FixedUpdate(){

#if UNITY_ANDROID && !UNITY_EDITOR
        Vector2 vector =  OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad, OVRInput.Controller.RTrackedRemote);
        float x = vector.x;
        float z = vector.y;

#else 
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

#endif

        Rigidbody rigidbody = GetComponent<Rigidbody>();
        rigidbody.AddForce(x * speed, 0, z * speed);
    }
}

OVRInputを使うために呪いとして追加していた、FixedUpdate内で OVRInput.FixedUpdate()、Update内でOVRInput.Update()の呼び出しを削除しました。

UIを表示できるように

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_3.png

元々あった得点表示とYou Winと表示するCanvasをOVRCameraRig内のCenterEyEAnchor内へドラックして移動します。

CenterEyEAnchor内にコンテンツを設定することで常に目の前に表示できるようになります。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_5.png

以下実際の設定値です。色々試行錯誤した結果です。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_6.png

Canvasについて、
Render ModeWorld Space にします。
Rect Transformについてそれぞれ
Postionは(0,0,5)、Width,Heightは(300,300)
Scale(0.02,0.02,0.02)に設定しました。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_7.png

ScoreLabelについて、
Rect Transformについてそれぞれ
Postionは(-90,-90,0)、Width,Heightは(50,50)
Font Size40に設定しました。

Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_8.png

WinnerLabelについて、
Rect Transformについてそれぞれ
Postionは(20,0,0)、Width,Heightは(280,80)
Font Size60に設定しました。

完成

まとめ

結構簡単にできました。

参考情報

http://bibinbaleo.hatenablog.com/entry/2018/05/14/001544
https://framesynthesis.jp/tech/unity/touch/