Unityで3Dシューティングアクションを作るチュートリアル④

#体力ゲージ、ゲームオーバー、ゲームクリア
#体力ゲージの設定は以下の手順を踏みます。
1. HandleSlideAreaを削除する(これをしないとツマミが残った状態になります)。　
2. CanvasのUI Scale ModeをScale With Screenに変える。
   これは体力ゲージの表示の仕方を変えています。
　 画面の大きさに合わせて表示するようにしています。
3. 体力ゲージの位置調整を行います。作業画面だと変な位置に見えるのですがフル画面で再生するとちょうど良い位置に
   なるように調整して下さい。
4. 体力ゲージの土台の色を変えます。ダメージを受けている部分です。
5. 体力ゲージのメインの色を変えます。残り体力の部分です。

※位置が調整しにくいのですが、画像を参考に調整してみてください。

![スライド148.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/6b9527ba-741b-1f6c-014e-8bc816054d4c.png)

![スライド149.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/b845c946-6025-46e9-9606-68eb423037f6.png)

![スライド150.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/47dcf183-222e-0191-9a04-2423d88bc576.png)

![スライド151.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/6a228fff-8fa1-49e9-13cf-d0edddcbf647.png)

![スライド152.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/0006ae8e-af69-ec1b-33ec-ec862a1d936f.png)

![スライド153.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/5f585f9b-5e69-845b-1f92-6462d7280797.png)

#Playerスクリプトに追記していきます。該当する場所に追記していきます。

#using~の追記内容

```csharp
using UnityEngine.UI;
```

#using~の説明
<details><summary>**using UnityEngine.UI;**
</summary>UnityのUI機能を使用する場合に追加します。
UI機能とはUserInterfaceの略で今回の体力ゲージであったり、画面上に表示されるボタンや
画像や文字などのことを指します。</details>

#変数を宣言する部分の追記内容

```csharp
private float PlayerHP;
public GameObject slider;
private Slider _slider;
```

#変数を宣言する部分の説明
<details><summary>**private float PlayerHP;**
</summary>プレイヤーのHPを定義しています。ダメージを受けた時に、
この数値を減らすことによってダメージ処理を行います。</details>

<details><summary>**public GameObject slider;**
</summary>sliderとはどのゲームオブジェクトのことを指すのか定義しています。</details>

<details><summary>**private Slider _slider;**
</summary>体力ゲージの値を_sliderと定義しています。</details>

#void Startの追記内容

```csharp
_slider = slider.GetComponent<Slider>();
PlayerHP = 5;
```

#void Startの説明

<details><summary>**_slider = slider.GetComponent<Slider>();**
</summary>_sliderにSliderの値を代入しています。</details>

<details><summary>**PlayerHP = 5;**
</summary>PlayerHPを5にする。
ゲーム開始時のプレイヤーの体力を5に設定しています。
必ずスライダーのValueのMax値と同じにして下さい。7</details>

#void Updateの追記内容

```csharp
_slider.value = PlayerHP;
```
 
#void Updateの説明
<details><summary>**_slider.value = PlayerHP;**
</summary>_sliderの値をPlayerHPの値と同じにしています。これによりPlayerHPが減ると_sliderの値も減り、
ゲージも変化します。</details>

#コルーチンの内容

```csharp
IEnumerator Damage()
    {
        PlayerHP -= 1;
        yield return new WaitForSeconds(0.5f);
    }
```

#コルーチンの説明
<details><summary>**IEnumerator Damage()**
</summary>Damageコルーチンを定義しています。</details>

<details><summary>**PlayerHP -= 1;**
</summary>PlayerHPを1減らしています。</details>

<details><summary>**yield return new WaitForSeconds(0.5f);**
</summary>0.5秒待ちます。この待ち時間を入れないとダメージを受けた時に一気に体力が減ってしまいます。</details>

#衝突判定の内容

```csharp
void OnTriggerEnter(Collider collision)
    {
        if (collision.gameObject.tag == "Enemyattack")
        {
            StartCoroutine("Damage");
        }
    }
```

#衝突判定の説明

<details><summary>**void OnTriggerEnter(Collider collision)**
</summary>衝突判定の内容をここから記入します。</details>

<details><summary>**if (collision.gameObject.tag == "Enemyattack")**
</summary>もし衝突したオブジェクトのタグがEnemyattackなら</details>

<details><summary>**StartCoroutine("Damage");**
</summary>Damageコルーチンを開始します。</details>

#完成形のスクリプト
追記内容は※6と表示しています。

```csharp:Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//※6

public class Player : MonoBehaviour
{

    private CharacterController characterController;//※1
    private Vector3 velocity;//※1
    public float walkSpeed;//※1
    private Animator animator;//※2
    public GameObject bullet;//※3
    public Transform muzzle;//※3
    public float speed = 1000;//※3
    private float PlayerHP;//※6
    public GameObject slider;//※6
    private Slider _slider;//※6

void Start()//ゲーム開始時に一度だけ実行する内容
    {
        characterController = GetComponent<CharacterController>();//※1
        animator = GetComponent<Animator>();//※2
        _slider = slider.GetComponent<Slider>();//※6
        PlayerHP = 5;//※6
    }

void FixedUpdate()//ゲーム開始時に何度も実行する内容
    {
        if (characterController.isGrounded)//※1
        {
            velocity = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));//※1
            if (velocity.magnitude > 0.1f)//※1
            {
                animator.SetBool("isRunning", true);//※2
                transform.LookAt(transform.position + velocity);//※1
            }
            else//※2
            {
                animator.SetBool("isRunning", false);//※2
            }
        }
        velocity.y += Physics.gravity.y * Time.deltaTime;//※1
        characterController.Move(velocity * walkSpeed * Time.deltaTime);//※1

if (Input.GetMouseButtonDown(0))//※3
        {
         StartCoroutine("shot");//※3
        }

_slider.value = PlayerHP;//※6

}

IEnumerator shot()//※3
    {
        animator.SetBool("Attack", true);//※3
        yield return new WaitForSeconds(0.5f);//※3
        Vector3 force;//※3
        GameObject bullets = GameObject.Instantiate(bullet) as GameObject;　//※3
        bullets.transform.position = muzzle.position;//※3
        force = this.gameObject.transform.forward * speed;//※3
        bullets.GetComponent<Rigidbody>().AddForce(force);//※3
        animator.SetBool("Attack", false);//※3
        Destroy(bullets.gameObject,2); //※3
    }

IEnumerator Damage()//※6
    {
        PlayerHP -= 1;//※6
        yield return new WaitForSeconds(0.5f);//※6
    }

void OnTriggerEnter(Collider collision)//※6
    {
        if (collision.gameObject.tag == "Enemyattack")//※6
        {
            StartCoroutine("Damage");//※6
        }
    }
}
```

![図5.png](https://qiita-image-store.s3.amazonaws.com/0/214359/4f2877e6-3270-1280-aa9f-1334d66596a6.png)

![スライド156.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/cb5cb9ea-db58-c23d-6159-ca0ee3cafa85.png)

![スライド157.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/8a0c9395-7146-589a-8c38-d1a585e9cdaf.png)

![スライド158.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/c3ffd6e3-5c34-0f0d-c092-ec8eadc64bd5.png)

![スライド159.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/e0d4d409-5cba-caf6-76aa-36af4c8b61eb.png)

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/214359/81d05741-9c4b-af0c-7441-b137206e9a10.png)

![図2.png](https://qiita-image-store.s3.amazonaws.com/0/214359/e57f88c0-090f-c364-9ce6-02d150035c73.png)

#テストプレイをしてみると…
![PlayerDamage.gif](https://qiita-image-store.s3.amazonaws.com/0/214359/3060ed4b-8683-9d04-9b34-7e41c773f12f.gif)
敵の攻撃を受けるとダメージを受けてゲージが減っています

![スライド164.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/40932c6d-5ed5-756f-bfec-d0c992dde8fd.png)

![スライド165.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/c6c25304-17bf-e4ac-953c-fd960d6b110a.png)

![スライド166.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/89f05c87-360f-d919-c275-e5538fca4842.png)

![スライド167.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/acb392bb-573d-ac36-fd67-6df2a57d9a3a.png)

![スライド168.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/57c5ce6c-4b34-3815-3523-ce9efd8ce16e.png)

![スライド172.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/b1d2eb96-de4f-70cb-f224-06a3e868d502.png)

![スライド173.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/773c77b4-2930-aac2-6890-f51c6c592e98.png)

![スライド174.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/af9d63a5-411d-93ce-be7a-a2249dcb3d2e.png)

![スライド175.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/30b53524-0840-85d6-fa78-f7a9c814532f.png)

![スライド176.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/ce56ba93-e325-26e8-358e-1c9733776c08.png)

#Playerスクリプトに追記していきます。該当する場所に追記しています。

#using~の記入内容

```csharp
using UnityEngine.SceneManagement;
```

#using~の説明
<details><summary>**using UnityEngine.SceneManagement;**
</summary>シーンの遷移を行う時に追加します。今回はゲームオーバーやゲームクリアを表示する際に
画面を変えるので使用しています。</details>

#void Updateの追記内容

```csharp
if (PlayerHP == 0)
        {
            SceneManager.LoadScene("GameOver");
        }
```

#void FixedUpdateの説明
<details><summary>**if (PlayerHP == 0)**
</summary>もしPlayerHPが0なら。if文で条件を変数の値にする場合、=ではなく、==にします。</details>

<details><summary>**SceneManager.LoadScene("GameOver");**
</summary>シーンをゲームオーバーにします。シーンを変える場合は
SceneManager．LoadScene(”シーンの名前”);です。</details>

#完成形のスクリプト
追記内容は※7と表示しています。

```csharp:Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//※6
using UnityEngine.SceneManagement;//※7

public class Player : MonoBehaviour
{

    private CharacterController characterController;//※1
    private Vector3 velocity;//※1
    public float walkSpeed;//※1
    private Animator animator;//※2
    public GameObject bullet;//※3
    public Transform muzzle;//※3
    public float speed = 1000;//※3
    private float PlayerHP;//※6
    public GameObject slider;//※6
    private Slider _slider;//※6

void Start()//ゲーム開始時に一度だけ実行する内容
    {
        characterController = GetComponent<CharacterController>();//※1
        animator = GetComponent<Animator>();//※2
        _slider = slider.GetComponent<Slider>();//※6
        PlayerHP = 5;//※6
    }

void FixedUpdate()//ゲーム開始時に何度も実行する内容
    {
        if (characterController.isGrounded)//※1
        {
            velocity = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));//※1
            if (velocity.magnitude > 0.1f)//※1
            {
                animator.SetBool("isRunning", true);//※2
                transform.LookAt(transform.position + velocity);//※1
            }
            else//※2
            {
                animator.SetBool("isRunning", false);//※2
            }
        }
        velocity.y += Physics.gravity.y * Time.deltaTime;//※1
        characterController.Move(velocity * walkSpeed * Time.deltaTime);//※1

if (Input.GetMouseButtonDown(0))//※3
        {
         StartCoroutine("shot");//※3
        }

_slider.value = PlayerHP;//※6

if (PlayerHP == 0)//※7
        {
            SceneManager.LoadScene("GameOver");//※7
        }
}

IEnumerator shot()//※3
    {
        animator.SetBool("Attack", true);//※3
        yield return new WaitForSeconds(0.5f);//※3
        Vector3 force;//※3
        GameObject bullets = GameObject.Instantiate(bullet) as GameObject;　//※3
        bullets.transform.position = muzzle.position;//※3
        force = this.gameObject.transform.forward * speed;//※3
        bullets.GetComponent<Rigidbody>().AddForce(force);//※3
        animator.SetBool("Attack", false);//※3
        Destroy(bullets.gameObject,2); //※3
    }

IEnumerator Damage()//※6
    {
        PlayerHP -= 1;//※6
        yield return new WaitForSeconds(0.5f);//※6
    }

void OnTriggerEnter(Collider collision)//※6
    {
        if (collision.gameObject.tag == "Enemyattack")//※6
        {
            StartCoroutine("Damage");//※6
        }
    }
}
```

#テストプレイをしてみると…
※早くゲームオーバーになるように敵を増やしています。
　敵を増やしたい場合はEnemyを選択してCtrl + D で増やして敵を好きな場所に配置して下さい。

![GameOver.gif](https://qiita-image-store.s3.amazonaws.com/0/214359/cdaec00d-b9e4-f770-cbfb-8615f580e069.gif)

体力がなくなったらゲームオーバーになりました。

![スライド179.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/ebfbe18d-aa26-d07c-a996-6922c254ffe2.png)

![スライド180.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/77739f57-7d77-58cb-2066-a7332e5b4fe2.png)

![スライド182.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/d64ea502-bb8f-8dd7-0b1b-6ca4fc48cda9.png)

![スライド183.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/1c9b7fc0-5893-60a3-3a84-673e690e72df.png)

![スライド184.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/4d141d4c-b08e-1c26-bf15-7eac76748071.png)

![スライド185.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/f6364296-9420-e1f3-02c2-092076329441.png)

![スライド186.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/cdb5a2ef-16e1-389a-4d1c-1778051fe47f.png)

![スライド187.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/7d50b3e7-4116-7d14-47fc-d48ba537b0f4.png)

![スライド188.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/3b141faf-5e94-bae2-4c6a-64d983eef59c.png)

![スライド189.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/0aa6b8ed-2cc9-7cb2-5761-6061c3f88f38.png)

![スライド190.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/df8e02aa-7646-bd93-da5a-badf5bd15d6d.png)

#変数を宣言する部分の記入内容

```csharp
private GameObject[] enemyObjects;
```

#変数を宣言する部分の説明
<details><summary>**private GameObject[] enemyObjects;**
</summary>enemyObjectsという配列を作成しています。配列というのは同じ属性を持つ一つのグループのことです。
今回はEnemyというタグがついたオブジェクト全てを指します。つまり敵キャラ全てのことです。く</details>

#void FixedUpdateの追記内容

```csharp
enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");
        if (enemyObjects.Length == 0)
        {
            SceneManager.LoadScene("GameClear");
        }
```

#void FixedUpdateの説明
<details><summary>**enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");**
</summary>配列enemyObjectsが何を指すのかを決めています。今回はEnemyというタグがついたオブジェクト全てに
指定しています</details>

<details><summary>**if (enemyObjects.Length == 0)**
</summary>もしenemyObjectsの数が0なら。先程配列で指定したオブジェクトの数が0になったらという意味で
要するに敵を全員倒したらです。</details>

<details><summary>**SceneManager.LoadScene("GameClear");**
</summary>シーンをGameClearに変えます。</details>

#完成形のスクリプト
追記内容は※8と表示しています。

``````csharp:Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//※6
using UnityEngine.SceneManagement;//※7

public class Player : MonoBehaviour
{

    private CharacterController characterController;//※1
    private Vector3 velocity;//※1
    public float walkSpeed;//※1
    private Animator animator;//※2
    public GameObject bullet;//※3
    public Transform muzzle;//※3
    public float speed = 1000;//※3
    private float PlayerHP;//※6
    public GameObject slider;//※6
    private Slider _slider;//※6
    private GameObject[] enemyObjects;//※8

void Start()//ゲーム開始時に一度だけ実行する内容
    {
        characterController = GetComponent<CharacterController>();//※1
        animator = GetComponent<Animator>();//※2
        _slider = slider.GetComponent<Slider>();//※6
        PlayerHP = 5;//※6
    }

void FixedUpdate()//ゲーム開始時に何度も実行する内容
    {
        if (characterController.isGrounded)//※1
        {
            velocity = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));//※1
            if (velocity.magnitude > 0.1f)//※1
            {
                animator.SetBool("isRunning", true);//※2
                transform.LookAt(transform.position + velocity);//※1
            }
            else//※2
            {
                animator.SetBool("isRunning", false);//※2
            }
        }
        velocity.y += Physics.gravity.y * Time.deltaTime;//※1
        characterController.Move(velocity * walkSpeed * Time.deltaTime);//※1

if (Input.GetMouseButtonDown(0))//※3
        {
         StartCoroutine("shot");//※3
        }

_slider.value = PlayerHP;//※6

if (PlayerHP == 0)//※7
        {
            SceneManager.LoadScene("GameOver");//※7
        }
        enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");//※8
        if (enemyObjects.Length == 0)//※8
        {
            SceneManager.LoadScene("GameClear");//※8
        }
}

IEnumerator shot()//※3
    {
        animator.SetBool("Attack", true);//※3
        yield return new WaitForSeconds(0.5f);//※3
        Vector3 force;//※3
        GameObject bullets = GameObject.Instantiate(bullet) as GameObject;　//※3
        bullets.transform.position = muzzle.position;//※3
        force = this.gameObject.transform.forward * speed;//※3
        bullets.GetComponent<Rigidbody>().AddForce(force);//※3
        animator.SetBool("Attack", false);//※3
        Destroy(bullets.gameObject,2); //※3
    }

IEnumerator Damage()//※6
    {
        PlayerHP -= 1;//※6
        yield return new WaitForSeconds(0.5f);//※6
    }

void OnTriggerEnter(Collider collision)//※6
    {
        if (collision.gameObject.tag == "Enemyattack")//※6
        {
            StartCoroutine("Damage");//※6
        }
    }
}
```

#テストプレイをしてみると…
![clear.gif](https://qiita-image-store.s3.amazonaws.com/0/214359/3b58d49e-21f6-61f3-e4ac-7e65fbed7250.gif)
敵を全員倒すとGameClearのシーンに変わります。

#シーンを変えた時に画面が暗かった時の対応

![スライド202.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/b4cee673-c6cd-5476-0830-b57fd0440890.png)

![スライド203.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/0ba1bc0d-580f-8138-971e-07dfa18343a5.png)

#以上でチュートリアルは終わりです♪
まだまだ基本的な構造だけですがこれでも一通りやればなんとなくUnityの使い方は分かったのではないでしょうか？

それではまた♪

[目次](https://qiita.com/Getabako/items/55daf89bbd2e0998a16c)に戻る

[ゲタバコ先生のホームページ遊びに来てね♪](http://getabako.wp.xdomain.jp/)