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}"));
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]
で呼ぶことも出来る(そして多分こちらの方が高速?)ので、実際に使う際はこちらでと考えております。
それでは、失礼いたします。
みだけさん
コメント、有難うございます。お役に立てたようでなによりです。
頂いたお話を元に改善してみますね。しばらくお待ちください。
みだけさん
調整内容と、仕様についてお答えします。
◆ 調整:コメント行機能
数字ではなく、なんらかの文字を入れると警告とともに行の取り込みをスルーするようにしました。
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 までご連絡ください。
迅速なご対応ありがとうございます!
また、enumの件、こちらの書き方が間違っていたんですね、申し訳ありません。
早速試してみます!ありがとうございます!