テクニカルアーティストが3Dのワークフローを改善した話

# はじめに
[QualiArts Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qualiarts)の12日目担当の@tm8rです。

昨日は@sune2による「[SpriteのPhysics Shapeを使ってuGUIで自由な形の当たり判定を作る](https://qiita.com/sune2/items/cf9ef9d197b47b2d7a10)」でした。

本稿ではQualiArtsのテクニカルアーティスト（以下TA）のざっくりとした歴史と、新プロジェクトへのジョインのタイミングでツールとワークフローの刷新をしたお話をします。

QualiArtsがどんな技術組織でプロダクトを開発、運営しているかはアドカレ1日目の以下の記事をご参照ください！
[QualiArtsの技術組織と技術文化](https://creator.game.cyberagent.co.jp/?p=6633)

# TAとは？
そもそもTAとはなんぞや、という方のために説明すると、ゲームや映像製作においてアーティストとエンジニアの橋渡し役をするような職種です。

会社によって呼び方も役割も異なるので、一言でTAと言ってもその業務範囲は多岐にわたります。

その多種多様さは以下の記事から窺い知ることができます。
[いまゲーム開発で需要が高い役職、テクニカルアーティストとは何か？関係者座談会](https://www.gamebusiness.jp/article/2019/08/30/16123.html)

# QualiArtsのTA
QualiArts（当時はAmebaGames）では2016年の2月にTAチームが立ち上げられました。
2018年からは3Dビジュアライズラボという組織に統合されて、ここに所属するメンバーがそれぞれ横断的に各プロジェクトに関わる形になっています。

現在TAの肩書を持つのは自分を含めた2人で、「**アーティストが製作物のクオリティアップに集中できる環境をつくる**」をテーマに、日々ワークフローやパイプラインの改善、MayaやUnityのサポートなどを行っています。

![アドカレ2019 (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/61bb03e6-cb89-05d7-21a7-da62b1c07aed.png)
2人のざっくりしたスキルセットはこんな感じです。
僕はエンジニア出身なので、どちらかというとパイプライン寄りのTAでゴリゴリコードを書いて、もうひとりはアーティスト出身なのでアート寄りのTAとして役割分担をしています。

# 初期のプロジェクトとの関わり方
TAチーム立ち上げ当初はTAが4人おり、1プロジェクトにだいたい1人から2人がメインの担当としてついていました。

このときには各プロジェクトが既に運用、量産のフェーズに入っていたことに加え、社内標準のワークフローなどはなかったため、要望を受けたタイミングでそれに特化したツールを作成していました。
そのため**共通コードもほとんどなく、プロジェクトに最適な形で都度ゼロベースでツールが作られる**ような形になっていました。
今思えば4人いたからなんとか回っていた感…！😇

# ツールとワークフローの刷新
あるとき新規プロジェクト立ち上げなどの関係で4人のうちの2人がTAチームから外れることになり、TAは現在の2人という状況に。
その後も新規の3Dを扱うプロジェクトが増えていくことを考えると、従来通り都度ゼロからツールを作る形では立ち行かなくなるのは目に見えているので、もともとやりたい気持ちがあったコードの共通化を進めることにしました。

さらに、せっかく新プロジェクトも立ち上がるということで、社内標準となる安全で効率のよいワークフロー、パイプラインを設計することにしました。
ここからは実際に起きていた問題とその改善についてお話します。

## 非効率なツール開発、面倒なツール導入
ツールはGitHubで管理しており、アーティストさんがSourceTreeなどお好きなツールを使用して落としてくる形になっています。

他にも色々配布方法はあると思いますが、**ブランチを切り替えれば実装中の新ツールを試してもらうことができる**点、どうせUnityのプロジェクトがGitHub管理なのでアーティストさんもGitHubから逃れられないという点から、今も昔も配布方法は変わっていません。
（もちろんアーティストさんがGitHubを使用する際のサポートもTAが行っています）

![以前のツールのリポジトリ構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/6a67acb4-837f-cde7-a80a-0004513e9339.png)

以前の構成はこのように絶対に落とす「base」リポジトリ、共通ツールの「common」リポジトリ、そしてプロジェクトごとのリポジトリが存在する形でした。
アーティストさんは最低3つリポジトリを落としてくる必要がある上に、モジュール設定ファイルを自分の環境に合わせて書き換えたり適切な場所に配置したりする必要がありました。

また、各プロジェクトのツールは概ね処理が各ファイルにベタに書かれていて、再利用性が低く見通しも悪くなっていました🤯

![現在のツールのリポジトリ構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/5b1ee535-e1f0-cbdb-7722-1740369837c1.png)
というわけでこのような構成に刷新しました。

ざっくり言うと「core」という共通ライブラリとツールのベース部分を管理するリポジトリを各プロジェクトがサブモジュールとして参照する形です。
これによってツール追加の際のコード量は大きく削減でき、今後立ち上がる新規プロジェクトは従来より低コストでツールを提供する土壌が作れました。

また、1プロジェクトにしか所属してない場合は1リポジトリを落とせば済むようになったので、アーティストさんもハッピーな形になりました😊

![ランチャー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/0fb907e2-15ea-ddcc-6486-db4290101c3b.png)
さらに、あわせてランチャーも作成しました。
ツールのリポジトリを同ディレクトリに落としておけば、このように各プロジェクトのツールを認識し、必要な環境変数をセットした上でMayaを起動してくれるので、モジュール設定ファイルの書き換えや配置も不要になりました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/af5f3a6e-9f5b-6b28-61cb-a398752bb5b8.png" width="460" />
ついでにプロジェクトごとに適切なスプラッシュスクリーンが表示されるのでクリックミスにも気付けるしなんかちょっとテンション上がるしで一石二鳥🤗
（ちなみに起動後はプロジェクト用のシェルフタブが自動的にアクティブになるので、そこでも判別できたりします）

## ディレクトリ構成、命名規則関連
これまではプロジェクト立ち上げのタイミングでTAがいなかったので、効率化や安全性も考慮したディレクトリ構成や命名規則について十分、かつ**継続的に**考えられているとは言えない状態でした。
具体的にはこんな問題が起こってしまっていました。

+ UnityとMaya側でディレクトリ構成が異なるなど、成果物から元のシーンを辿るのが困難
+ どういった種類のものなのかファイル名、ノード名から判断するのが困難なものがある
+ シーン名とFBXの命名が異なるものがある

しかし今回は**プロジェクト開始からリリースまで継続して携われた**ので、アーティストさんやエンジニアの意見をヒアリングしつつ、作業もしやすく、かつ自動化、効率化を見据えた設計ができ、リリースまでに突如発生した新しい種類のアセットもルールから大きく外れない形で対応ができました。

具体的なルールの例は以下のようなものがあります。

+ 少なくとも種類（キャラモデル、キャラモーションなど）単位でディレクトリ階層数をあわせる
+ シーン名からディレクトリ構造が分かるようにする
 + `Model/Chara/Hoge` だったら `model_chara_hoge.ma` にするなど
+ シーン名、グループノード名から対象の種類（キャラ、小物、背景）が分かるようなPrefix、Suffixをつける

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/4505b1c1-7b6c-d365-d881-595d34f05784.png" width="460" />
こういった対応の恩恵の一つとして、この専用のファイラであるファイルマネージャーというツールにおける命名規則に則ったシーンの作成、通常のファイラより高速なシーンへのアクセスの実現が挙げられます。
ファイルマネージャーはYAML形式の設定ファイルでディレクトリ構造や命名規則を管理しているので、プロジェクトごとの対応は基本的にこのYAMLファイルを作成するだけで済みます。

これ以外にも様々な自動化処理に貢献しています。命名規則is大事。

## ミスによる手戻り
モーションで使用しようとしたモデルに問題があって作業がやり直しになったり、エクスポートをしてみたら想定通りに動かない、といった問題が発生していました。

というわけで、まずシーンファイルの管理ディレクトリをWorkという**作業ファイルを管理する領域**とPublishという**正規ファイルのみを管理する領域**に分けることにしました。
![ファイル管理（モデル）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/8dcffcac-3e22-ffc4-bfcd-0d7154c70ef2.png)
モデル製作におけるファイルの流れはこのような感じです。
エクスポーターに関しては次の項目で説明しますが、エクスポーターを実行するとエクスポート対象ごとに適切なバリデーション処理が自動的に走ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/e54bf559-5333-b157-26ed-5ea558a7d5f5.png" width="380" />
問題があった場合はエクスポートがキャンセルされ、具体的な問題がGUIで表示されます。
すべてのバリデーションを通過して初めてシーンファイルがPublish領域に配置される形になります。

したがって、**プログラムで検知可能な問題はエクスポートが完了する前に気付く**ことができ、**Publish領域に配置されているのはこのバリデーションが通った正規のファイルであることが保証される**ので、後工程はこのファイルを参照することで安全性が高まります。
もちろん任意のタイミングでバリデーターを単独で実行することもできます。

![ファイル管理（モーション）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/ddca2b61-9a08-da46-c51d-9ddb8e05b770.png)
というわけでモーション製作におけるファイルの流れはこのようになります。
（モデルをPublish領域からリファレンスしていない場合もバリデーターがエラーと判定するようになっています）

## エクスポートに関わる問題
エクスポート関連では以下のような問題が起きていました。

+ ディレクトリ構成がUnityと異なる
 + エクスポート先が自動解決できないので都度設定する必要がある
+ どのシーンから何が書き出されたのか分からない
+ 複数のモデルのモーションを含むシーンをエクスポートする際、ネームスペースなどの問題から、エクスポートするファイル数分シーンを開いてエクスポートするという作業を繰り返す必要がある

まず、ディレクトリ構成の差分による問題はプロジェクト初期からジョインすることで解決できました。
これによりエクスポート先の自動解決も可能になったので、あとはそのシーンから何がエクスポートされるかが決定できればよさそうです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18707/021b050b-2495-e831-a58e-a3317b4db0b3.png" width="380" />
というわけで、エクスポートの設定をシーンに保存する形にしました。
エクスポーターのGUIを開けばそのシーンから何がエクスポートされるか分かり、以降は誰が作業しても同じものがエクスポートできる状態になりました。

ちなみにエクスポート設定といっても別段複雑な情報は持っておらず、単純にエクスポートの種類（キャラの体のモーション、小物のモデルなど）と、紐づけるノードを持つだけの単純なものです。
また、命名規則が厳格に決まっているおかげで、シーンに存在するノード名からどのノードをどんな設定にするべきかは自動で判別できるので、設定自体は基本的にエクスポート対象ごとにワンクリックで済みます。

一括エクスポート機能も追加し、ベイク処理もできる限りまとめる形にしたので、エクスポートにかかる時間を大幅に削減することができました。

# まとめ
というわけで新プロジェクトには以下のような改善をした新ツール、ワークフローが導入できました。

+ リポジトリの整理とランチャー導入によるツール導入コストの改善
+ 共通部分のサブモジュール化による開発工数削減
+ Publish領域の新設とバリデーターによる手戻りの防止
+ エクスポート設定の保存による再現性の担保
+ 一括エクスポートによるエクスポート時間の短縮

また、新規プロジェクトのリリース後、引き続き新規プロジェクトのサポートをしつつ、既存プロジェクトのワークフローも同じ形式に刷新してアーティストさんの負荷の削減ができたので、TA2人でも継続的に複数プロジェクトのサポートをできる状態がつくれたことが証明できました💪

# おまけ（開発環境など）
最後に開発環境などをご紹介します。

コードはすべてPythonで、UIの構築は原則PySide（Qt.py）で行っています。
エディタは全員PyCharmを使用し、flake8などを使用してスタイルチェックをすることで一貫性を保っています。

ちなみにランチャーもこの知見が活かせるようにPython+PySide2で書いており、PyInstallerでWindowsとMacそれぞれの実行ファイルを作成してGitHubのリリース機能で配布しています。

# さいごに
まだまだ歴史の浅いQualiArtsのTAですが、このような抜本的な改善から、ちょっとしたMayaで起きたトラブルの解決、2Dデザイナーさん用のPhotoshop拡張の作成、果てはタスク管理ツールのカスタマイズまで、大小様々な幅広いサポートを行っています。

また今回のアドカレのような会社の取り組みなどで情報の発信を行っていきますので、少しでもTAに興味のある方々のヒントになれば幸いです。

明日は@k-yamによる「[UnityのProject Tinyを使ってみた](https://qiita.com/k-yam/items/442a1bee6b95ebc93284)」です。
引き続き明日以降の[QualiArts Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qualiarts)もよろしくお願いいたします！🙏