【Unity】モグラ叩きゲームvol.9『モグラの生成と加点』の実装をつける<完結>

ここでは、プレハブ化したモグラをランダム生成し、ハンマーで叩かれたら加点する実装をしていきます。

前回の記事を読み進めていないと、作業ができませんので、ぜひ目を通しておいてください。

では、早速始めましょう。

手順①MoguraGenenator.csを作る

まずは、モグラをランダムで生成するためのスクリプトを作っていきます。

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

public class MoguraGenerator : MonoBehaviour
{
    public GameObject moguraPrefab;
    bool isThereMogura;


    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
//モグラを生成する関数
    public void SpawnMogura()
    {
        GameObject monster = Instantiate(moguraPrefab);
        monster.transform.SetParent(transform, false);
        isThereMogura = true;
        if (isThereMogura == true)
        {
            Debug.Log("成功");
        }
    }
   
}

上記のコードをコピペしておきましょう。

そして、このスクリプトはアタッチしたオブジェクトを親として、インスタンシエイトされるオブジェクトは子要素となります。

従って、以下の画像のように設定してください。

また、publicで宣言したモグラのプレハブをアタッチする必要があります。

これを、残り2つのMouraSpotにもやります。

手順②GameManager.csに追記する

では、ゲーム全体を管理するGameManager.csに必要なコードを追記しましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class GameManager : MonoBehaviour
{
    public MoguraGenerator moguraGenerator1;
    public MoguraGenerator moguraGenerator2;
    public MoguraGenerator moguraGenerator3;

  
    public Text leftTimeText;
    float leftTime = 30;

    // Start is called before the first frame update
    void Start()
    {
    
        StartCoroutine("CreateMogura1");
        StartCoroutine("CreateMogura2");
        StartCoroutine("CreateMogura3");
    }

    // Update is called once per frame
   void Update()
        {
      
            //1秒に1秒ずつ減らしていく
            leftTime -= Time.deltaTime;
            //マイナスは表示しない
            if (leftTime < 0) leftTime = 0;
            leftTimeText.text = "残り時間:" + ((int)leftTime).ToString(); 
        
        }
    
    IEnumerator CreateMogura1()
    {
        yield return new WaitForSeconds(0.5f); //0.5秒遅らせる
        moguraGenerator1.SpawnMogura();
    }
    IEnumerator CreateMogura2()
    {
        yield return new WaitForSeconds(1.0f); //1秒遅らせる
        moguraGenerator2.SpawnMogura();
    }
    IEnumerator CreateMogura3()
    {
        yield return new WaitForSeconds(1.5f); //1.5秒遅らせる
        moguraGenerator3.SpawnMogura();
    }
}

このコードには、以下2つの大事な考え方が含まれています。

  • 手順①で作ったMoguraGenerator.csをGameManager.csで実行する
  • 「コルーチン」という便利な機能を使っている

他のスクリプトを引っ張ってきて実行する

public MoguraGenerator moguraGenerator1;
public MoguraGenerator moguraGenerator2;
public MoguraGenerator moguraGenerator3;

スクリプトを宣言することで、そのスクリプトで作られた関数を自由に使うことができます。

moguraGenerator1.SpawnMogura();

そのため、上記のようにGameManager.csでSpawnMogura()を使うことができます。

publicで宣言しているので、MoguraGenerator.csがアタッチされたMoguraSpotをGameManager.csがアタッチされたオブジェクトのインスペクターから設定してください。

コルーチンを使っている

モグラを時間差で生成するために、コルーチンを使っています。

    IEnumerator CreateMogura1()
    {
        yield return new WaitForSeconds(0.5f); //0.5秒遅らせる
        moguraGenerator1.SpawnMogura();
    }
    IEnumerator CreateMogura2()
    {
        yield return new WaitForSeconds(1.0f); //1秒遅らせる
        moguraGenerator2.SpawnMogura();
    }
    IEnumerator CreateMogura3()
    {
        yield return new WaitForSeconds(1.5f); //1.5秒遅らせる
        moguraGenerator3.SpawnMogura();
    }

IEnumeratorと書いてから関数名を書くことで、コルーチンを使うことができます。

モグラを0.5秒、1.0秒、1.5秒ずつずらしてモグラを出現させるようにしています。

そして、このコルーチン関数を実行するには、以下のようにStartCoroutine関数の引数に関数名を当てはめるのです。

StartCoroutine("CreateMogura1");
StartCoroutine("CreateMogura2");
StartCoroutine("CreateMogura3");

これをstart関数で実行しているので、ゲーム開始時と同時に処理されることになります。

手順④加点の実装

では、モグラを叩いたら加点される仕組みを作りましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class GameManager : MonoBehaviour
{
    public MoguraGenerator moguraGenerator1;
    public MoguraGenerator moguraGenerator2;
    public MoguraGenerator moguraGenerator3;

    public Text scoreText;
    public Text leftTimeText;
    int score;
    string playTime;
    float leftTime = 30;

    // Start is called before the first frame update
    void Start()
    {
       
        StartCoroutine("CreateMogura1");
        StartCoroutine("CreateMogura2");
        StartCoroutine("CreateMogura3");
        scoreText.text = "得点:" + score;
   
    }

    // Update is called once per frame
    void Update()
    {
        playTime = System.DateTime.Now.ToString();//playtimeなくてもいい?

        //1秒に1秒ずつ減らしていく
        leftTime -= Time.deltaTime;//floatじゃないと使えないみたい
        //マイナスは表示しない
        if (leftTime < 0) leftTime = 0;

        leftTimeText.text = "残り時間:" + ((int)leftTime).ToString(); 
        if (leftTime == 0)
        {
            finalText.text = scoreText.text;
            //Debug.Log("時間になった");
            //Debug.Log(score);
            //Debug.Log(playTime);
        }
    }
    IEnumerator CreateMogura1()
    {
        yield return new WaitForSeconds(0.5f);
        moguraGenerator1.SpawnMogura();
    }
    IEnumerator CreateMogura2()
    {
        yield return new WaitForSeconds(1.0f);
        moguraGenerator2.SpawnMogura();
    }
    IEnumerator CreateMogura3()
    {
        yield return new WaitForSeconds(1.5f);
        moguraGenerator3.SpawnMogura();
    }

//加点される関数
    public void AddScore()
    {
        score += 10;

        scoreText.text = "得点:" + score;
    }
}

10点ずつ加点される関数を作ったので、今度はそれをどこで実行するかを考える必要があります。

答えは、前回作ったMoguraManager.csです。

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

public class MoguraManager : MonoBehaviour
{
    Collider2D moguraCollider;
    Animator animator;
    GameManager gameManager; //追記
    AudioSource audioSource;
    public AudioClip pikopikoSE;

    // Start is called before the first frame update
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        gameManager = GameObject.Find("GameManager").GetComponent<GameManager>(); //追記
        animator = GetComponent<Animator>();
        moguraCollider = GetComponent<Collider2D>();
        HideColliderMogura();
    }

    // Update is called once per frame
    void Update()
    {
        transform.position -= new Vector3(0,0.1f,0);
    }
    public void HideColliderMogura()
    {
        moguraCollider.enabled = false;
        Debug.Log("モグラコライダーが消えた");
    }
    public void ShowColliderMogura()
    {
        moguraCollider.enabled = true;
        Debug.Log("モグラコライダーがついた");
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //次やること、攻撃を受けたら、得点が追加される
        animator.SetTrigger("Hurt");
        audioSource.PlayOneShot(pikopikoSE);
        gameManager.AddScore(); //追記
        HideColliderMogura();
        StartCoroutine(Damage());
    }
    IEnumerator Damage()
    {
        
        yield return new WaitForSeconds(0.5f);
        animator.enabled = false;
        yield return new WaitForSeconds(1.0f);
        animator.enabled = true;
        animator.Play("float@mogura");
    }

}

//追記とある部分はどれも重要なので、逃さす追記してください。

今回は、publicと宣言せずに、GameManager gameManagerを宣言しています。

他のスクリプトから関数を引っ張る方法は一つではありません。

gameManager = GameObject.Find("GameManager").GetComponent<GameManager>(); //追記

上記のように、Find関数を使って、ヒエラルキーにあるGameManagerという名前のオブジェクトを探して、そのオブジェクトのコンポーネントにアプローチしているんですね。

ただし、この方法では、GameManagerという名前を少しでも変えると、役に立たないのでご注意ください。

 gameManager.AddScore(); //追記

こうすることで、モグラが攻撃されるたび、AddScore関数が実行されて10点ずつ加点されます。

手順⑤結果の表示

次に、いくら得点したのか、それを表示させましょう。

まず、下記のようにScoreCanvasの子要素にPanelとボタン、テキストを作ってください。

そして、以下のコードをGameManager.csに追記してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; 
using System;

public class GameManager : MonoBehaviour
{
    public MoguraGenerator moguraGenerator1;
    public MoguraGenerator moguraGenerator2;
    public MoguraGenerator moguraGenerator3;

    public Text scoreText;
    public Text leftTimeText;

    public GameObject resultPanal; //追記
    public Text finalText; //追記
    int score;
    string playTime;
    float leftTime = 30;

    // Start is called before the first frame update
    void Start()
    {
      

        StartCoroutine("CreateMogura1");
        StartCoroutine("CreateMogura2");
        StartCoroutine("CreateMogura3");
        scoreText.text = "得点:" + score;
        resultPanal.SetActive(false); //追記
    }

    // Update is called once per frame
    void Update()
    {
        playTime = System.DateTime.Now.ToString();//playtimeなくてもいい?

        //1秒に1秒ずつ減らしていく
        leftTime -= Time.deltaTime;//floatじゃないと使えないみたい
        //マイナスは表示しない
        if (leftTime < 0) leftTime = 0;

        leftTimeText.text = "残り時間:" + ((int)leftTime).ToString(); 
        if (leftTime == 0)
        {
            resultPanal.SetActive(true); //追記
            finalText.text = scoreText.text; //追記
            //Debug.Log("時間になった");
           
        }
    }
    IEnumerator CreateMogura1()
    {
        yield return new WaitForSeconds(0.5f);
        moguraGenerator1.SpawnMogura();
    }
    IEnumerator CreateMogura2()
    {
        yield return new WaitForSeconds(1.0f);
        moguraGenerator2.SpawnMogura();
    }
    IEnumerator CreateMogura3()
    {
        yield return new WaitForSeconds(1.5f);
        moguraGenerator3.SpawnMogura();
    }

    public void AddScore()
    {
        score += 10;

        scoreText.text = "得点:" + score;
    }

   
}

そして、publicで宣言したものは、下記のようにアタッチしておいてください。

手順⑥メインシーンからタイトルシーンへの切り替え

次に、メインシーンからタイトルシーンへの切り替えです。

下記のように、GameManager.csに追記してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; 
using UnityEngine.SceneManagement; //追記
using System;

public class GameManager : MonoBehaviour
{
    public MoguraGenerator moguraGenerator1;
    public MoguraGenerator moguraGenerator2;
    public MoguraGenerator moguraGenerator3;

    public Text scoreText;
    public Text leftTimeText;

    public GameObject resultPanal;
    public Text finalText;
    int score;
    string playTime;
    float leftTime = 30;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine("CreateMogura1");
        StartCoroutine("CreateMogura2");
        StartCoroutine("CreateMogura3");
        scoreText.text = "得点:" + score;
        resultPanal.SetActive(false);
    }

    // Update is called once per frame
    void Update()
    {
        playTime = System.DateTime.Now.ToString();//playtimeなくてもいい?

        //1秒に1秒ずつ減らしていく
        leftTime -= Time.deltaTime;//floatじゃないと使えないみたい
        //マイナスは表示しない
        if (leftTime < 0) leftTime = 0;

        leftTimeText.text = "残り時間:" + ((int)leftTime).ToString(); 
        if (leftTime == 0)
        {
            resultPanal.SetActive(true);
            finalText.text = scoreText.text;
            //Debug.Log("時間になった");
            //Debug.Log(score);
            //Debug.Log(playTime);
        }

      
        
    }
    IEnumerator CreateMogura1()
    {
        yield return new WaitForSeconds(0.5f);
        moguraGenerator1.SpawnMogura();
    }
    IEnumerator CreateMogura2()
    {
        yield return new WaitForSeconds(1.0f);
        moguraGenerator2.SpawnMogura();
    }
    IEnumerator CreateMogura3()
    {
        yield return new WaitForSeconds(1.5f);
        moguraGenerator3.SpawnMogura();
    }

    public void AddScore()
    {
        score += 10;

        scoreText.text = "得点:" + score;
    }

    //追記
    void InitScore()
    {
        //スコア初期化
        score = 0;
    }

    //追記
    public void OnTitleButton()
    {
        SceneManager.LoadScene("Title");
        SaveScore(score);
        InitScore();
        
    }
    //追記
    public void OnRetryButton()
    {
        SceneManager.LoadScene("Main");
        SaveScore(score);
        InitScore();
        
    }
}

ポイントは、冒頭にusing UnityEngine.SceneManagement; がないとシーン切り替えの関数は使うことができないことです。

忘れずに、追記してください。

そして、リトライボタンとタイトルボタンに関数をつけます。

付け方は、下記の画像をご覧ください。

ボタンを選択すると、On Click()という項目があり、プラスボタンを押すと、オブジェクトをアタッチできるようになります。

今回は、GameManager.csで作ったボタン関数を使いたいので、GameManagerオブジェクトをアタッチしてください。

最後に、切り替えたいシーンを追加します。

シーンの追加は、画面左上からFile→Build Settingで入れたいシーンを選択して、Addを押してください。

手順⑦タイトルシーンからメインシーンへの切り替え

最後に、タイトルシーンからメインシーンへの切り替えです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class TitleManager : MonoBehaviour
{
    AudioSource audioSource;
    // Start is called before the first frame update
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        audioSource.Play();
    }

    public void OnStartButton()
    {
        SceneManager.LoadScene("Main");
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

TitleManager.csを作り、上記をコピペしてください。

そして、TitleManagerオブジェクトを作り、スクリプトをアタッチしてください。

そして、スタートボタンには、必要な関数を当てはめてください。

以上が終われば、スタートボタンを押せば、メインシーンへの遷移ができるようになるはずです。

まとめ:ゲーム完成お疲れ様でした!MENTAでサポートします。

ここまで、全部で10記事にわたってモグラ叩きゲームの作り方を解説しました。

一つのゲームを作り上げることは、自信につながりますし、Unityの理解がより深まるはずです。

なお、モグラ叩きゲームにおけるランキング機能の実装については、これまで紹介した以上に高度なコーディングをやらなくていけません。

そのため、記事で紹介するのは限界があると判断し、ランキングまで実装したい方に関しては、MENTAで個別対応させていただいています。

もちろん、モグラ叩きの作り方を最初から教えてほしいという方にもお答えしていますので、ぜひお問合せください。

最後まで読んでいただきありがとうございました!

懇切丁寧にサポートします!!

コメントを残す

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

ABOUT US

まえぴー
放課後等デイサービスで、保育士&作業療法士として療育の仕事をしています。Unityで個人ゲーム開発を行なっており、ストアに知育アプリを無料リリースしています! 子どもと向き合う時間をたくさん作って、一緒に楽しい時間を過ごすことが大切だと信じています! こども発達支援研究会で認定講師をしています。