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に行きます

<img width="200" alt="Build_Settings_と_Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/acaee7cf-d578-97bc-d2ba-4766290b7e75.png">
Platformで``Android``を選んだ後に ``switch platform``を選びます。
``switch platform``ボタンの隣りにある``Player Setting``をクリックして``PlayerSetting``を表示します


<img width="200" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/452af071-3fa9-f325-f182-0b97161aed4b.png">
``Other setting``内の
``Package name``に任意の識別子を設定します。(他のアプリとかぶらないような)
``Minimum API Level``はとりあえず ``5.1``にしました。 (でもGoは7.1なので7.1でよかったかもです。)


<img width="200" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/eb1dc7e1-d0d8-6777-e457-b6990ed7383e.png">

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

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

# コントローラー側の対応

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

<img width="400" alt="https://qiita-image-store.s3.amazonaws.com/0/3844/a22b6ef7-80ea-f443-b7da-ba2a5b141d22.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/3844/a22b6ef7-80ea-f443-b7da-ba2a5b141d22.jpeg">

ピクリとも動かない。


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

<img width="500" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/5c980cdd-21c5-e85f-7713-e7994fd323b3.png">

``import``をクリックし
<img width="424" alt="Import_Unity_Package_と_Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/42602725-b3d6-7c15-0745-28ff1d21b01d.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




<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Unityの玉転がしチュートリアルを#OculusGoに対応させる(途中) <a href="https://t.co/R7syXriz6S">pic.twitter.com/R7syXriz6S</a></p>&mdash; m0a (@abe00makoto) <a href="https://twitter.com/abe00makoto/status/996536720395915264?ref_src=twsrc%5Etfw">2018年5月15日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


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

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

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


<img width="992" alt="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" src="https://qiita-image-store.s3.amazonaws.com/0/3844/9da87239-0e89-4218-04e1-578f2a2aea7e.png">

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

<img width="323" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/ddb7f7d5-4e77-850e-b358-d8ea2603131b.png">

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

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

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

<img width="326" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_9.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/80370c63-41c6-5b2b-86e8-9235563abd84.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を表示できるように

<img width="302" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/cbdafdc5-fd89-818d-0208-54aced8886b6.png">

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

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



<img width="913" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_5.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/1d612c66-fb3d-7944-715c-11f6e2dac039.png">

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

<img width="318" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_6.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/9214d2d4-574c-f2a5-f983-99c1c774913b.png">

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

<img width="324" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_7.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/0525549d-a102-59f8-519b-4150c7644edf.png">


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

<img width="315" alt="Unity_2018_1_0f2_Personal__64bit__-_stage01_unity_-_Roll-a-Ball_-_Android__Personal___Metal_8.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/7a3027e2-0eb5-67e1-bc83-9dd569c28f68.png">


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

# 完成

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Unityの玉転がしチュートリアルを#OculusGoに対応させる(完成) <a href="https://t.co/QwZUAHBbx5">pic.twitter.com/QwZUAHBbx5</a></p>&mdash; m0a (@abe00makoto) <a href="https://twitter.com/abe00makoto/status/996558012230787073?ref_src=twsrc%5Etfw">2018年5月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# まとめ

結構簡単にできました。


# 参考情報
http://bibinbaleo.hatenablog.com/entry/2018/05/14/001544
https://framesynthesis.jp/tech/unity/touch/