【自由研究】Unityで逃走ゲームを作る

# Unityとは

- **Unity**とは、ゲームなどを作成するための支援をしてくれるソフト。
- **Unity**は、ハイクオリティな作品の作成が可能で、操作方法もわかりやすい。

# Unityで作られた有名なゲーム

- スーパーマリオラン
- 白猫プロジェクト
- ドラゴンクエスト８（スマホ版）
- ポケモンGO

など多数。

# アセットストアとは

- ほかのユーザーが作成したプログラムの部品や素材を、有料または無料で販売されている。
- キャラクター、テクスチャ、オーディオ、スクリプトなどが手に入るので、ゲームの作成が楽にできる。
- 自分のアセットを販売することもできる。

# 作るゲーム

- オオカミから逃げて、ゴール（玉）を目指す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/f67d08ee-4e2d-589d-174e-5fa5cccf4786.png)

# プロジェクトの作成

- `Create Project`から、プロジェクトを作成する。 

# 必要なアセットのインポート

- 以下のアセットをインポートする。
    - `Standard Assets`
    - `01_kohaku_B`
    - `Mecanim Locomotion Starter Kit`をインポートする。

### `Standard Assets`のインポート

- Unityメニュー→ウィンドウ→アセットストア→`standard assets`で検索→`Standard Assets`を選択（→ダウンロード）→インポート→ダイアログのインポート

### `01_kohaku_B`のインポート

- `http://unity-chan.com/` →右上ダウンロード→規約に同意してダウンロード→制服ユニティちゃん→ダウンロード
- Unityのメニュー→アセット→パッケージをインポート→カスタムパッケージで、先ほどダウンロードしたファイルを選択→ダイアログのインポート

### `Mecanim Locomotion Starter Kit`のインポート

- Unityメニュー→ウィンドウ→アセットストア→`mecanim locomotion`で検索→`Mecanim Locomotion Starter Kit`を選択（→ダウンロード）→インポート→ダイアログのインポート


### オオカミのインポート

- Free3Dから、「オオカミ」のダウンロード
    - `https://free3d.com`  で、検索欄に「オオカミ」と入力して、検索する。
    - `オオカミの装備とゲームの準備完了`をクリック、ダウンロード。
    - `利用可能なファイル`から、`k2yeh64fmm0w-Wolf-Rigged-and-Game-Ready.zip`をダウンロード
    - 保存→解凍→`Wolf.unitypackage`
    - Unityのアセット→パッケージをインポート→カスタムパッケージで、`Wolf.unitypackage`をインポートする。
    - Assetフォルダ直下に2つのWolfファイルができている。
        - `Wolf.fbx`は何も設定されていないファイル。
        - `Wolf.prefab`は、設定済みのファイル。
        - ここでは、`Wolf.fbx`を使う。
        - `Wolf.fbx`を選んで、インスペクターを表示→「Wolfのインポート設定」画面→Rigボタン→アニメーションタイプ→古い機能→適用する（狼の姿が消えるが問題ない）
        - Animation→ラップモード→ループ
        - クリップ→`Wolf_Skeleton|Wolf_Run_Cycle_`→(その下の)ラップモード→ループ→適用する 

# 舞台の作成

- ゲームオブジェクト→3Dオブジェクト→Trrain（地形）→ ⚙（歯車アイコン）→Trrain（地形）の設定
- `メッシュ解像度(Trrain（地形）)`の横幅300、奥行き300、高さ400にする。（単位はメートル）
- `樹木とディテールのオブジェクト`の「詳細表示されるカメラの距離」にも最大値の250を設定する。

### 自然を作成する

- 地図の全体を上から見渡せるようにする（ギズモなどを利用して）
- 自然を作成する。木々を配置する。
- 山の地形を作る
    - Terrainのインスペクター→筆を選択→その下のプルダウンで、`Raise or Lower Terrain`を選択→一段階小さいブラシを選択
    - クリックすると山が高くなり、シフトを押しながらクリックすると山が低くなる
- テクスチャを貼る
    - Terrainのインスペクター→筆を選択→その下のプルダウンで、`Paint Texture`を選択→Terrain（地形）レイヤーの編集ボタンをクリック→Create Layer→GrassHillAlbedo
- 草を生やす
    - 上記の、筆のアイコンの2つ右の☘（クローバーアイコン）をクリック→下にあるディテールの編集ボタンをクリック→`Add Grass Texture'をクリック
    - ダイアログが出るので、Detail Textureの右の◯を押して、`GrassFront01AlbedoAlpha`を選び、Addボタンを押す。
    - ブラシサイズを10にして、塗る
- 木々を生やす
    - 上記の、筆とクローバーの間の🌴（木のアイコン）をクリック、樹木を編集ボタン→`Add Tree`→`Tree Prefab`の◯アイコンをクリック→`Broadleaf_Mobile`を選択→`Add`
    - 樹木の密度を50程度にして塗る。
- 自然の中を散策する
    - プロジェクト→Assets→Standard Assets→Characters→Prefabs→FPSControllerを適当な場所に置く→Main Cameraのチェックは外す→キーボード、マスで散策できる。
- 空の背景を設定する
    - アセットストアから`Sky5X One`をインポートする→
    - Unityメニュー→ウィンドウ→レンダリング→ライティング設定→スカイボックスマテリアルの右の◯をクリック→sky5X2を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/eae82f12-334c-4ab5-5f54-19389e0e804a.png)


### ゴールを設定する。

- ゲームオブジェクト→3Dオブジェクト→スフィア
    - プロジェクトの作成→マテリアルで、Yellowのマテリアルを作成して、スフィアに適用させておく。
- スフィアのインスペクターを表示して、トランスフォームの「拡大／縮小」のX,Y,Zに2を設定して、サイズを大きくしておく。
- 好きな場所（平地）のゴールを設定する。
- スフィアを光らせておく。
    - ゲームオブジェクト→ライト→スポットライト
    - スポットライトのインスペクターを表示し、ライトのタイプにポイント、範囲に14、色は赤色、強度には5を指定する。
    - 下のほうにある、ハローの描画には必ずチェックを付けておく。（ハローは光の輪っか）
    - 場所は、スフィアと重なるように手動で合わせるっぽい。

# `01_kohaku_B`の設定

- プロジェクト→UnityChanTPK→Models→01_kohaku_B→Prefebsフォルダにある、`01_kohaku_B`を適当な場所に置く
- `01_kohaku_B`が見やすいようにMain Cameraを移動する。
- `01_kohaku_B`の名前を`Target`に名前を変更しておく

### `01_kohaku_B(Target)`が、キーボードで操作できるように設定する

- ヒエラルキーのTargetを選択して、インスペクターのControllerの右の◯をクリック→`Locomotion`を選択。（`Locomotion`とは、`Mecanim Locomotion Starter Kit`に含まれているコントローラー）
- インスペクターの`コンポーネントを追加`をクリック→`Physics`（物理）→`Character Controller`（キャラクターコントローラー）を追加する。
    - 中心のYを1に設定しておく（1に設定しておかないと少し浮いてしまう）
    - スロープ制限を90にする（90度の直角のスロープでも登れるようにする）
- インスペクターの`コンポーネントを追加`をクリック→`スクリプト`→`Locomotion Player`を追加する。
- 同じインスペクター内の`Spring Manager(Script)`は⚙（歯車）から削除する。
- プログラムを実行すると、`01_kohaku_B(Target)`がキーボードで操作できるようになった。

### `Target(01_kohaku_B)`をカメラがついていくようにする

- `01_kohaku_B(Target)`のタグを`Player`にする。
- プロジェクトの`Standard Assets`→`Cameras`→`Prefebs`の中にある`FreeLookCameraRig`をTargetの近くに置く。
- `FreeLookCameraRig`の`Auto Target Player`にチェックが付いていることを確認する。（タグが`Player`のキャラクターを追いかける）
- `FreeLookCameraRig`の`Move Speed`を5、`Turn Speed`を4にする。
- `Main Camera`を削除する。

# 追跡者（オオカミ）の配置

- `Assets`フォルダ直下の、`Wolf.fbx`をTargetから離れた場所に配置する。
- 名前を`Wolf1`に変更しておく。

### ナビゲーションの設定を行う

> - ナビゲーションシステムは、ゲームの世界を動き回るキャラクターの作成を可能にするもの。
> - このシステムによって、二階へ行くためには階段を使用し、溝を越えるためにはジャンプしたりしなければならないことをキャラクターに理解させるすることができる。

- ナビゲーションのタブがインスペクターの横にない場合、Unityメニューから、`ウインドウ`→`AI`→`ナビゲーション`で表示させておく。
- ヒエラルキーから、画面内で動かないもの（「Terrain」「Sphere」「Spot Light」）をシフトキーを押しながら選んで、インスペクターウィンドウ右上の`静的`にチェックを付ける→その状態から、ナビゲーションタブ上の`ベイク`ボタンを押す→右下`Bake`ボタンを押すと、水色のオオカミが動く範囲が自動的に判断される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/b9512232-eb67-b2da-f1b9-2c7e7b813043.png)

> 水色にならない場合は、自分の環境では、`ウィンドウ`→`レイアウト`→`初期出荷時に戻す`で表示された。

### Wolf(Wolf1)のインスペクターの設定

- ヒエラルキーから`Wolf1`を選ぶ→インスペクター→アニメーション右の◯をクリック→`Wolf_Skeleton|Wolf_Run_Cycle_`を選ぶ
- コンポーネントを追加→`Agent`で検索→`Nav Mesh Agent`を追加
- コンポーネント追加から、RigitBody（リジッドボディ）と、Box Colider（ボックスコライダー）を追加する。以下のようにコライダの大きさを調節する。(当たり判定の部分）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/0e293960-aab5-9214-09f5-6de955b2d342.png)

- 追跡するスクリプトを追加する。
    - ヒエラルキーから`Wolf1`を選び、`コンポーネントを追加`→`新しいスクリプト`→`KohakuTargetScript`と入力→`作成して追加`
    - Visual Studioから、以下のコードを入力して、`ビルド`→`ソリューションのビルド`→Visual Studioを閉じる

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class KohakuTargetScript : MonoBehaviour
{
    public GameObject target;
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        agent.destination = target.transform.position;
    }
}
```

- インスペクターの`Kohaku Taget Script`の`ターゲット`に、`01_kohaku_B(Target)`をドラッグ・アンド・ドロップする。

> - ここで実行すると、オオカミが追いかけてくるようになる。

### 自然の中のいろいろな所にオオカミを配置する

- ヒエラルキーの`Wolf1`をコピーして、`Wolf2`～`Wolf8`を作成し、適当な場所に置く。
- オオカミの速度をランダムになるようにスクリプトを追加する。
  - `Wolf1`～`Wolf8`を選択して、インスペクターの`コンポーネント追加`→`New Script`→`WolfSpeedScript`と入力して作成する。
  - Visual Studioから、以下のコードを入力して、`ビルド`→`ソリューションのビルド`→Visual Studioを閉じる
    
```csharp

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class WolfSpeedScript : MonoBehaviour
{
    float speedRandom;
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }
    void Update()
    {
        speedRandom = Random.Range(3.0f, 6.0f);
        agent.speed = speedRandom;
    }
}
```

# テキストの配置

- Unityメニュー→`ゲームオブジェクト`→`UI`→`テキスト`で、テキストを追加。名前を`Text`→`MessageText`に変更する。
- `Canvas`を選択→`キャンパススケーラ`→`UIスケールモード`→`画面サイズに拡大`
- ヒエラルキーからMessageTextを選択→`矩形トランスフォーム`の幅350、高さ50にする。
- テキストに、`Game Over!`と入力する。
- フォントスタイルをボールドに、フォントサイズを30に、色は赤にする。
- 実行してみて、真ん中に来るように配置する。
- ゲームオーバー時には、スクリプトで表示させるので、テキストは消しておく（空にする）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/948fc172-503a-46ce-c07e-f98d3c41a4ff.png)

### Game Overのスクリプトを書く

- ヒエラルキーから、`01_kohaku_B(Target)`を選んで、コンポーネント追加→スクリプト追加で、`ResultScript`という名のスクリプトを作成する。
- Visual Studioから、以下のコードを入力して、`ビルド`→`ソリューションのビルド`→Visual Studioを閉じる

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class ResultScript : MonoBehaviour
{
    Text text;
    GameObject obj;
    GameObject wolf1;
    GameObject wolf2;
    GameObject wolf3;
    GameObject wolf4;
    GameObject wolf5;
    GameObject wolf6;
    GameObject wolf7;
    GameObject wolf8;
    bool flag;
    private void Start()
    {
        obj = GameObject.Find("MessageText");
        wolf1 = GameObject.Find("Wolf1");
        wolf2 = GameObject.Find("Wolf2");
        wolf3 = GameObject.Find("Wolf3");
        wolf4 = GameObject.Find("Wolf4");
        wolf5 = GameObject.Find("Wolf5");
        wolf6 = GameObject.Find("Wolf6");
        wolf7 = GameObject.Find("Wolf7");
        wolf8 = GameObject.Find("Wolf8");
        text = obj.GetComponent<Text>();
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if (hit.gameObject.name == "Wolf1" || hit.gameObject.name == "Wolf2"
            || hit.gameObject.name == "Wolf3" || hit.gameObject.name == "Wolf4"
            || hit.gameObject.name == "Wolf5" || hit.gameObject.name == "Wolf6"
            || hit.gameObject.name == "Wolf7" || hit.gameObject.name == "Wolf8")
        {
            text.text = "Game Over!";
            StartCoroutine("BeginFirstScene");
        }
        if (hit.gameObject.name == "Goal")
        {
            text.text = "逃走成功!";
            flag = true;
            StartCoroutine("BeginFirstScene");
        }
    }

    public IEnumerator BeginFirstScene()
    {
        if (flag)
        {
            wolf1.SetActive(false);
            wolf2.SetActive(false);
            wolf3.SetActive(false);
            wolf4.SetActive(false);
            wolf5.SetActive(false);
            wolf6.SetActive(false);
            wolf7.SetActive(false);
            wolf8.SetActive(false);
        }
        yield return new WaitForSeconds(2.0f);
        SceneManager.LoadScene("NavMeshAgent_Game");
    }
}
```

- 現在のシーンを別名で保存する。シーン名右クリック→`NavMeshAgent_Game`で保存。
- Unityメニュー→`ファイル`→`ビルド設定`→`シーンを追加`ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/55f9ae83-761d-251e-1e1b-91c7dde1c239.png)

# 音楽の設定

- アセットストアから`Loop Music Free`をダウンロード、インポートする。
- Unityメニューの`ゲームオブジェクト`→`空のオブジェクトを作成`→`Music`に名前を変更する。
- `Music`を選んで、`コンポーネント追加`→`オーディオ`→`オーディオソース`→`オーディオクリップ`の右の◯をクリックして好きな音楽を選択。
- `ループ`にチェックを付ける

# ゲームの完成

- 逃走成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/96400be5-6bd5-d681-ef3e-86dcdb8ab7ae.png)

- ゲームオーバー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/07f271da-b569-9149-71f9-6b76bc234874.png)


# ゲームのカスタマイズ（発展学習）

- アセットストアから検索して、以下のような変更をしてみる。
  - 主人公（逃走者）のキャラクターを変えてみる。
  - 敵（オオカミ）のキャラクターを変えてみたり、数を変えてみる。
  - 空の背景を変えてみる。
  - 音楽を変えてみる。

参考：[小学生がスラスラ読める すごいゲームプログラミング入門 日本語Unityで3Dゲームを作ってみよう！ ](https://www.shuwasystem.co.jp/book/9784798057347.html)