変数値の更新をスクリプタブルオブジェクトに置き換えたサンプル

スクリプタブルオブジェクトに置き換えることでコード中のマジックナンバーを外部で設計できるようになります

コード

ItemGenerator(1/2)

// System.Collectionsを使うための宣言
using System.Collections;
// Unityエンジンを使うための宣言
using UnityEngine;

// ItemGeneratorクラスを定義
public class ItemGenerator : MonoBehaviour
{
    // ゲームオブジェクトを格納する変数を宣言
    public GameObject applePrefab;
    public GameObject bombPrefab;

    // アイテム生成間隔、アイテム落下速度、爆弾生成率を格納する変数を宣言
    float span;
    float speed;
    float ratio;

    // コルーチンのインスタンスを格納する変数を宣言
    Coroutine generateCorutine;

    // アイテム生成のパラメータをセットするメソッド
    public void SetParameter(GenerateParam itemParameter)
    {
        // 引数で受け取ったパラメータを各変数に格納する
        span = itemParameter.span;
        speed = itemParameter.speed;
        ratio = itemParameter.ratio;

        // ログを出力する
        Debug.Log($"生成:{span}, {speed} {ratio}");
    }
}

このコードは、アイテム生成に関するパラメータを設定するメソッドを定義しています。

まず、GameObject型の変数applePrefabbombPrefabを宣言しています。これらは、それぞれリンゴと爆弾のプレハブ(Prefab)を指すオブジェクトです。Prefabは、ゲームオブジェクトの設定や挙動を定義したテンプレートのようなもので、実行時にインスタンス化することができます。

次に、アイテム生成に関するパラメータを格納する変数spanspeedratioを宣言しています。spanはアイテムの生成間隔、speedはアイテムが落下する速度、ratioは爆弾の生成率を表します。

さらに、コルーチンのインスタンスを格納するための変数generateCorutineを宣言しています。コルーチンは、一定時間ごとに処理を実行することができる非同期処理のことで、アイテムの生成や移動などによく使われます。

最後に、アイテム生成のパラメータを設定するためのSetParameterメソッドを定義しています。このメソッドは、GenerateParamという構造体を引数に取ります。GenerateParamは、アイテム生成に必要なパラメータをまとめた構造体で、spanspeedratioの値を持っています。

SetParameterメソッドでは、引数で受け取ったGenerateParamの各値を、前述の変数spanspeedratioに格納します。そして、Debug.Logメソッドを使って、生成されるアイテムの種類とパラメータをログに出力します。

このように、SetParameterメソッドを呼び出すことで、アイテム生成に関するパラメータを設定することができます。

ItemGenerator(2/2)

    // アイテム生成を開始するメソッド
    public void GenerateStart()
    {
        // コルーチンを開始し、そのインスタンスを格納する
        generateCorutine = StartCoroutine(Repeat());
    }

    // アイテム生成を停止するメソッド
    public void GenerateStop()
    {
        // コルーチンを停止する
        StopCoroutine(generateCorutine);
    }

    // アイテム生成を繰り返すコルーチン
    private IEnumerator Repeat()
    {
        while (true)
        {
            // アイテムの種類をランダムに選択する
            GameObject itemPrefab;
            int dice = Random.Range(1, 11);
            itemPrefab = dice <= ratio ? bombPrefab : applePrefab;

            // アイテムの位置をランダムに設定し、インスタンス化する
            float x = Random.Range(-1, 2);
            float z = Random.Range(-1, 2);
            GameObject generateItem = Instantiate(itemPrefab, new Vector3(x, 4, z), Quaternion.identity);

            // アイテムの落下速度を設定する
            generateItem.GetComponent<ItemController>().dropSpeed = speed;

            // 次のアイテム生成まで待機する
            yield return new WaitForSeconds(span);
        }
    }
}

このコードは、Uアイテム生成を制御するクラスの一部分です。

このクラスには以下のメソッドが含まれます。

  • GenerateStart(): アイテム生成を開始するメソッドです。コルーチン(繰り返し処理)を開始します。
  • GenerateStop(): アイテム生成を停止するメソッドです。コルーチンを停止します。
  • Repeat(): アイテムを生成する繰り返し処理が含まれるコルーチンです。このコルーチンは、GenerateStart()メソッドで開始され、GenerateStop()メソッドで停止されます。

Repeat()メソッドでは、以下の処理が繰り返し行われます。

  • アイテムの種類をランダムに選択します。
  • アイテムの位置をランダムに設定し、インスタンス化します。
  • アイテムの落下速度を設定します。
  • 次のアイテム生成まで一定時間待機します。

また、以下の変数が含まれます。

  • bombPrefab: 爆弾のプレハブ(GameObject)です。
  • applePrefab: 林檎のプレハブ(GameObject)です。
  • ratio: 爆弾を生成する確率を表す変数で、1~10の乱数を生成してその値がratio以下の場合に爆弾を生成します。
  • speed: アイテムの落下速度を表す変数です。
  • span: アイテム生成間隔を表す変数です。

GameDirector

using System.Collections;
using TMPro; // TextMeshProを使う時は忘れないように注意!!
using UnityEngine;

public class GameDirector : MonoBehaviour
{
    GameObject timerText; // タイマーを表示するTextMeshProUGUIのGameObject
    GameObject pointText; // ポイントを表示するTextMeshProUGUIのGameObject
    float time = 30.0f; // 制限時間
    int point = 0; // 獲得したポイント
    GameObject generator; // アイテム生成用のオブジェクト

    [SerializeField]
    ItemParameter itemParameter; // ItemParameterスクリプトの内容を管理するためのオブジェクト

    // りんごを取得した時の処理
    public void GetApple()
    {
        this.point += 100;
    }

    // 爆弾を取得した時の処理
    public void GetBomb()
    {
        this.point /= 2;
    }

    // ゲーム開始時の処理
    void Start()
    {
        // 各オブジェクトを検索して参照を取得する
        this.timerText = GameObject.Find("Time");
        this.pointText = GameObject.Find("Point");
        this.generator = GameObject.Find("ItemGenerator");

        // アイテム生成を開始する
        StartCoroutine(GenerateItem());
    }

    // アイテムを生成する処理
    private IEnumerator GenerateItem()
    {
        // ItemParameterスクリプトで指定された生成パラメータの数だけループする
        for (int i = 0; i < itemParameter.generateParams.Length; i++)
        {
            // アイテム生成用オブジェクトにパラメータを設定する
            generator.GetComponent<ItemGenerator>().SetParameter(itemParameter.generateParams[i]);

            // アイテム生成を開始する
            generator.GetComponent<ItemGenerator>().GenerateStart();

            // 次のアイテム生成までの時間だけ待機する
            var timeLap = itemParameter.generateParams[i].timeLapse;
            yield return new WaitForSeconds(timeLap);

            // アイテム生成を停止する
            generator.GetComponent<ItemGenerator>().GenerateStop();
        }

    }

    // ゲームの各フレームの処理
    void Update()
    {
        // 制限時間を減らす
        this.time -= Time.deltaTime;

        // 制限時間が0以下になったら何もしない
        if (time < 0)
        {
            return;
        }

        // タイマー表示用のテキストを更新する
        this.timerText.GetComponent<TextMeshProUGUI>().text = this.time.ToString("F1");

        // ポイント表示用のテキストを更新する
        this.pointText.GetComponent<TextMeshProUGUI>().text = this.point.ToString() + " point";
    }
}

このコードは、Unityのスクリプトであり、毎フレーム更新されるUpdate()メソッドの中で、以下のような処理を行っています。

  • time変数に、Time.deltaTimeで取得したフレーム間の時間の差を減算することで、経過時間を計測しています。
  • timeが0未満になった場合、以降の処理をスキップしてメソッドを終了します。
  • timerTextpointTextという2つのオブジェクトにアタッチされたTextMeshProUGUIコンポーネントのtextプロパティに、現在の時間とポイント数を文字列として代入することで、それぞれのUIテキストを更新しています。

GenerateParam

using System;
using UnityEngine;

[Serializable]
public class GenerateParam
{
    public float timeLapse;
    public float span;
    public float speed;
    public int ratio;
}

[CreateAssetMenu(fileName = "ItemParam", menuName = "Custom/ItemParam")]
public class ItemParameter : ScriptableObject
{
    public GenerateParam[] generateParams;
}

スクリプタブルオブジェクト解説

GenerateParam(1/2)

[Serializable]
public class GenerateParam
{
    public float timeLapse;
    public float span;
    public float speed;
    public int ratio;
}
  • GenerateParam クラスを定義しています。このクラスは、生成されたアイテムのパラメータを保持するためのもので、timeLapse(時間経過)、span(出現間隔)、speed(移動速度)、ratio(出現確率)の4つのパラメータを持ちます。
  • [Serializable] 属性を指定しているため、このクラスのインスタンスはシリアル化可能で、ファイルに保存したりネットワークを介して送信することができます。

GenerateParam(2/2)

[CreateAssetMenu(fileName = "ItemParam", menuName = "Custom/ItemParam")]
public class ItemParameter : ScriptableObject
{
    public GenerateParam[] generateParams;
}
  • ItemParameter クラスを定義しています。このクラスは、アイテムのパラメータをまとめたデータを保存するためのもので、generateParams という配列を持っています。
  • [CreateAssetMenu] 属性を指定しているため、このクラスは Assets メニューに表示され、ユーザーが新しいアイテムパラメータを作成することができます。fileName は作成されるアセットのファイル名、menuName は作成されるアセットのメニュー名を指定します。
  • ScriptableObject を継承しているため、このクラスのインスタンスはファイルに保存することができます。また、このクラスのインスタンスはプレイ中に変更することができず、プロジェクト内で共有されます。

スクリプタブルオブジェクトの登録

ScriptableObject,Unity

Posted by hidepon