課題8: ScriptableObjectを用いたパラメータセットの定義

目的GameDirector が持つアイテム生成のパラメータ(spanspeedratio など)をデータ駆動設計や ScriptableObject を用いて外部化・管理し、パラメータ調整を容易にする。

ステップ:

1. ScriptableObjectを用いたパラメータセットの定義

  • パラメータを外部化し、Unityエディタ上で簡単に調整・追加できるようにします。
// GenerationParameters.cs
using UnityEngine;

[CreateAssetMenu(fileName = "GenerationParameters", menuName = "ScriptableObjects/GenerationParameters", order = 1)]
public class GenerationParameters : ScriptableObject
{
    public float span;       // アイテム生成間隔
    public float speed;      // アイテムの落下速度
    public int ratio;        // 爆弾の出現割合
    public float duration;   // このパラメータセットが有効な時間範囲
}

手順:

  • Assets/Scripts フォルダ内に GenerationParameters.cs を作成し、上記のコードを貼り付けます。
  • Unityエディタで Assets > Create > ScriptableObjects > GenerationParameters を選択し、必要なパラメータセット(例: 初期段階、中盤、終盤)を作成します。
    • EarlyStageParameters: span=1.0f, speed=-0.03f, ratio=2, duration=4.0f
    • MidStageParameters: span=0.8f, speed=-0.05f, ratio=4, duration=10.0f
    • LateStageParameters: span=0.5f, speed=-0.05f, ratio=6, duration=8.0f
    • EndStageParameters: span=0.3f, speed=-0.06f, ratio=0.0f, duration=4.0f

EarlyStageParametersのサンプル

2. GameDirectorにパラメータセットを適用するロジックを追加:

  • GameDirectorが時間経過に応じて適切なパラメータセットを適用するように、ScriptableObjectを参照して設定を行います。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro; // TextMeshProを使う時は忘れないように注意!!

public class GameDirector : MonoBehaviour
{
    public List<GenerationParameters> generationParametersList; // ScriptableObjectのリスト
    private int currentStage = 0;
    private float elapsedTime = 0.0f;


    GameObject timerText;
    GameObject pointText;
    float time = 30.0f;
    public int point = 0;
    GameObject generator;

    void Start()
    {
        this.timerText = GameObject.Find("Time");
        this.pointText = GameObject.Find("Point");
        this.generator = GameObject.Find("ItemGenerator");

        // 初期パラメータセットを適用
        ApplyCurrentGenerationParameters();
    }

    void Update()
    {
        this.time -= Time.deltaTime;
        elapsedTime += Time.deltaTime;

        // パラメータセットの切り替え
        if (currentStage < generationParametersList.Count && elapsedTime > generationParametersList[currentStage].duration)
        {
            currentStage++;
            elapsedTime = 0.0f;  // elapsedTime をリセット
            if (currentStage < generationParametersList.Count)
            {
                ApplyCurrentGenerationParameters();
            }
        }

        if (this.time < 0)
        {
            this.time = 0;
            this.generator.GetComponent<ItemGenerator>().SetParameter(10000.0f, 0, 0);
        }

        this.timerText.GetComponent<TextMeshProUGUI>().text = this.time.ToString("F1");
        UpdateScoreUI();
    }

    // パラメータセットを適用するメソッド
    private void ApplyCurrentGenerationParameters()
    {
        GenerationParameters currentParams = generationParametersList[currentStage];
        this.generator.GetComponent<ItemGenerator>().SetParameter(currentParams.span, currentParams.speed, currentParams.ratio);
    }

    // スコア変更イベントハンドラ
    public void HandleScoreChange(object sender, ScoreEventArgs e)
    {
        this.point += e.ScoreChange;
        UpdateScoreUI();
    }

    // スコアUIの更新
    private void UpdateScoreUI()
    {
        this.pointText.GetComponent<TextMeshProUGUI>().text = this.point.ToString() + " point";
    }
}

3. ScriptableObjectのリストをGameDirectorに設定:

  • GameDirectorのインスペクターに generationParametersList フィールドを追加し、作成した各パラメータセットをリストに追加します。

4. テストと確認:

  • ゲームをプレイし、時間経過に応じてアイテム生成のspan、speed、ratioがScriptableObjectで設定したパラメータに基づいて変更されることを確認する。
  • ScriptableObjectのパラメータを調整し、ゲームの挙動が期待通りに変化することを確認する。

学習ポイント:

  • データ駆動設計の基本。
  • ScriptableObject の活用方法。
  • パラメータ管理の外部化によるコードの整理。

Unity

Posted by hidepon