Unityで3Dミニゲームを作る #7 クリア条件を作る②

投稿者: | 2019-12-06

gameScriptに取得したコインによって成功か失敗かを表示するメソッドを書きます。

// 宣言
public static bool ended;

//---
    void Judgment()
    {
        ended = true; // ゲーム終了

        if (playerScript.coins > 9) // 取得したコインが10枚なら成功
        {
            resultText.text = "Passed";
        }
        else // 失敗
        {
            resultText.text = "Failed";
        }
    }  

プレイヤーが取得したコインが10枚以上だとクリアです。
これをプレイヤーが取得したり、プレイヤーを通り過ぎてしまったりして、破壊されたコインが10枚になったときに呼び出せば良いです。

// playerScript
// 通り過ぎて破壊されたコイン + 取得したコインが10枚で、まだゲームが終了していないとき
if (coinScript.destroyedCoin + coins > 9 && !gameScript.ended)
{
    //gameScriptが付いたオブジェクトのJudgment()を実行
}

プレイヤーの方は問題ないですが、通り過ぎたコインを破壊するのは、個々のコインに付いたcoinScriptです。
コインオブジェクトは他のスクリプトによってオブジェクト化されて、すぐに破壊されます。
もともとシーンに配置されていないので、gameScriptが付いたオブジェクトを事前にインスペクタでアタッチしておくことは出来ません。また、プレハブにオブジェクトをアタッチすることもできません。

でも、クリアの判定に使うメソッドが静的メソッドなら、オブジェクトを指定する必要がないので問題ありません。

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

public class coinScript : MonoBehaviour
{
    public static int NumOfCoin; // 発生したコインの数
    public static int destroyedCoin; // プレイヤーを通り過ぎて破壊されたコインの数

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

    }

    // Update is called once per frame
    void Update()
    {
        if (transform.position.z > 6f)
        {
            destroyedCoin++; // 破壊されたコインの数を1足す

            if (destroyedCoin + playerScript.coins > 9) // 通り過ぎて破壊されたコイン + 取得されたコインが10枚で終了
            {
                if (!gameScript.ended)
                {
                    gameScript.Challenge(); // 静的メソッドはオブジェクトを指定しなくても使える
                }
                
            }
            else {
                Destroy(gameObject);              
            }
        }
    }
}

成功か失敗かを画面に表示するためのテキストオブジェクトを作りました。

中央に青く表示されます。

これをgameScriptにアタッチします。

すると、このテキストオブジェクトがアタッチされたのは、gameScriptのクラスでなく、シーンに配置されたインスタンスなので、静的メソッドからこのテキストを直接操作しようとするとエラーがでました。

gameScriptが付いたオブジェクトは実際は複数あって、それぞれに別のTextオブジェクトがアタッチされている可能性があり、どのオブジェクトなのかを特定しないといけないようです。

なので、静的メソッドのChallenge()が実行されると、FindGameObjectWithTag()が実行されて、特定のタグが付いたオブジェクトを探すようにして、そのオブジェクトのメソッドを実行するようにしました。(もっと良い方法があると思います。)

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

public class gameScript : MonoBehaviour
{
    public Text resultText;
    public static bool ended;
    
    // Start is called before the first frame update
    void Start()
    {
        resultText.text = ""; // テキストの文字列を空にする
        ended = false; // ゲーム終了していない
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape)) //Escapeキーを押す
        {
            SceneManager.LoadScene("flyingCube"); // シーンを再読み込み
        }
    }

    public static void Challenge()
    {
        GameObject game;
        if (game = GameObject.FindGameObjectWithTag("game")) // 「game」タグのついたオブジェクトを探す
        {
            gameScript sc_game = game.GetComponent<gameScript>();
            sc_game.Judgment(); // Judgmentメソッドを実行
        }
    }

    void Judgment()
    {
        ended = true; // ゲーム終了している

        if (playerScript.coins > 9) // 取得したコインが10枚なら成功
        {
            resultText.text = "Passed"; // テキストの文字列を変更
        }
        else // 失敗
        {
            resultText.text = "Failed"; // テキストの文字列を変更
        }
    }  
}

gameScriptを付けたオブジェクトに新規の「game」タグをつけました。
gameタグはこのオブジェクトにだけに付けることにします。

// playerScript
private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Coin")) // プレイヤーがコインと重なったとき
    {
        playerAudio[2].clip = audio[3]; 
        playerAudio[2].Play(); // コインを拾ったときの音を出す

        Instantiate(coinParticle, transform.position, transform.rotation); // パーティクルを出す

        Destroy(other.gameObject); // コインを破壊
        coins++; // 取得したコインを1足す
        text.text = coins.ToString(); // 取得したコインの枚数を表示

        if (coinScript.destroyedCoin + coins > 9 && !gameScript.ended) // 通り過ぎたコイン + 取得コインが10枚で、ゲームが終了していないとき
        {
            gameScript.Challenge(); // 成功か失敗かを判定する
        }
    }
}

クリア条件を2枚にしてテストしました。

コメントを残す

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