.mochi.xml がどの要素でできていて、それぞれが Unity の何になり、どの順で展開されるかの説明です。要素ごとの規則は要素のリファレンス、属性の値の書き方は値の文法にあります。
| |
|---|
| 形式 | 整形式の XML です。大文字と小文字を区別します |
| ルート要素 | 1 ファイルに 1 つで、名前はファイル名から .mochi.xml を除いた部分と同じです(MOCHI1003) |
| コメント・XML 宣言・処理命令 | 書けます。読み飛ばします |
| 要素の間の空白と改行 | 読み飛ばします |
| 属性の値の中の改行とタブ | XML の規則で空白に置き換わってから読まれます |
| 書き方 | 扱い | 番号 |
|---|
要素の中の文字(<Object>Hall</Object>・CDATA) | 書けません。値は属性に書きます | MOCHI1006 |
子要素で値を書く(<Transform> 要素) | 書けません。位置・回転・拡大はホストの属性に書きます | MOCHI1004 |
名前空間(xmlns・接頭辞) | 書けません | MOCHI1007 |
| DOCTYPE | 書けません | MOCHI1001 |
要素は、Unity に何を作るかで次の 6 種類に分かれます。
| 分類 | 意味 | 要素 |
|---|
| ルート要素 | ファイルの最上位の要素です。名前は部品の名前で、エントリポイントでは prefab のルートの GameObject になります | 部品の名前のタグ |
| ホスト | GameObject を 1 つ作る要素です。name・position などの共通の属性を受け付けます | <Object>・<Row>・<Grid>・<Prefab>・部品のタグ |
| コンポーネントのタグ | 親の GameObject にコンポーネントを足す要素です。名前は Unity のコンポーネントの型名です | <MeshRenderer>・<Light> など |
| 制御 | 中身を、データの行の数だけ、または条件が真のときだけ展開する要素です。自身は何も作りません | <For>・<If> |
| 宣言 | 部品が受け取る props を宣言する要素です。何も作りません | <Props>・<Prop> |
| 差し込み | 中身の行き先を示す要素です。<Slot> は使う側が書いた中身を受け取り、<At> は prefab の中の GameObject を指します。自身は何も作りません | <Slot>・<At> |
GameObject を作るのは、ルート要素とホストの 6 種類のタグだけです。
| タグ | 作る物 | name を書かないときの名前 |
|---|
ルート要素(<Hall prefab="true"> など) | エントリポイントとして生成するとき、prefab のルートの GameObject | 部品の名前(name は書けません) |
<Object> | GameObject 1 つ | GameObject |
<Row> | GameObject 1 つ(子を +X 方向へ並べます) | Row |
<Grid> | GameObject 1 つ(子を格子状に並べます) | Grid |
<Prefab> | prefab のインスタンス 1 つ | prefab のルートの GameObject の名前 |
部品のタグ(<Plaque/> など) | GameObject 1 つ。部品のファイルの中身がその子になります | 部品の名前 |
| コンポーネントのタグ | 作りません。親の GameObject のコンポーネントになります | なし |
<For>・<If> | 作りません。中身のホストが、<For>・<If> の親の子になります | なし |
<Slot> | 作りません。使う側が書いた中身のホストが、<Slot> の親の子になります | なし |
<At> | 作りません。子のホストが、指した prefab の中の GameObject の子になります | なし |
<Props>・<Prop> | 作りません | なし |
次の例を生成すると、prefab の中は下の図のヒエラルキーになります。
<MeshFilter mesh="builtin:Plane"/>
<Row spacing="0.5" position="0 1.5 4">
<For each="art" in="folder('../Gallery/art/')">
<Plaque title="{art.title}"/>
<Prefab src="../Kit/KitFrame.prefab" position="3 0 0"/>
<!-- file: Assets/Hall/Plaque.mochi.xml -->
<Prop name="title" type="string"/>
<Object name="{title}" size="1 0.5 0.1"/>
Hall ← ルート要素(prefab のルート)
├─ Floor ← <Object name="Floor">。MeshFilter と MeshRenderer が付く
├─ Row ← <Row>。name を書かないので Row
│ ├─ Plaque ← <Plaque>(<For> の 1 行目・01_Sea.png)
│ │ └─ Sea ← Plaque.mochi.xml の <Object name="{title}">
│ └─ Plaque ← <Plaque>(<For> の 2 行目・02_Moon.png)
└─ KitFrame ← <Prefab>。prefab のルートの名前
├─ Canvas ← ここから下は KitFrame.prefab の中身
<Plaque name="Entrance" title="Welcome"/>
<Plaque name="Exit" title="Goodbye" offset="0 2 0" position="6 0 0"/>
<!-- file: Assets/Hall/Plaque.mochi.xml -->
<Prop name="title" type="string"/>
<Prop name="offset" type="Vector3" default="0 1.5 0"/>
<Object name="{title}" position="{offset}"/>
| |
|---|
| 部品 | .mochi.xml の 1 ファイルです。ファイル名から .mochi.xml を除いた部分が部品の名前で、ルート要素の名前も同じです |
| 部品の使い方 | 部品の名前をタグとして書きます。使った所に GameObject が 1 つでき、部品のファイルの中身(<Props> を除く)がその子になります |
| props | 部品の引数です。部品は <Props> に <Prop> で名前・型・既定値を宣言し、使う側は部品のタグに props の名前を属性として書いて値を渡します |
| props の渡し方の規則 | 関数の引数と同じく、宣言に無い名前は渡せず(MOCHI3005)、default の無い props は省けません(MOCHI3008)。ホストの共通の属性(name・position など)は props にならず、使った所の GameObject の属性になります |
| エントリポイント | ルート要素に prefab="true" を書いた部品です。保存すると、このファイルから prefab を 1 つ生成します。ほかのファイルから部品として使うこともできます |
| エントリポイントの props | 値を渡す側が無いので、全部の props に default が必要です |
| |
|---|
| 値の書き場所 | 属性だけです。要素の中の文字や子要素で値を書く書き方はありません |
| 型 | 属性ごとに決まっています(position は Vector3、active は bool など)。書いた文字をその型の値として読みます |
| 束縛 | 値の全体を {名前} か {行.列} と書くと、props か <For> の行の値を読みます。文字の途中には書けません |
| ホストの共通の属性 | name・key・position など 14 個です。RectTransform を持つ GameObject は、位置と大きさを RectTransform の属性で書きます(RectTransform を持つ GameObject) |
| 要素ごとの属性 | <Prefab src>・<For each>・<Row spacing> などです |
| 部品のタグの属性 | ホストの共通の属性と、その部品が宣言した props です |
| コンポーネントのタグの属性 | Unity のコンポーネントの C# のプロパティ名です(<Light intensity="2"/>) |
slot 属性 | 部品のタグの子に書き、その子をどの <Slot> へ渡すかを選びます |
| |
|---|
| 生成時に決まる値 | Unity で保存して prefab を生成するときに決まり、prefab に書かれる値です。定数・runtime の無い props・<For> の行は全部これです |
<For> と <If> | 生成時に展開します。ワールドの実行中に行の数や条件は変わりません |
| 実行時に変わる値 | T# スクリプトを持つ部品の中で、runtime="true" の props か、その部品の C# のメンバーを束縛した値です |
| 実行時に変わる値を書ける所 | active と、runtime="true" の props だけです。ほかの属性は MOCHI5004、<If test> は MOCHI5003 です(実行時に変わる値) |
| 段 | 内容 |
|---|
| 1. 部品の目録 | Assets/ と Packages/ の下の .mochi.xml を、ファイル名で部品として登録します。ファイルの中身は、そのタグが使われたときに読みます |
| 2. エントリポイントの読み込み | XML として読み、ルート要素の名前・prefab 属性・<Props> を確認します。props には default の値が入ります |
| 3. 展開 | ルート要素の子を、書いた順に展開します。ホストは属性の値を読んで GameObject を作り、それから子を展開します |
| 3a. 部品のタグ | props の値を使う側で読んでから、部品のファイルの中身を、使った所の GameObject の子として展開します |
3b. <For>・<If> | <For> はデータの行ごとに、<If> は test が true のときだけ、中身をその場に展開します |
| 4. 並べる | <Row>・<Grid> は、子を全部展開した後で子の位置を決めます |
| 5. 書き出し | エラーが 1 つも無いときだけ、prefab とマテリアルの複製を書きます(保存での生成) |
束縛の {名前} で読める名前は、書いた場所で次の 7 通りに決まります。
| 書いた場所 | 読める名前 |
|---|
| 部品のファイルの中 | そのファイルの <Props> で宣言した props と、属性を囲む <For> の行(同じファイルの物) |
| 部品の中から見た、使う側の props と行 | 読めません。部品の中で使うときは、props として渡します |
| 使う側が部品のタグの子に書いた中身 | 中身を書いたファイルの props と行です。部品の props は読めません |
入れ子の <For> | 内側から外側の行も読めます。同じ名前の行は内側が優先されます |
| props と同じ名前の行 | その <For> の中では行が優先されます |
<Prop default> | 名前を読めません(束縛は MOCHI5001) |
| T# スクリプトを持つ部品の本体 | props でも行でもない名前は、その部品の C# のメンバーとして読みます(実行時に変わる値) |