【Unity】チュートリアルの「Roll a Ball」をやってみる話 #9

記事をご覧いただき、誠に有難うございます。

投稿主の無能です。

今回は、Stage Clearをクリア時にだけ表示させたいと思います。


クリアの処理

Stage Clearの表示は、表示・非表示を切り替えることで実現できそうです。

Canvasの名前を「UI_StageClear」に変更します。

Canvasの名前を「UI_StageClear」に変更

そしてUI_StageClearを非アクティブにします。

UI_StageClearを非アクティブにする

すると子オブジェクトのテキストもあわせて非アクティブになります。

子オブジェクトのテキストも非アクティブになる

この非アクティブになっているUI_StageClearを、クリア時にアクティブにすれば問題解決します。

次に、名前を「GameManager」として空のオブジェクトを作成します。

この空のオブジェクトは、ゲーム全体を監視するオブジェクトになり、GameManagerスクリプトをアタッチするための空のオブジェクトです。

空のオブジェクトを作成

名前を「GameManager」とし、Positionをリセット

次にスクリプトを作成します。

GameManagerスクリプトを作成する

UI_StageClearのアクティブ化を実現するために、ゲーム全体の処理を管理するGameManagerスクリプトを作成します。

ProjectビューのScriptsフォルダに「GameManager」という名前のスクリプトを新規作成します。

「GameManager」という スクリプトを新規作成

作成するとアイコンが変化しますが、普通のスクリプトですので、いつも通りで大丈夫です。

このGameManagerスクリプトを、先程作成したGameManagerにアタッチします。


これで下準備が整ったのでGameManagerスクリプトをVSで開きます。

必要な変数の準備

ステージクリアを判別するために、ステージ内にある収集アイテムの残数を把握しておく必要があります。
収集アイテムがゼロになったらステージクリアとなるようにします。

変数はこのような記述になります。

public class GameManager : MonoBehaviour
{
    // ステージ内の収集アイテムの個数
    int count;
    // ステージクリアのUI
    public GameObject UIStageClear;

}
このようになります。


次にUpdate関数です。

Update関数での処理

Update関数内では、収集アイテムの個数を常に把握する変数countがゼロになったら、変数UIStageClearをアクティブにする、という処理になります。

このような記述になります。


private void Update()
{
	// 収集アイテムの個数を把握する
    count = GameObject.FindGameObjectsWithTag("CollectItem").Length;

    // countがゼロになったらステージクリアのUIをアクティブにする
    if (count == 0)
    {
        UIStageClear.SetActive(true);
    }
}

このようになります。


注意点:if

ここで注意点なのですが、ifの条件でcountと0を比較しているのですが、

if (count = 0)

という書き方をしてしまう場合があります。

この場合は「変数countに0を代入する」という、以前スクリプトを記述する時に説明した「代入演算子」になってしまいます。

今回はint型とbool型なので、一応エラーが表示されます。

今回のエラーは表示される

この比較する条件がboolだった場合に、正常に条件を判断できない場合が出てくる可能性があります

今回のように比較する場合は必ず「==」や「!=」という「比較演算子」を使うように十分注意してください。

次にcountに代入する右辺について説明します。

FindGameObjectsWithTagの動作

FindGameObjectsWithTag("CollectItem").Length;

の部分ですが、Tagでゲームオブジェクトを探す、という処理になります。
Tagは「”」の中になります。

Lengthは長さ(個数)です。

右辺全てを日本語で言い換えると

GameObjectのCollectItemというTagの付いたゲームオブジェクトの個数を探してくる

という風になります。

注意点:FindGameObjectsWithTag

続いてFindGameObjectsWithTagですが、紛らわしい事に

FindGameObjectWithTag:単体の場合
FindGameObjectsWithTag:複数個の場合

と個数に応じて使い分けが必要なものになります。

この点もあわせて注意してください。

スクリプトを保存し、Unityに戻ります。

publicで宣言した変数UIStageClearにUI_StageClearをアタッチします。

UIStageClearにUI_StageClearをアタッチ
それではゲームを実行してみます。
今回は収集アイテムを全て取得して、UIが表示されるか確認します。

Gameビュー

正しく処理されていますね!

収集アイテムの個数の表示

でも、収集アイテムの個数が分からない状態だと、ゲームとしては不親切ですよね。
ですので、ステージに残っている収集アイテムの個数を表示させたいと思います。

まずはUIが必要なので、アイテムの個数を表示するUIを作成します。

Canvasの名前を変更する

先程UI_StageClearをCanvasにしましたが、これを「UI_GameStatus」に名前を変更してアクティブにします。

「UI_GameStatus」に名前を変更してアクティブにする

すると「Stage Clear」が表示されっぱなしの状態に戻るので、この状態を解消します。

子のText(TMP)の名前を「StageClear」にし、非アクティブにします。

Text(TMP)の名前を「StageClear」にし非アクティブにする

これでクリア時の表示の問題が解消されました。

先程HierarchyビューにあるGameManagerオブジェクトに、GameManagerスクリプトをアタッチした時、Canvasをアタッチしたかと思います。
名前が違うがCanvasがアタッチされている

ここを先程非アクティブにしたStageClearに変更します。
StageClearに変更

この状態で、Unityでゲームを実行して先程と同様に処理されるかを確認します。
収集アイテムを全て取得して、変更したコンポーネントが正常に表示されるかを確認します。

Gameビュー

正常に表示されました。

収集アイテムの個数を表示する

収集アイテムの個数を表示させるには、Text(TMP)を追加します。
UI_GameStatusを選択し、メニュー Game Object > UI > Text - TextMeshPro を選択してテキストを新規作成します。

テキストを新規作成

この時に注意するのがテキストがCanvasの子オブジェクトになっているかを確認しましょう。
この時子オブジェクトではない場合は表示されません。

CanvasからText(TMP)が外れている

Canvasの子オブジェクトではないので表示されない

もし何らかの原因でCanvasの子オブジェクトから外れた場合は、ドラッグしてCanvasの子オブジェクトへ戻してください。

それでは新規作成したテキストを「LeftItem」と名前を変更し、表示を調整します。

今回収集アイテムの個数を表示する場所は左下にします。
表示箇所は任意なので、自由に表示位置を決めてください。

「LeftItem」へ名前を変更

左下に移動

左下のRect Transformの設定

テキストはスクリプトで変更するのでこのままでも良いのですが、0にしておきます。


では準備が整ったので、GameManagerスクリプトに戻って処理を記述します。

スクリプトでの処理

先程、ゲームのクリア条件として収集アイテムの個数を取得していました。
それをそのまま流用して、残り個数の表示に使います。

次の変数を追加します。

// アイテムの個数を表示するUI
public TextMeshProUGUI leftItem;

このようになります。


すると、usingの部分に一文が自動的に追加されます。

using TMPro;が追加された

このusingの部分は、使用する道具箱を宣言しているようなもので、「このスクリプトはTMProを使いますよ」と予め使うことを宣言しています。

最初に用意してあるUnityEngineという道具箱の中にはTextMeshProで使う道具が入っていなかったので、TMProという道具箱を使います、というイメージです。

これでTextMeshProが使えるようになります。

因みにこの道具箱を使う宣言が無いと、以下のようなエラーが表示されます。


このTMPro以外の道具箱以外にも、幾つかの道具箱がありますが、使う時に覚えましょう。

では残りのアイテム個数を表示するようにします。
このように記述を追加します。

// 収集アイテムの個数を表示する
leftItem.SetText("Item : " + count.ToString());

このようになります。


次にUnityに戻ります。

変数leftItemはpublicで宣言したので、コンポーネントをアタッチします。

HierarchyビューのGameManagerを選択すると、leftItemの部分がNoneになっているので、ここにLeftItemをアタッチします。

作成したleftItemがNoneになっている

LeftItemをアタッチ

それでは正常にアイテムが表示されるか、アイテムを取得して数が変化するかを、ゲームを実行して確認します。
Gameビュー

正常に表示されました。
あとはフォントを設定します。
このように設定しました。

LeftItemの設定

このようになりました。
Gameビュー

今回の最後に、Playerがステージクリアの表示が出てもコロコロと転がることが出来てしまうのが気になります。
そりゃあテキストを表示させているだけなので、Playerに変化はありませんよね。
ステージをクリアしたらPlayerを消して、その後にクリアの表示をさせてみましょう。

Playerのクリア後の処理

Stage Clearと表示させる時に、Playerを非アクティブにします。

まずは変数の追加で、Playerを追加します。
このような記述になります。

// プレイヤー
public GameObject player;
このようになります。

そして、if文を少し変更します。
このような記述になります。

// countがゼロになったら
if (count == 0)
{
	// プレイヤーを非アクティブにする
    player.SetActive(false);
    // ステージクリアのUIをアクティブにする
    UIStageClear.SetActive(true);
}
このようになります。


ではスクリプトを保存してUnityに戻ります。

次にpublicで宣言したPlayerをGameManagerにアタッチします。

playerをpublicで宣言したので欄が追加されている

Playerをアタッチ

ではゲームを実行して確認しましょう。
収集アイテムを全て取得して、Playerが非アクティブになるかを確認しましょう。

クリアと同時にPlayerが消えた

正常にクリア後に非アクティブになった

これでステージクリアの処理ができました!

今回はここまで。

まとめ

本記事では
  • GameManagerを作成し、ステージ内の収集アイテムを取得できるようにした
  • クリア条件をもとにステージクリアの表示ができるようになった
  • クリア後のPlayerの表示を調整した
という事を行いました。

次は、音が無いのが寂しいので、BGMをや効果音(SE)を付けたいと思います。
ぐっとゲームらしさが増してくると思います。

本記事もご覧頂き、誠に有難うございます。
ではまた。

コメント