LoginSignup
3
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-06-15

体力ゲージ、ゲームオーバー、ゲームクリア

体力ゲージの設定は以下の手順を踏みます。

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

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

スライド148.PNG

スライド149.PNG

スライド150.PNG

スライド151.PNG

スライド152.PNG

スライド153.PNG

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

using~の追記内容

using UnityEngine.UI;

using~の説明

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

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

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

変数を宣言する部分の説明

private float PlayerHP;
プレイヤーのHPを定義しています。ダメージを受けた時に、
この数値を減らすことによってダメージ処理を行います。

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

private Slider _slider;
体力ゲージの値を_sliderと定義しています。

void Startの追記内容

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

void Startの説明

_slider = slider.GetComponent();
_sliderにSliderの値を代入しています。

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

void Updateの追記内容

_slider.value = PlayerHP;

void Updateの説明

_slider.value = PlayerHP;
_sliderの値をPlayerHPの値と同じにしています。これによりPlayerHPが減ると_sliderの値も減り、
ゲージも変化します。

コルーチンの内容

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

コルーチンの説明

IEnumerator Damage()
Damageコルーチンを定義しています。

PlayerHP -= 1;
PlayerHPを1減らしています。

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

衝突判定の内容

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

衝突判定の説明

void OnTriggerEnter(Collider collision)
衝突判定の内容をここから記入します。

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

StartCoroutine("Damage");
Damageコルーチンを開始します。

完成形のスクリプト

追記内容は※6と表示しています。

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

スライド156.PNG

スライド157.PNG

スライド158.PNG

スライド159.PNG

図1.png

図2.png

テストプレイをしてみると…

PlayerDamage.gif
敵の攻撃を受けるとダメージを受けてゲージが減っています

スライド164.PNG

スライド165.PNG

スライド166.PNG

スライド167.PNG

スライド168.PNG

スライド172.PNG

スライド173.PNG

スライド174.PNG

スライド175.PNG

スライド176.PNG

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

using~の記入内容

using UnityEngine.SceneManagement;

using~の説明

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

void Updateの追記内容

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

void FixedUpdateの説明

if (PlayerHP == 0)
もしPlayerHPが0なら。if文で条件を変数の値にする場合、=ではなく、==にします。

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

完成形のスクリプト

追記内容は※7と表示しています。

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

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

スライド179.PNG

スライド180.PNG

スライド182.PNG

スライド183.PNG

スライド184.PNG

スライド185.PNG

スライド186.PNG

スライド187.PNG

スライド188.PNG

スライド189.PNG

スライド190.PNG

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

private GameObject[] enemyObjects;

変数を宣言する部分の説明

private GameObject[] enemyObjects;
enemyObjectsという配列を作成しています。配列というのは同じ属性を持つ一つのグループのことです。
今回はEnemyというタグがついたオブジェクト全てを指します。つまり敵キャラ全てのことです。く

void FixedUpdateの追記内容

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

void FixedUpdateの説明

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

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

SceneManager.LoadScene("GameClear");
シーンをGameClearに変えます。

完成形のスクリプト

追記内容は※8と表示しています。

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
敵を全員倒すとGameClearのシーンに変わります。

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

スライド202.PNG

スライド203.PNG

以上でチュートリアルは終わりです♪

まだまだ基本的な構造だけですがこれでも一通りやればなんとなくUnityの使い方は分かったのではないでしょうか?

それではまた♪

目次に戻る

ゲタバコ先生のホームページ遊びに来てね♪

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2