Menu
CoddyTech

1つのスクリプトでゲームを動かす

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 12/56。

スコアをプレイヤーのスクリプトに、ライフをヘルス用スクリプトに、ゲームオーバーの判定を3つ目のスクリプトに置くと、それぞれのスクリプトで他のスクリプトの数値が必要になり、新しいルールを追加するたびに複数のファイルを変更することになります。Unityのゲームでは通常、これらの数値を専用の空のGameObjectにアタッチした1つのスクリプト、GameManagerにまとめます。GameManagerがスコアとライフ、そしてゲームを終了するルールを管理します。他のスクリプトは、GameManagerのパブリックメソッドを呼び出して、起きたことを報告するだけです。このPK戦では、ゴールネットが各ゴールを報告します。

public class GameManager : MonoBehaviour
{
    private int goals;
    private int shotsLeft = 5;

    public void ShotTaken(bool scored)
    {
        if (shotsLeft == 0) return;
        shotsLeft--;
        if (scored) goals++;
        Debug.Log("Goals: " + goals + ", shots left: " + shotsLeft);
        if (shotsLeft == 0) Debug.Log("Full time: " + goals + " goals");
    }
}
// Net.cs、ゴールのトリガーにて
public GameManager game;

void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Ball")) game.ShotTaken(true);
}

ゴールネットは、残りのシュート数やゲームが終了するタイミングを知りません。ゴールを報告し、その意味をマネージャーが判断します。キーパーのスクリプトは、セーブをgame.ShotTaken(false)で報告します。シュート数3回のPK戦にするには、1つのスクリプト内の数値を1か所変更するだけです。ShotTakenの先頭にある判定によって、試合終了後に転がり込んだボールが得点に加算されるのを防ぎます。

InspectorでGameManagerオブジェクトをgameフィールドにドラッグして割り当てると、Unityがそのオブジェクト上のGameManagerスクリプトを見つけます。マネージャーはHUDを管理する場所でもあります。スコアテキストとゲームオーバーパネルを保持させれば、数値を変更するのと同じメソッドで画面も更新され、他のスクリプトがUIに触れることはありません。

challenge icon

チャレンジ

簡単

宝石探しです。矢印キーでPlayerを動かします(スクリプトは準備済みです)。宝石を取るとそのpoints分のポイントを獲得し、爆弾に当たるとライフを失います。GameManagerがこれらを管理します。Inspectorでは、各宝石と爆弾のgameフィールドはすでにGameManagerオブジェクトに、GameManagerのフィールドはHUDとPlayerに紐付けられています。

GameManager.csでは:

  • AddScore(int points)はポイントをscoreに加算し、Score: 6のようにscoreTextに表示します。
  • LoseLife()はlivesを1減らし(開始時は3)、Lives: 2のようにlivesTextに表示します。
  • livesが0になるとゲームオーバーです。gameOverPanelを表示し、Playerのスクリプトを無効にして矢印キーが効かないようにします。その後は、AddScoreを呼び出しても何も変わりません。

Gem.csとBomb.csでは:Player(タグPlayerが付いています)が宝石または爆弾に触れると、ゲームに通知し(宝石ならそのpoints、爆弾ならライフを1つ失います)、自身を削除します。

Playを押して、宝石を集めて爆弾に当たったら、Checkを押してください。

自分で試してみよう

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text scoreText;
    public TMP_Text livesText;
    public GameObject gameOverPanel;
    public Player player;
    private int score;
    private int lives = 3;
    private bool gameOver;

    public void AddScore(int points)
    {
        // ゲームオーバーでなければ、ポイントを加算して新しいスコアを表示する
    }

    public void LoseLife()
    {
        // ライフを1つ減らして表示する。ライフが0になったらゲームオーバー
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

本格的なゲームを作るのすべてのレッスン