PythonでUnityのPrefabを編集してみた

WRITER: admin
2020/06/02

はじめまして、開発GUnityクライアントエンジニアをしております

定期的にあるPrefabの編集作業、編集箇所は決まっていて作業量は少なくても
いざエディターで開いて編集すると意外と時間がかかっていることがありませんか?

インスペクターからSpriteを別のものに差し替えたり、テキストの修正だけなら
実際作業している時間よりエディターを立ち上げている時間の方が長いのでは・・・?
と思うこともしばしば(個人の感想です)

ということで、エディター外部からPrefabを編集してみることにしました

Prefabファイルの内容

編集するにあたってまずPrefabファイルが何者なのかを確認しましょう
テキストエディタで開くと、中身はどうやらYAML記法のテキストのようです


詳しい書式の説明も公式に記載されています  フォーマットに関する説明

さて、YAMLならYAMLのパーサーがあるから安全に編集できそう、と思ったのですが、
どうやらPythonで有名どころのPyYAMLではTag諸々の関係でUnityのYAMLは読めないようです

テキストとして編集するのはうっかり壊しそうですし、パーサーの自作も大変……

と調べていたら、すでにライブラリがありました

UnityPerser

https://github.com/socialpoint-labs/unity-yaml-parser

内部ではPyYAMLを利用しているようでした
Unity用のローダーなどを渡したり、Unity固有タグを足したり、といった部分を担ってくれているよう

使い方はサンプルにあるように、ファイルパスを渡してload/dumpするだけなので手軽に使えそうです

 

実際に使ってみた

このPrefabを編集してみます

1.自作クラスのフィールドを編集する

banner.prefabの_currentEventIdを書き換えます

実行するスクリプトはこちら

実行すると、以下のように書き換わっています

エディターで確認してもこの通り、反映されています

特定のコンポーネントの_currentEventIdだけを変えたい場合はコンポーネントのguidで検索

 

2.Spriteの参照入れ替え

以下のようにprefabとtextureでまとめて別ディレクトリに入っている構成で
prefab以下のevent01を複製しevent02をつくります

event02以下のbanner.prefabのImageは
textures以下のevent01の画像を参照しています

これをevent02の画像に差し替える場合について考えます

画像の名前とguidをDictionaryか何かで紐づけて置換すれば良さそうですね
画像のguidはmetaファイルから取得できます
画像名もイベントの連番部分が変更されているのでそこの対応もいれると、以下のようなスクリプトになります

このスクリプトを実行すると

参照しているSpriteの差し変えができています

 

この部分ですが、公式のサンプルのように直接キーでアクセスすると、guidがNoneになってしまうものがありエラーがでるので調べたところ、attributesで指定した名前を「含む」attributeを持った要素が返されるようでした

 

使ってみての感想

思ったより手軽に書き換えができるようでした

fileIdを参照して特定のオブジェクトのコンポーネントを編集、という使い方もできるとよかったのですが
標準では対応していなさそうでした

しかし、数秒とかからない実行時間は魅力ですし、c#+エディタ拡張での対応よりもExcel等外部ファイルとの連携もしやすそうです
他にもJenkinsと組み合わせて自動化したり、対話型のスクリプトを書いて小回りの効くCLツール化もできそうです

ちょっとした入力値のチェックも挟みやすいので、一部では手作業よりもミスを減らす効果も期待できるのではないでしょうか

うまく使っていけると開発効率が上がりそうですね!

いくつか定常作業をまとめてツール化してみたいと思います
ぜひ皆さんもUnityParser使ってみてください!