UnityでVRアプリを開発する（ハンズオン資料）

「UnityによるVRアプリケーション開発」の翻訳に関わった筆者が勉強会のハンズオン資料として用意したものです。


---

用意するもの
Unity (この記事ではバージョン5.4.2を使用しています)
Cardboard、もしくはDaydream向けにビルドする場合はGoogle VR SDK for Unity もダウンロードしておきます。
ダウンロードurl https://github.com/googlevr/gvr-unity-sdk/raw/master/GoogleVRForUnity.unitypackage
ユニティちゃん 3Dモデルデータ。データはこちらからダウンロードします。
http://unity-chan.com/download/releaseNote.php?id=UnityChan

---

#シーンの中に必要な要素
カメラオブジェクト
ライト
表示する3Dオブジェクト

---
3Dオブジェクトは何を使うか

本の中ではUnityのStandard Assetsに含まれているEthanという人間型のオブジェクトをゾンビ化したものがサンプルプロジェクトで使用されています。
実は、日本向けにするにあたって「果たしてゾンビのままで良いのだろうか」という疑問を持ってはいました。しかし校正やら何やらドタバタしているうちに、そこまで手が回らなかった...というのが正直なところです。

---

ゾンビじゃないとすると、何を使えば良いのか...
日本でUnityといえば、やはりUnity-Chanでしょう！

---


---

## Unityを起動して新規プロジェクトを作成します。

左側のシーンの階層には Main Camera と Directional Light の2つが既にあるはずです。

---

##オブジェクトを追加してみましょう。

Hierarchyパネルの［Create］メニューにある、［3D Object］→［Cube］を選択してください。

デフォルトの白い立方体がシーンに追加されます。この立方体はInspectorパネルで確認できるとおり、無回転の状態、スケール1で、位置 (0, 0, 0) である地平面の中央に配置されます。これは［Reset］の設定値となります。［Reset］は、このオブジェクトのInspectorパネルのTransformコンポーネントの中にあります。

---

###カメラオブジェクト
3D空間に配置したものをどのように画面に映すかを担うものです。
Unityで新規プロジェクトを作成すると Main Camara というオブジェクトがデフォルトでシーンに追加されます。

VRの場合はさらに、画面を左右それぞれの目に合わせて分割表示して立体視できるようにします。
そしてもう一つ、レンズの歪み補正もやる必要があります。
これらの処理はUnityおよびGoogle VR SDKがやってくれます。

---
###VR実行時の画面

![abc2016autumn_vr.jpg](https://qiita-image-store.s3.amazonaws.com/0/27559/5dfc7867-b9c0-d055-35f7-eff887de3b2a.jpeg)


---

####カメラを動かしてみましょう
カメラを選択すると　Camera Preview の小窓が出てきます。
それを見ながらカメラを動かして、どう見え方が変わるか試してみてください。

---

###地平面のオブジェクトをシーンに追加しましょう

Hierarchyパネルから［Create］メニュー（またはメインの［GameObject］メニュー）をクリックし、［3D Object］→［Plane］を選択してください。

---

###立方体を地平面の上まで移動させます。

Inspectorパネルから、Yの位置を0.5に設定し、Positionが (0, 0.5, 0) となるようにします。

---
###立方体に色をつけます。

色を設定したマテリアルを作成し、それをオブジェクトに適用してシーンに色を付けましょう。

1. Projectパネルから最上位の`Assets`フォルダーを選択し［Create］→［Folder］を選び、そのフォルダーの名前を`Materials`に変更してください。
2. `Materials`フォルダーを選択し、［Create］→［Material］を選んで、名前を`Red`に変更してください。
3. Inspectorパネル内のAlbedoの右側にある白い四角形をクリックするとColorパネルが開きます。いい感じの赤色を選んでください。
5. Hierarchy（またはScene）パネルから立方体を選択してください。
6. `Red`のマテリアルをProjectパネルから立方体のInspectorパネルにドラッグしてください。立方体が赤色になるはずです。

---

シーンとプロジェクトを保存してください。
（万が一Unityが途中で落ちてもデータが消えないように）

---

それでは、Unityちゃんに登場してもらいましょう。

---

###ユニティちゃんのデータのインポート

1. Unityのメインメニューの［Assets］から［Import Package］→［Custom Package...］を選択します。
2. ダウンロードしたUnityChan_1_2.unitypackageというファイルを見つけて選択します。
3. すべてのアセットにチェックが付いていることを確認して、［Import］をクリックします。
4. Project パネルの Assets/UnityChan/Prefabs/for Locomotion フォルダーの中から unitychan_dynamic_locomotion を見つけて、シーンにドラッグ＆ドロップします。

unitychan_dynamic_locomotionを使うのは、歩くためのアニメーションが含まれているため

---

プレビューボタンを押すと、ユニティちゃんがアニメーションで動きます。
表情やアニメーションの種類を変えるボタンが表示されるので試してみましょう。　

---

これらのボタンはVRで使う時には邪魔になるので表示されないようにします。

ユニティちゃんのオブジェクトを選択した状態でInspectorの中にある次のスクリプトコンポーネントのチェックボックスをOFFにします。

- Face Update
- Unity Chan Control Script With Rigid Body
- Random Wind

---

###ユニティちゃんに歩き回ってもらいましょう

オブジェクトが立方体が一つでは淋しい場合は、この後の手順の前に他にも幾つか追加しておきましょう。

####Nav Mesh Agentを追加します。

1. ユニティちゃんを選択します
1. Inspectorの下の方にある Add Component を押して、 Navigation → Nav Mesh Agent の順に選択します

---

####Nav Mesh 作成

表示オブジェクトのうち、動かないもののStaticチェックボックスをONにする。

- Cube
- Plane

---
WindowメニューからNavigationを選択すると、Inspectorの隣にNavigationタブが追加されます。

Bakeボタンを押すと、ユニティちゃんが歩き回れるエリアが設定され、その部分が青く表示されます。　

---

###平面の上をランダムに歩いてもらう

ユニティちゃんを選択し、スクリプトを追加する

1. Inspectorの下にある Add Component を押して、 New Script を選択します。
2. MoveControl.cs と名前をつけて、次のように入力します。

```MoveControl.cs
using UnityEngine;
using System.Collections;

public class MoveControl : MonoBehaviour {

    RaycastHit hit;
    Ray ray;
    NavMeshAgent agent;
    Animator animator;

    // Use this for initialization
    void Start () {
        agent = GetComponent<NavMeshAgent> ();
        animator = GetComponent<Animator> ();
        StartCoroutine (RePositionWithDelay());
    }

    IEnumerator RePositionWithDelay() {
        while (true) {
            SetRandomPosition ();
            yield return new WaitForSeconds (5);
        }
    }

    void SetRandomPosition() {
        float x = Random.Range (-5.0f, 5.0f);
        float z = Random.Range (-5.0f, 5.0f);
        Debug.Log ("X,Z: " + x.ToString("F2") + ", " + z.ToString("F2"));
        agent.SetDestination( new Vector3 (x, 0.0f, z));
        animator.SetFloat ("Speed", 0.2f);
    }

    // Update is called once per frame
    void Update () {
        if (agent.destination == transform.position) {
            animator.SetFloat ("Speed", 0.0f);
        }
    }
}

```

---
####ユニティちゃんの歩くスピードを調整する

デフォルトの設定だと移動スピードが速すぎるので調整します。

ユニティちゃんを選択して、InspectorのNav Mesh Agentのspeedを小さい値(1〜1.5くらい)にする。

---
##VRアプリとして実行するための設定

###Google VR SDK for Unityのインポート
2. Unityのメインメニューの［Assets］から［Import Package］→［Custom Package...］を選択します。
3. ダウンロードしたGoogleVRForUnity.unitypackageというファイルを見つけて選択します。
4. すべてのアセットにチェックが付いていることを確認して、［Import］をクリックします。
5. Project パネルの Assets/GoogleVR/Prefabs フォルダーの中から GvrViewerMain を見つけます。
2. Hierarchy パネルにドラッグします。

---
###動かしてみましょう
まずはプレビューボタンを押してみます。

optionキーを押しながらマウスを左右に動かすと見ている方向が変わります。

---

###実機で動かしてみましょう

####ビルド設定
1. メインメニューバーから［File］→［Build Settings...］を選択してください。
2. ［Scenes In Build］に現在のシーンがない場合は、［Add Open Scenes］をクリックしてください。
3. ウィンドウ左側の［Platform］リストから、Gear VRの場合は[Android]を選び、［Switch Platform］をクリックしてください。
4. それから［Player Settings...］をクリックして、Inspectorパネルを見てください。
5. ［Virtual Reality Supported］チェックボックスのチェックを外した状態にします。
6. ［Build And Run] ボタンを押します。

---
端末にアプリが転送されて実行されます。
Cardboardに端末をセットして見てみましょう。

---

#自分も歩く（一人称視点）

これまでは自分は同じ位置にいて周りを見回すだけでした（三人称視点）。
自分自身も動けるようにしてみましょう。

頭を向けている方向のベクトルを検出し、その方向に進むようにします。

---
###歩きだすトリガー

Cardboardのボタンを押すと歩き出し、もう一度押すと止まるようにします。

---
####クリック検出スクリプト

1. Projectウィンドウで、Create → Folder の順に操作し、 Scripts というフォルダを作成します。
2. 作成した Scripts フォルダを選択して右クリックし、 Create → C# Script の順に操作して、 Clicker.cs という名前をつけて、次のように入力します。

```Clicker.cs
using UnityEngine;
using System.Collections;

public class Clicker {
	public bool clicked() {
#if (UNITY_ANDROID || UNITY_IPHONE)
		return GvrViewer.Instance.Triggered;
#else
		return Input.anyKeyDown;
#endif
	}
}
```

---
###自分のオブジェクトを作成します

カメラオブジェクトを動かすと、視点が移動して自分が動いているように見せることができます。

1. Game Objectメニューから、Create Empty を選択し、MySelf と名前をつけます。
2. Hierarchyビューの中で、Main Camera を MySelf の下の階層になるよう移動します。
3. MySelfを選択してInspectorで Add Component ボタンを押し、Physics → Character Controllerを追加します。
3. MySelf を選択して Inspector の Add Component を押してスクリプトを追加し、HeadLookWalkと名前をつけます。

---
#### 歩くためのスクリプト

HeadLookWalkをダブルクリックして、次のように入力します。

```HeadLookWalk.cs
using UnityEngine;
using System.Collections;

public class HeadLookWalk : MonoBehaviour {
	public float velocity = 0.7f;
	public bool isWalking = false;

	private CharacterController controller;
	private Clicker clicker;

	// Use this for initialization
	void Start () {
		controller = GetComponent<CharacterController> ();
		clicker = new Clicker ();
	}
	
	// Update is called once per frame
	void Update () {
		if (clicker.clicked ()) {
			isWalking = !isWalking;
		}
		if (isWalking) {
			Vector3 moveDirection = Camera.main.transform.forward;
			moveDirection *= velocity * Time.deltaTime;
			moveDirection.y = 0.0f;
			controller.Move (moveDirection);
		}
	}
}
```

---
プレビューで試してみましょう。
マウスを押すと視点が動き出します。

---
###端末で動かしてみましょう

Cardboardのボタンを押す（画面をタップ）とカメラ（自分自信）が動き出します。

---
##自分の体を得る

ドロイド君の体と手を追加してみましょう。

床面に影が映るのを見ると、自分がドロイド君になった気持ちになれるかもしれません(^^

---
###ドロイド君の体の作製

体はシリンダー、手はカプセル

####体　
MySelfの下の階層に Cylinder を追加します。

* Position 0, -0.58, 0
* Rotation 0, 0, 0
* Scale 0.7, 0.35, 0.7

---
####腕

1. Main Cameraの下の階層に空の Game Object を追加して Body と名前をつけます。
2. Body の下の階層に空の Game Object を追加して RightArm と名前をつけます。
    3. Position 0.371, 0, 0.566
3. RightArm の下に Capsule を追加します。
    4. Position -0.015, 0, 0.112
    5. Rotation 90, 0, 0
    6. Scale 0.1, 0.2, 0.1
7. RightArm をCopy & Paste して LeftArm と名前を変えて左手にします。
    8. RightArm も Body の下の階層にあることを確認します。
    9. Position -0.34, 0, 0.566

---
### 色を設定しましょう

せっかくなのでドロイド君に緑色のマテリアルを設定します。

---
### カメラのポジションの設定

ドロイド君の影が見えるようにカメラの位置を調整します。

MainCamera

* Position 0, -0.29, 0


---

##Daydreamコントローラー

コントローラーを使って右手を動かしてみましょう

---
###コントローラを扱うためのプレハブ

Assets/GoogleVR/Prefabs/Controller の下にある GvrControllerMain をシーンにドラッグ＆ドロップします。


### これ以降はUnityのDaydream Technology Preview版が必要になります...
こちらからダウンロードします。
https://unity3d.com/jp/partners/google/daydream

~~全員でダウンロードを始めるとWiFiがパンクして大変なことになるので、少々裏技を...(^^;~~

---
~~####Google VR SDK for Unityの古いバージョンを使えば、とりあえず動くことを確認できます。~~

~~Google VR SDK for Unity 0.9.1~~
~~https://github.com/googlevr/gvr-unity-sdk/raw/5a02da736744eb5970e04d36c251231a1f5ab201/GoogleVRForUnity.unitypackage~~

~~あくまでこの場での回避策ということでご了承ください m(_ _)m~~

---
###スクリプトの追加

右手のオブジェクト RightArm に ArmControl という名前でスクリプトを追加します。

```ArmControl.cs
using UnityEngine;
using System.Collections;

public class ArmControl : MonoBehaviour {
	// Update is called once per frame
	void Update () {
		transform.rotation = GvrController.Orientation;
	}
}
```

---
##応用例
たくさん手を振ったらユニティちゃんがこっちを向いて微笑んでくれるとか...(^^

---

<div><img src="http://unity-chan.com/images/imageLicenseLogo.png" alt="ユニティちゃんライセンス"><p>この作品は<a href="http://unity-chan.com/contents/license_jp/" target="_blank">ユニティちゃんライセンス条項</a>の元に提供されています</p></div>