初めてのVRアプリを構築する
このチュートリアルでは、Unityで初めてのVRアプリを構築する方法を説明しています。基本的なアプリの構築を通して、3Dオブジェクト、コンポーネント、ビルドの設定など、Unityのさまざまな基本概念について説明します。このチュートリアルは、Unityの基本的な概念やインターフェイスに慣れることを目的としているため、Oculus統合パッケージは使用しません。最後まで読み、自分のコンピューターで実行できるVRアプリを完成させてみましょう。
ごくシンプルなゲームアプリを作ります。シーンには、4つの壁に囲まれたプレイエリアと、プレイヤーとなる1個のボールがあります。ゲームの目的は、壁にぶつからないようにしながらボールを転がし続けることです。ボールがいずれかの壁にぶつかると、壁の色が変わり、ぶつかったことを示すテキストが画面に表示されます。入力として、キーボードかUnity互換のジョイスティックを使用する必要があります。
完成形を以下に示します。
このチュートリアルを始める前に、開発環境をセットアップし、必要な設定が完了していることを確認してください。
- ヘッドセットを開発用に設定し、テストモードを有効にします。
- Unity Editorをインストールします。
- 新しいプロジェクトを作成します。
- ビルド設定を構成します。
- VRサポートを有効にします。
このセクションでは、アプリの作成やゲームプレイのメカニズムの基本を説明します。ここでは、ワークフローの中心概念の中でも、このVRアプリを構築する上で役立つものに絞って説明します。Unityのさまざまな概念やワークフローの詳細については、
Unityのユーザーマニュアルをご覧ください。
- シーンは、さまざまなゲームオブジェクトを保持するコンテナです。
- ゲームオブジェクトは、キャラクター、小道具、照明、カメラ、または特殊効果を表す基本的なオブジェクトです。このアプリでは、平面、立方体、球体といった基本的な図形で構成される3Dオブジェクトを使用します。
- コンポーネントは、ゲームオブジェクトの動作を定義します。主に、変換コンポーネントにより、各ゲームオブジェクトの位置、回転、スケールが決まります。値は、プロパティごとにX、Y、Z座標の形で表記されます。位置は、デフォルトで(0,0,0)に設定されます。これは原点とも呼ばれ、シーンのすべての座標計算はそこを基点として実行されます。
- マテリアルは、オブジェクトにテクスチャーと色を追加します。このアプリでは、マテリアルの使用をオブジェクトの色だけに限定し、他の技術的詳細には触れないことにします。
ステップ1. ゲームオブジェクトに色を追加するためのマテリアルを作成します。
どんなアプリの設計においても、色とテクスチャーの追加は基本事項として必ず必要とされます。マテリアルにより、色、シェーダー、テクスチャーなどのさまざまな外観上の効果を定義できます。このアプリでは、マテリアルの使用をオブジェクトの色の追加のみに限ることにします。
- [Project (プロジェクト)]ビューの[Assets (アセット)]フォルダーの中に、アプリのさまざまなゲームオブジェクトのマテリアルをいれるための新しいフォルダーを作成し、その名前をMaterialsに変更した後、そのフォルダーをダブルクリックして開きます。
- メニューで[Assets (アセット)] > [Create (作成)] > [Material (マテリアル)]を選び、そのマテリアルの名前をfloor-colorに変更します。
[Inspector (インスペクター)]ビューの[Main Maps (メイン地図)]の下で、Albedo色フィールドをクリックして色選択ツールを開き、選択する色を変更します。このアプリでは(3,32,70)のRGB値を使用します。

ステップ2~4を繰り返して、壁、プレイヤーボール、および衝突時の壁の色の変更のためのマテリアルを作成します。それらの名前をそれぞれwall-color、ball-color、after-collisionに変更し、RGB値をそれぞれ(255,255,255)、(240,240,0)、(241,107,8)に設定します。

ステップ2. フロア、プレイヤーボール、4つの壁を作成します。
このアプリのゲームオブジェクトは、フロア、ボール、4つの壁であり、それぞれストックのUnity平面、球体、および立方体を使用して作成します。
フロア:
- メニューで[Game Object (ゲームオブジェクト)] > [3D Object (3Dオブジェクト)] > [Plane (平面)]に移動します。
- [Hierarchy (階層)]ビューで、その名前をfloorに変更します。
- [Inspector (インスペクター)]ビューの[Transform (変換)]の下で、その位置が原点、つまり(0,0,0)であることを確認します。そうでない場合は、(0,0,0)にリセットしてください。
- [Transform (変換)]の下で、スケールを(2,1,2)に設定し、フロアを大きくします。平面オブジェクトは平らなので体積はありません。したがって、デフォルトでY値は1に設定されます。
floor-colorマテリアルを平面上にドラッグ&ドロップし、色を追加します。

プレイヤーボール:
- メニューで[Game Object (ゲームオブジェクト)] > [3D Object (3Dオブジェクト)] > [Sphere (球体)]に移動します。
- [Hierarchy (階層)]ビューで、その名前をplayer-ballに変更します。
- Materialsフォルダーから球面にball-colorをドラッグ&ドロップします。
[Inspector (インスペクター)]ビューの[Transform (変換)]の下で、位置が(0,0,0)に設定されていることを確認した後、Y値を0.5に設定して(0,0.5,0)とし、ボールをフロアの上に置きます。

4つの壁:
- メニューで[Game Object (ゲームオブジェクト)] > [3D Object (3Dオブジェクト)] > [Cube (立方体)]に移動します。
- Materialsフォルダーから立方体にwall-colorをドラッグ&ドロップします。
- [Inspector (インスペクター)]ビューの[Transform (変換)]で、位置を(0,0,0)にリセットした後、スケールを(0.5,2,20.5)に設定して、壁がちょうどフロアの境界に合うように引き伸ばします。
[Hierarchy (階層)]ビューで、立方体を右クリックして、次の手順を実行します。
a.立方体の名前をfirst-wallに変更します。
b.立方体を3回複製して3つの壁を追加し、それぞれの名前をsecond-wall、third-wall、fourth-wallに変更します。
- [Hierarchy (階層)]ビューでthird-wallを選択し、[Inspector (インスペクター)]ビューの[Transform (変換)]で、回転を(0,90,0)に設定します。この手順をfourth-wallについても繰り返します。
[Hierarchy (階層)]ビューでfirst-wallを選択し、[Inspector (インスペクター)]ビューの[Transform (変換)]で、壁の位置として以下に示す値を入力して、壁がフロアの四方を囲むようにします。このステップを残りの壁についても繰り返します。
first-wallは(-10,0,0)
second-wallは(10,0,0)
third-wallは(0,0,10)
fourth-wallは(0,0,-10)

ステップ3: カメラとライティングを調整します。
メインのカメラとライティングを調整して、シーンの見栄えを良くします。
- [Hierarchy (階層)]ビューで[Main Camera (メインカメラ)]を選択します。
- [Inspector (インスペクター)]ビューの[Transform (変換)]で、位置を(0,10,-20)に、また回転を(20,0,0)に設定します。
- [Hierarchy (階層)]ビューで[Directional Light (平行光源)]を選択します。
- [Inspector (インスペクター)]ビューの[Transform (変換)]で、回転を(50,60,0)に設定します。
ステップ4: プレイヤーボールに動きを追加します。
- [Hierarchy (階層)]ビューでplayer-ballを選択します。
[Inspector (インスペクター)]ビューで、次の手順を実行します。
a.[Add Component (コンポーネントの追加)] > [Physics (物理演算)] > [Rigidbody]をクリックします。

b.[Add Component (コンポーネントの追加)] > [New Script (新しいスクリプト)]をクリックし、名前をPlayerControllerに設定した後、[Create and Add (作成して追加)]をクリックします。
c.PlayerControllerスクリプトの横にある歯車アイコンをクリックし、[Edit Script (スクリプトを編集)]をクリックして、コードエディタでそれを開きます。

d.サンプルコードを次のコードに置き換えて、キーボードからの入力を取得し、ボールを動かすための力を加えます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Appears in the Inspector view from where you can set the speed
public float speed;
// Rigidbody variable to hold the player ball's rigidbody instance
private Rigidbody rb;
// Called before the first frame update
void Start()
{
// Assigns the player ball's rigidbody instance to the variable
rb = GetComponent<Rigidbody>();
}
// Called once per frame
private void Update()
{
// The float variables, moveHorizontal and moveVertical, holds the value of the virtual axes, X and Z.
// It records input from the keyboard.
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
// Vector3 variable, movement, holds 3D positions of the player ball in form of X, Y, and Z axes in the space.
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
// Adds force to the player ball to move around.
rb.AddForce(movement * speed * Time.deltaTime);
}
}
[Inspector (インスペクター)]ビューのPlayerControllerスクリプトの[Speed (速度)]に、速度の値を入力します。例えば、500とします。この変数は、ステップ4.2.dのPlayerControllerスクリプトで宣言したのと同じspeed変数です。

上部のプレイボタンをクリックして、アプリをプレビューします。キーボードの矢印キーを押して、ボールを転がします。
ステップ5. テキストを追加します。
- メニューで[Game Object (ゲームオブジェクト)] > [UI] > [Text (テキスト)]に移動します。
- [Hierarchy (階層)]ビューで、Textを選択し、その名前をmessageに変更します。
- テキストがプレイヤーにどのように表示されるかをプレビューするために、[Scene (シーン)]表示タブから[Game (ゲーム)]表示タブに切り替えます。
- [Inspector (インスペクター)]ビューの[Rect Transform (長方形変換)]で、テキストの位置を指定します。必要なら、フォントの色やフォントサイズを変更することもできます。
ステップ6. ボールが衝突状態に入ったとき、または衝突状態から出たときの壁と表示テキストの色を変更します。
衝突は、ボールが壁に当たった時点で発生します。衝突をハイライトするための効果を追加することができます。例えば、ボールが壁に衝突した時点で、画面上で壁の色が変わり、「Ouch! (おっと!)」というテキストが表示されるという具合です。一方、ボールが再び転がる状態になったなら、壁の色が元の色に戻り、「Keep Rolling...(うまく転がしてね...)」というテキストが画面に表示されます。
- [Hierarchy (階層)]ビューでfirst-wallを選択します。
- [Inspector (インスペクター)]ビューで、[Add Component (コンポーネントの追加)] > [New Script (新しいスクリプト)]をクリックし、名前をColorControllerに設定した後、[Create and Add (作成して追加)]をクリックします。
- ColorControllerスクリプトの横にある歯車アイコンをクリックし、[Edit Script (スクリプトを編集)]をクリックして、コードエディタで開きます。
サンプルコードを次のコードに置き換えます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ColorController : MonoBehaviour
{
public Material[] wallMaterial;
Renderer rend;
// Appears in the Inspector view from where you can assign the textbox
public Text displayText;
// Start is called before the first frame update
void Start()
{
// Assigns the component's renderer instance
rend = GetComponent<Renderer>();
rend.enabled = true;
displayText.text = "";
}
// Called when the ball collides with the wall
private void OnCollisionEnter(Collision col)
{
// Checks if the player ball has collided with the wall.
if (col.gameObject.name == "player-ball")
{
displayText.text = "Ouch!";
rend.sharedMaterial = wallMaterial[0];
}
}
// It is called when the ball moves away from the wall
private void OnCollisionExit(Collision col)
{
if (col.gameObject.name == "player-ball")
{
rend.sharedMaterial = wallMaterial[1];
displayText.text = "Keep Rolling...";
}
}
}
- [Hierarchy (階層)]ビューでfirst-wallを選択します。
[Inspector (インスペクター)]ビューのColorControllerスクリプトで、次の手順を行います。
a.[Wall Material (壁のマテリアル)]を展開して[Size (サイズ)]に2を入力し、[Element 0 (要素0)]と[Element 1 (要素1)]に、after-collisionとwall-colorをそれぞれドラッグ&ドロップします。
b.[Display Text (テキストを表示)]の横の歯車アイコンをクリックしてmessageを選択します。この[Display Text (テキストを表示)]は、ステップ6.4でColorController.csスクリプト内に宣言したのと同じフィールドです。

- [Hierarchy (階層)]ビューでsecond-wallを選択します。
- [Inspector (インスペクター)]ビューで[Add Components (コンポーネントの追加)] > [Scripts (スクリプト)]をクリックし、リストからColorControllerを選択した後、ステップ6を繰り返します。
- 残りの壁についてステップ7とステップ8を繰り返します。
- 上部のプレイボタンをクリックして、アプリをプレビューします。キーボードの矢印キーを押して、ボールを転がします。
ステップ7. アプリをビルドして実行します。
ビルド設定で選択したターゲットプラットフォームに応じて、Androidの場合は.apkファイル、Windowsの場合は.exeファイルがUnityによってビルドされます。ここではOculus統合パッケージを使用しなかったため、このアプリをMeta Questコントローラーで実行することはできません。
- シーンを保存します。
- [File (ファイル)] > [Build and Run (ビルドして実行)]に移動します。
- ファイルをダブルクリックすると、アプリがコンピューター上で実行されます。入力として、キーボードまたはUnity互換ジョイスティックを使用します。