Unity

Unityで3Dシューティングアクションを作ろう④

投稿日:

今回やること

  • 体力ゲージ
  • ゲームオーバー
  • ゲームクリア
  • シーンを変えた時に画面が暗かった時の対応

体力ゲージ

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

  • HandleSlideAreaを削除する(これをしないとツマミが残った状態になります)。
  •  

  • CanvasのUI Scale ModeをScale With Screenに変える。
    ※これは体力ゲージの表示の仕方を変えて、画面の大きさに合わせて表示するようにしています。
  • 体力ゲージの位置調整を行います。作業画面だと変な位置に見えるのですがフル画面で再生するとちょうど良い位置になるように調整して下さい。
  • 体力ゲージの土台の色を変えます。ダメージを受けている部分です。
  • 体力ゲージのメインの色を変えます。残り体力の部分です。

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

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と表示しています。

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
        }
    }
}

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


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

ゲームオーバー

Playerスクリプトに追記

以下追記内容です

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と表示しています。

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 で増やして敵を好きな場所に配置して下さい。

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

ゲームクリア

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

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と表示しています。

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
        }
    }
}

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


敵を全員倒すとGameClearのシーンに変わります。

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

以上でチュートリアルは終わりです♪
お疲れ様でした♪

このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

-Unity

執筆者:


comment

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

Unityでマインクラフト風のマップをランダム生成する

今回やること 画像のようにマイクラ風のマップを自動で生成するツールを作成します こちらを参考にしましたが、マイクラのようにブロックの高さがきっちり分けられるようにしたかったので直してみました マップを …

no image

保護中: 出待ちちゃん

この投稿はパスワードで保護されているため抜粋文はありません。

ブラウブリッツ秋田のブラウゴン応援ゲーム

操作説明 マウスでひたすらクリックするだけです 100回クリックすると…!?

Unityでのジャンプ【Rigidbody,CharacterControllerどちらも対応】

はじめに Unityでジャンプを実装する場合にはいくつかの方法があります その中でも、よく使われるのが、 ①CharacterControllerを使用したジャンプ ②Rigidbodyを使用したジャ …

ARプレゼンツール

使用用途 2020.3.27に秋田総研さんが主催したオンラインプレゼン大会Talk Your Will Akita(TYWA)で使用したARプレゼンツールです Unityでカメラを映し、その空間内にA …

ゲタバコ倶楽部へようこそ

  • 300733総閲覧数:
  • 16今日の閲覧数:
  • 231528総訪問者数:
  • 15今日の訪問者数:

住所
Akita,Japan

営業時間
月~日: 10:00 AM – 10:00 PM

このページはゲタバコ先生の日々思うことや活動、プログラミングの習得方法を発信するページです。
仕事のご依頼、メッセージ等、サービス概要をご覧の上で、お気軽にご連絡ください。

getabakosensei@gmail.com