[unity] XlsToJson 実際に運用する際のちょっとしたテクニック

XlsToJson の基本的な使い方はこちらを参照してください。

本記事は、書きそびれたいくつかのテクニックを紹介しておきます。

手修正した Json や Scriptable Object を、エクセルに逆出力したい

unity でパラメータを修正しながら動作を確認するようなツールを作成した場合、こういった逆出力が必要になるかもしれません。

Tools/XlsToJson/[Xlsx Update] JsonData(Scriptable Object) -> ????.xlsx を実行することでテーブルをエクセルに書き出すことができます。

但し、enum やサブクラスは逆出力できません。これらを修正したい場合、必ずエクセルで行うようにしてください。

また、残念ながら const 設定値は素の値になってしまいます…こちらは仕様とさせてください。

シート(テーブル)によって出力形式(Json / ScriptableObject)を切り分けたい

簡単なのは出力形式によってエクセルファイルを分けることです。
それぞれのエクセルファイルで XlsToJson Settings... を使い、必要な出力形式のみにチェックを入れて作成します。

CREATE Importer したら自動生成されたコードでエラーになり、詰んだ

エクセルの記述ミスなどでコードにエラーが発生するかもしれません。
Editor/uindies/XlsToJson/importer 内のコードでエラーの場合は、一旦全部消してしまうのもアリですが、テーブルクラスやアクセッサクラスでこの状態になると、既にテーブルを使用したゲームクラスとの兼ね合いで泣く泣く手修正(不毛)することにも…。

既に出来上がっているテーブルクラスの更新は危険が伴うので、更新前にはバックアップしておきましょう。CREATE Importer で再作成する前に、Git にコミットしておく事をオススメします。

XlsToJson の不具合のようであれば、ご報告お願いします!

データをIDで検索する

XlsToJson ではオートナンバリングされた ID というフィールドが必要ですが、このフィールドを使って行を検索することができます。
アクセッサを使った例を示します。

var row = Character.FindRowByID(1);
Debug.Log($"{row.CharacterName}"); // 結果は Jessie

ID 以外のフィールドを Find 対象にする

ID だけではなく、例えば CharacterName から行データを取得したい場合、CharacterName* とエクセルに記述してください。(アスタリスクをつける)

すると、クラスに FindRowByCharacterName というメソッドが新たに自動作成されます。

var row = Character.FindRowByCharacterName("Bob");
Debug.Log($"{row.CharacterNo}"); // 結果は 2

Find 対象にするフィールド内容は重複しないようにしてください。
重複している場合、その中で最初に見つかった1つしか検索することはできません。

条件により、複数のデータを抽出する

このようなデータで、「女性(Female)だけ」を抜き出したいケース。
残念ながら、XlsToJson だけでこれを満たすコードは自動生成されませんので、以下のように抽出クラス(CharacterEx.cs)を作成します。

using System.Collections.Generic;

public partial class Character
{
    public static List<Class_Character.Row> FindRowsBySex(Class_Character.Sex sex)
    {
        return Rows.FindAll( (row) => row.Sex == sex );
    }
}

ソース名は CharacterEx.cs ですが、クラスは Character であり、partial としてある点がミソです。
こうすることで、例えテーブルの形が変わり、後にアクセッサのコードを作り直したとしても、自前で作成したコードは残り、上書きされることはありません。
使い方も今までと同じ。

var list = Character.FindRowsBySex(Class_Character.Sex.Female);
list.ForEach((row) => Debug.Log($"{row.ID} {row.CharacterName} {row.Sex}"));

4件のコメント

  1. 1年以上も前の記事に、コメント失礼いたします。
    XlsToJson、まだ触り始めたばかりですが、シンプルで使いやすく、まさにこれが欲しかったというもので助かっております。
    ちなみに、Bing Copilotに教えてもらい知りました。

    使っていて、この機能があったらいいなと思った点と、こればもしかしてバグなのかなと思った点がありましたので、もし今後アップデートされるご機会があればご参考にしていただければと、記載させていただきます。

    ■あったらいいなと思った点:コメント行機能
    例えば、ID列に「-1」など特定の値を入れることで、その行をコメントアウトする機能があると便利だと思いました。
    例えば大量の敵データを扱う際に、ここから下はステージ2用…というように区別したく、その際にこういったコメント行機能があると、格段に便利になります。
    (実はゲーム会社勤務なのですが、会社で使ってるデータフォーマットでは、行・列とも可能で便利に使っています)

    ■バグかと思った点:EnumをFIND対象にするケース
    このページでご説明のある、ID 以外のフィールドを Find 対象にする方法ですが、この対象でenumを使うと、上手く動作しませんでした。
    具体的には、ChrParamというテーブルで、
    ID Label* name
    int enum:Label string
    と、そのテーブルで定義しているenumを入力するパラメータに「*」を入れた場合、このケースで言えば
    FindRowByLabel()
    関数に渡す引数が、
    Class_ChrParam.Label型
    ではなく、単に
    Label型
    という存在しない型になってしまっており、エラーが出てしまいました。

    ※ちなみに、これは何をしようとしているかというと、数字のため少々使いにくいIDの代わりに、ユニークなenumをセットしてこれを使おうとしております。
    stringのnameだと、検索の負荷が重いのかなと思い、enumでと考えました。
    ただ、enum定義の時の並び順と、実データとが一致していれば、
    ChrParam.Rows[(int)Class_ChrParam.Label.chr2]
    で呼ぶことも出来る(そして多分こちらの方が高速?)ので、実際に使う際はこちらでと考えております。

    それでは、失礼いたします。

    1. みだけさん

      コメント、有難うございます。お役に立てたようでなによりです。
      頂いたお話を元に改善してみますね。しばらくお待ちください。

    2. みだけさん

      調整内容と、仕様についてお答えします。

      ◆ 調整:コメント行機能
      数字ではなく、なんらかの文字を入れると警告とともに行の取り込みをスルーするようにしました。
      X などを入れておくといいでしょう。

      ◆ 仕様:EnumをFIND対象にするケース
      enum には [ENUM] と [GLOBAL_ENUM] がありますが、「Class_ChrParam.Label型」と仰っているのでおそらく [ENUM] の事だと推察します。
      クラス内 ENUM は同名で定義されることがあります。例えば Stage.EnumColor と Enemy.EnumColor のようなケースですね。

      こういったケースも考慮し、クラス内 enum の場合「どのクラスの enum か」エクセルで明示的に記載する必要があります。
      具体的にはこのように記載します。

      enum:Stage.EnumColor / enum:Enemy.EnumColor

      EnumColor が Stage と Enemy 共通の場合は [ENUM] ではなく [GLOBAL_ENUM] をご指定ください。
      こうすると、クラス内 enum ではなくどこからでも使える enum になるため、以下のように記述できます。

      enum:EnumColor

      ◆ ChrParam.Rows[(int)Class_ChrParam.Label.chr2]
      実行速度を最速にしたいケースにおいては、例えば以下のように [CONST] を使うことも検討してください。
      enum をキャストするコストも不要にすることができます。

      > Stage シート
      [CONST]
      int
      TYPE_A 1
      TYPE_B 2
      TYPE_C 3

      > Stage1@Stage シート
      SubClass.Member0
      int
      Stage.TYPE_A

      * enum の方が記載はスマートかつ自由度が高いので、最速が必要なければ、そのままでもいいと思います。

      「シンプルで使いやすい」は最高の褒め言葉ですね。
      割とどんなケースでも直感的に使える事を念頭に置きましたが、ルールを複雑にしない事には結構苦労した覚えがあるので。とても嬉しかったです。

      なお、諸事情により今後あまりブログを更新しない可能性があるので、
      なにかありましたら catsnipe@(@は半角)gmail.com までご連絡ください。

  2. 迅速なご対応ありがとうございます!
    また、enumの件、こちらの書き方が間違っていたんですね、申し訳ありません。

    早速試してみます!ありがとうございます!

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA