【ゲーム制作】アイテム配置してみました♪

こんばんは!
こじゃらです(=^・^=)

暗闇迷路ゲームの制作続きです!
今回はアイテムを迷路中に配置できるようにしてみました。

スクリーンショット

これが実際のゲーム画面です!
雷マークのアイコンがアイテムで、懐中電灯の電池を回復します。
懐中電灯は使用すると電池がどんどん減っていきます。

右上の星マークはゴールアイテムで、これを取るとステージクリアとなります。

スクリーンショットの迷路は実際に次のような道になっています。

これを懐中電灯の光だけを頼りに進むのは中々に怖い部分があります><

まだ実装はしていないのですが、ライフ回復アイテムも追加しようと思ってます。
レベルデザインには欠かせない要素の一つです。

実装の話などなど

迷路はステージ制にしようと考えており、次のようなパラメータで管理できるようにしています。

これらのパラメータは、UnityのScriptableObjectとして保存しておき、ステージ開始時にこれらの情報をロードしてゲームが開始されます。

ScriptableObjectのデータは、次のようなクラスがシリアライズされたものです。

LevelData.cs
using System;
using UnityEngine;

namespace Game.Level
{
    /// <summary>
    /// レベル情報
    /// </summary>
    [CreateAssetMenu(fileName = "LevelData", menuName = "ScriptableObjects/LevelData")]
    public class LevelData : ScriptableObject
    {
        /// <summary>
        /// プレイヤーPrefabのパス
        /// </summary>
        public string _playerPrefabPath;

        /// <summary>
        /// プレイヤーの初期位置
        /// </summary>
        public Vector2Int _playerInitialPosition;

        /// <summary>
        /// プレイヤーの初期向き
        /// </summary>
        public PlayerDirection _playerInitialDirection;

        /// <summary>
        /// フィールドのサイズ
        /// </summary>
        public Vector2Int _fieldSize;

        /// <summary>
        /// ゴールのPrefabパス
        /// </summary>
        public string _goalPrefabPath;

        /// <summary>
        /// ゴール位置
        /// </summary>
        public Vector2Int _goalPosition;

        [Serializable]
        public struct ItemData
        {
            public string _prefabPath;
            public int _minNum;
            public int _maxNum;
        }

        /// <summary>
        /// アイテムデータ
        /// </summary>
        public ItemData[] _itemData;
    }
}

コメントを残しておくと、あとで見返したときに他人のソースコードにならないで済んだりします。

実際にロードする処理は以下のようなソースコードになります。

        /// <summary>
        /// レベルをロードする
        /// </summary>
        /// <param name="dataPath">データパス</param>
        /// <returns></returns>
        private async UniTask Load(string dataPath)
        {
            // レベルデータのロード
            LevelData = await Resources.LoadAsync<LevelData>(dataPath) as LevelData;
            Debug.Assert(LevelData != null);
        }

async/awaitとの組み合わせは非常に強力です。
非同期処理を簡単に書けるのが素晴らしいです。

この辺の説明は、別の記事に改めて纏めていくつもりです。

さいごに

レベルデザインの楽しさと開発における知見が蓄積されていくこともあって、ゲーム制作が凄く楽しくなってきました。

ゲームを公開してプレイヤーに楽しんでもらうところが目標なので、そこを見失わないように、でも開発も楽んでいきたいです♪