当サイトではPRを含む商品リンクを使用しております。

Unityで図鑑画面の作り方の概要設計

Unity

りんぼくです。

未完成ではあるのですが、別のことに着手したいので現時点での状況をメモします。

素人ながらUnityで図鑑画面を作りたく、基礎的な作りを実装できたのでメモを残したいと思います。

ソースコードを全公開したかったのですが、余計な他の処理が混ざるのでやめておこうと思います。

また、きっと未来の私が見たらスマートな解決法ではないかと思いますので、初心者の自由研究程度で、この方法は参考程度で使用をお願いいたします。

「とりあえず動くものほしいな」という方は、私の記事をAIに食べさせてコードの出力をお願いしてみてください。

データ管理はSQLite-net 〜Unityで図鑑画面の作り方の概要設計〜

SQLiteで図鑑データやユーザの進捗を保存することとしました。

ゲームを構成する上で必要なデータを「マスタ」DBに

ユーザの進捗やオプションの変化を管理するデータを「ユーザ」DBに保管することにしました。

全アイテムと解放済みアイテムの比較  〜Unityで図鑑画面の作り方の概要設計〜

マスタとユーザDBにはそれぞれアイテムに関するテーブルがあります。

下記はC#で受け取るための型定義部分から抜き出しました。データベース操作用クラスに書いたやつです。

   //マスタDBのアイテムテーブル
  public class Items
    {
        [PrimaryKey]
        public string ItemID { get; set; }
        public int ZukanNo { get; set; }
        public string ItemName { get; set; }
        public string ItemIconID { get; set; }
        public string ItemCommonText { get; set; }
        public string ItemCatsText { get; set; }
        public string ItemHumanText { get; set; }
        public int ItemEffect { get; set; }
        public int Stage { get; set; }
        public int Position { get; set; }
    }
//ユーザDBの解放済みアイテムテーブル
    public class UnlockedItems
    {
        [PrimaryKey]
        public string ItemID { get; set; }
    }

それぞれを抜き出すための実処理はこのような感じです。

データベースのパスは適宜、正しいものを最初に定義しておく必要があります。

    public List<Items> GetItemsList()
    {
        var mastaDb = new SQLiteConnection(mastaDbPath);
        var listAllItems = mastaDb.Table<Items>().ToList();
        mastaDb.Close();
        return listAllItems;
        
    }
    public List<UnlockedItems> GetUnlockedItemsList()
    {
        var userDb = new SQLiteConnection(userDbPath);
        var listAllUnlockedItems = userDb.Table<UnlockedItems>().ToList();
        userDb.Close();
        return listAllUnlockedItems;
    }

実際に図鑑生成を担当するクラスから、先ほどの全件取得関数を呼び出して取得します。

取得した後に、所有済みかどうかで一覧画面で表示する情報を仕分けています。

    void CreateZukanData()
    {
        //アイテム全件
        var listAllItems = databaseManager.GetItemsList();
        //所有済みアイテム全件
        var listAllUnlockedItems = databaseManager.GetUnlockedItemsList();
        // 所有済みアイテムのIDをHashSetに格納(効率的にチェック可能)
        var unlockedItemIds = new HashSet<string>(listAllUnlockedItems.Select(item => item.ItemID));


        // 図鑑データを生成
        foreach (var item in listAllItems)
        {
            ZukanItem zukanItem;

            if (unlockedItemIds.Contains(item.ItemID))
            {
                // 取得済みアイテム
                zukanItem = new ZukanItem
                {
                    ItemID = item.ItemID,
                    ZukanNo = item.ZukanNo,
                    ItemName = item.ItemName,
                    ItemIconID = item.ItemIconID,
                    ItemDescription = item.ItemCommonText
                };
            }
            else
            {
                // 未取得アイテム
                zukanItem = new ZukanItem
                {
                    ItemID = item.ItemID,
                    ZukanNo = item.ZukanNo,
                    ItemName = "???",
                    ItemIconID = "IMICTE0000", // 未開放用の画像ID(仮)
                    ItemDescription = "未開放" // 未開放用の文章
                };
            }

            zukanItems.Add(zukanItem);
        }

    }

その後、アイテムNoという項目で昇順ソートして、図鑑用のプレハブをロードして、整列済みのアイテムリストでプレハブ生成処理をループする流れにしました。

    private async void PopulateZukanList()
    {
        zukanItems = zukanItems.OrderBy(item => item.ZukanNo).ToList();
        AsyncOperationHandle<GameObject> zukanPr = Addressables.LoadAssetAsync<GameObject>(zukanItemPrefabAdd);
        await zukanPr.Task; //非同期完了を待つ

        if (zukanPr.Status != AsyncOperationStatus.Succeeded)
        {
            //失敗時
            Debug.LogError($"Failed to load prefab: {zukanItemPrefabAdd}");
            return;
        }
        GameObject zukanPlehub = zukanPr.Result;

        foreach (var zItem in zukanItems)
        {
          //ここにプレハブ生成やオブジェクトの有効化など要件に応じて必要な処理を書く
      }
    }

プレハブを並べるのは、スクロールビュー上のコンテントの中に並べるようになります。

実行すると、こうやってアイテムIDが名前のプレハブが並びます。

図鑑詳細画面 〜Unityで図鑑画面の作り方の概要設計〜

ちょっとまだ未完成ですが、未来の自分のためにメモを残しておきたいです。

ボタンを押したら詳細画面で必要な情報をマスタのアイテムDBに取りにいきます。

そして、詳細用キャンバスに情報をセットしてアクティブにします。

詳細画面実装にあたっての葛藤や壁

初心者にとって結構な壁でした...。

プレハブにアタッチしたスクリプトの変数にアサインできない

要は、プレハブ上にあるボタンに、詳細キャンバスを開くためのC#スクリプトをアタッチし、スクリプトの中で詳細用キャンバスに情報をセットしたかったけど、プレハブにアタッチしてあるスクリプトには、特定のシーンのオブジェクトをアタッチできない。

という状況です。

解決にあたって別の選択肢も浮かんだのですが、そちらは不採用にしました。

没案1 ボタンプレハブ全てが詳細キャンバスを持っている形

ボタンプレハブ全てに画面いっぱいの詳細キャンバスを持たせておいて、最初の情報取得時に全てのアイテムで詳細画面を作ってしまい、ボタンをタップしたらアクティブにする という案です。

今文章を書いててこっちの方が良いんじゃないかともなんとなく思うのですが、

透明とはいえ、大量のキャンバスをシーンに呼び出すというのが気が引けてしまい不採用にしました。

でも、アイテム件数によっては全然良いかもしれないので今度試してみようかな。

没案2 都度単体アイテムをセレクトせずに、プレハブ生成時にローカル変数に持たせる

今はボタンを押すたびに対象のアイテムデータをテーブルから取ってくるようになっています。

せっかくボタン生成時にアイテムリストでループしてるので、そこで書くプレハブに図鑑内容を全部保持するセッターをつくって保持させておいてもいいのかなと思ったのですが、

データベースに接続するといっても、unityゲームのアセットの一部、ローカルにDBがあるため、みるかもわからないアイテム全ての説明文などの文字を大量にロードしてしまうよりも

タップした時に必要な情報だけを取ってくる方が良いのかなと思いました。

最終的なアイテム数と相談してもいいのかもしれません。

残留課題メモ

・未取得アイテムは詳細を開かないor詳細が未取得用になるようにすること

・画像をあどれっさぶるあせっとで対応させる

コメント

タイトルとURLをコピーしました