PSDファイルからUIレイアウトをインポートする自作ツールの紹介

PSDファイルからUIレイアウトをインポートする自作ツールの紹介

こんにちは。エンジニアの鈴木聡です。

私が携わっているプロジェクトでは、多くのUIを作成する必要があるため、Photoshop上で作成したレイアウトをUnityにインポートして使用できるようにするUnityEditor上のツールを作成しております。

これにより、UIデザイナーさんが組み上げたレイアウトが、正確にUnity上に取り込むことができるようになり、手戻りを大幅に削減することができる状態になっております。

今回は、そのツールであるPSD Layout Importerについての紹介をしたいと思います。

インポートの流れ

まずはPhotoshopを用いてUIレイアウトを組み上げ、PSDファイルとして出力します。そして、そのPSDファイルをPSD Layout Importerでインポートすると、UnityUIのprefabが生成されます。

Photoshop上でこのように作成してインポートすると…

Unity上でこのような形になります。

あとは細かい調整やコンポーネント設定を行い、GitHub上でPullRequestを出してもらいます。ここまでがUIデザイナーの作業になります。

作成されたPullRequestはエンジニアの方でもレビューを行い、レビューが通るとマージされます。あとはエンジニアの方でそのprefabを用いて実装作業を行うことになります。

役割分担とフローがはっきりしていていい感じですね!

…実際にはこの後にアニメーション制御や自動レイアウトやリスト表示などが待っているのですが… そちらについてはUIデザイナーとエンジニアで協力して対応するようにしています。

ツール内部の流れ

PSDファイルを読み込んでバイナリ解析

まずはPSDファイルを読み込み、バイナリ解析をして各種レイヤー情報を取得します。バイナリ解析は、公式のファイルフォーマットが公開されているので、その内容に従って読み解いていきます。
https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/

最初のうちは、フォーマットに従って読んでいけばよいのですが、途中からはDescriptorのような汎用的なフォーマットで親子表現ができるような場所が出てくるので、機能をうまく分離して、再帰的に呼び出しができるようにしながら読み進めていく必要があります。

さらに、Raw dataのところは特に説明がないテキストデータになっているので、ぼんやりと眺めて法則性を見出してデータを取り出していきます。

こんな感じのバイナリデータを

<<../EngineDict..<<.../Editor...
<<..../Text.(~..c.,..)...>>.../P
aragraphRun...<<..../DefaultRunD
ata....<<...../ParagraphSheet...
..<<....../DefaultStyleSheet.0..
..../Properties......<<......>>.
....>>...../Adjustments.....<<..
..../Axis.[.1.0.0.0.1.0.]....../
XY.[.0.0.0.0.].....>>....>>
//}

こんな感じでぼんやりと拾ってみたりしています。

EngineDict : 
  Editor : 
    Text : 能力
  ParagraphRun : 
    DefaultRunData : 
      ParagraphSheet : 
        DefaultStyleSheet : 0
        Properties : 
      Adjustments : 
        Axis : [ 1.0 0.0 1.0 ]
        XY : [ 0.0 0.0 ]

※ 細かい解析内容については「Aiming Tech Book Vol.2」に記事を書いていますので、気になる方はそちらを参照していただけると幸いです。
https://aiming.booth.pm/items/1578389

解析されたデータを用いてUnityUIを構築

解析が終わると、全てのデータが一つのインスタンスとして格納されますので、そのデータを参照してUIを構築していきます。ただ、ぱっと見だと中身がわからない状態になっているので、別途用意してあるログ出力を使ってテキストファイルとして出力を行い、そのファイルを参考にして拾うべきデータを抽出していきます。

このようなログが出ていたら、

fileHederSection :
  height : 1334
  width : 750

こんな感じで取得するイメージです。

// キャンバスサイズ
// ドキュメントのサイズから取得
var fileHeaderSection = (Dictionary<string, object>)document["fileHeaderSection"];
var canvasWidth = (float)(int)fileHeaderSection["width"];
var canvasHeight = (float)(int)fileHeaderSection["height"];

そして取得されたレイヤー情報を用いて、UnityUIのprefabを組み上げます。

var canvasGameObject = new GameObject();
var canvasRectTransform = canvasGameObject.AddComponent<RectTransform>();
canvasRectTransform.sizeDelta = new Vector2(canvasWidth, canvasHeight);

prefabが完成したらファイル出力して完了です。

最後に

PSD Layout Importer について、UIレイアウト作成ツールの一例として紹介させていただきました。プロジェクトの要件やメンバー構成によって、必要なツールやフローが変わっていくと思いますので、その時その時で最適な環境を整えて、全体の開発効率をあげることができれば、と思っております。

ゲーム開発を進めるに当たって、何かしらの参考になれば幸いです。