👻塗り絵を自機にして遊べる３Dゲームを作った話🎃

## はじめに

　この記事では、パソナグループファミリーデー向けに社内の有志で作成した「ぶっとびオバケ」というゲームについて書きます。
 ![スクリーンショット 2023-09-27 18.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/02cfbe06-3fb3-7c01-8ff4-716acf7f984a.png)

　本記事のタイトルでは「塗り絵を自機にして遊べる3Dゲーム」としていますが、より詳細に説明すると「自分で塗った絵を取り込んで、空気入れを改造して作ったデバイスを操作することで操作する体感協力ゲーム」といった感じになります。
　「ぶっとびオバケというゲームについて書く」と書きましたが、正確には「塗り絵の画像をアバターに反映する」と言う部分について解説します。
 　なお、この記事はあくまで大まかな流れを紹介するダイジェストであり、この記事の通りに操作したら同じものが作れるという性格のものではありません。また、頭の中で作業を振り返って執筆しているので曖昧な点や矛盾する点が含まれている可能性がありますので、予めご了承ください

### パソナグループファミリーデーとは？
パソナの社員やその家族のための年に一度のイベントです。２０２３年は１０月１４日に開催されました。
https://www.pasonagroup.co.jp/familyday/

## 誰がこの記事を書いたの？

　プログラマーの Atsushi Yonenagaです。
 　普段は業務でWebフロントエンドの開発などを行っていますが、個人的なプロジェクトでUnityを使ったVRコンテンツの開発なども行っています。
　このゲームで自分が担当した部分は、アバターのモデリングやアニメーション作成、Unityのゲームロジックからの制御繋ぎこみなどです。

## 使用ツール
モデリングソフト（Blender）
ペイントソフト（Affinity Photo）
ゲームエンジン・エディタ（Unity）

## 方針
　塗り絵を取り込むことのできるアトラクションとしては、先行事例が色々あります。例を挙げると……
 
 リトルプラネットの「Draw Your World」
 https://litpla.com/attraction/3dnurie/

 チームラボの「グラフィティネイチャー」
 https://www.teamlab.art/jp/w/graffiti_nature_reborn/amosrex/
 
 など。今回はこれに似た仕組みを開発しました。
 
　さて、このゲームの開発はあくまで社内向けイベント用の出店品です。あまり高度なことをする工数もありませんので、塗り絵をキャラクターに反映させる仕組みについては、UVマップの工夫でなんとかすることにしました。UVマップとは、二次元のテクスチャのどの座標を3次元のモデルの面のどの部分に対応させるか？というマップです。現代のゲームではUVマップが使用されるのが一般的で、今回はこのUVマップの形状を工夫することで塗り絵に塗られた色をゲーム内のアバターに反映させることにします。
 
　スキャンした塗り絵をテクスチャ画像として使用する手法としては、OpenCVを使った特徴点検出とか射影変形などを使用することもできますが、今回はそういったことは考えないことにします。デジタル画像上での塗り絵の位置が概ね一定であることを前提にした実装とします。
　「UVマップを工夫することで塗り絵を取り込む」を実装するにあたり、作戦としてはプレイヤーには「前から見た図・後ろから見た図」を塗ってもらい、前後から貼り付けることにします。

## モデリングする
　Blenderを使用して、今回のゲームの主人公であるオバケのアバターをモデリングしていきます。ちなみになぜオバケなのかというと、ファミリーデーが開催されるのが１０月中ばでありハロウィーンに近い時期だからです。風船のようなお化けに空気を入れて膨らませてそれで飛ばすというゲーム内容なので尻尾（？）のあたりを風船っぽいデザインにしています
 　ゲームのモデル作成では後の工程を考えて作業する必要が往々にしてあり、今回も前と後ろの２視点から見た時に隠れる部分が無くなるように少し配慮しながら作成しました。
  ![スクリーンショット 2023-12-24 16.50.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/048db5f4-864a-1243-fe47-df6b4698883e.png)

## シームを入れる
　後工程であるUV展開のためにメッシュにシームを入れていきます。今回はプレイヤーに前と後ろに分けて塗ってもらう形式にしたので、概ね前後の２パーツに分かれるように、オバケの体の側面を通るようにシームを入れていきます。こうすることでUV展開時に前後２つのパーツに分かれます。通常であれば腕を別パーツにしたりすると思うので、ここが通常のUV展開と違うところです。
 ![スクリーンショット 2023-12-24 16.51.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/f03977ec-1982-d69b-62f3-66b57629fe46.png)


## UV展開する
　シームを入れたらUV展開を行いUVマップを作成します。正しくシームが入れてあれば、モデリングソフトの機能でうまくUVマップに開いてくれるはずです。後工程で文言や名前の記入欄を作ることを想定して配置しておきます。（塗り絵のフォーマットの下書きを用意しておいて、それを元にUV展開しても良いかもしれません）
 　納得のいく配置になったら、UVマップをエクスポートします。
  ![ghost_uv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/ad658338-4e75-7225-cf35-a42dcc4875d0.png)

## リギング、スキニング、アニメーション作成、ブレンドシェイプ作成など
　ゲーム内ではお化けはフワフワと浮遊したり、ビューンと飛んで行ったりするので、それを表現するためにアニメーションを作成します。また、空気を入れたり逆に抜けて行ったりするのでそれを表現するためのブレンドシェイプの作成なども行います。ここは一般的なゲームと変わらないので詳細は割愛しますが、こちらの画像を見ると、今まで直立していたオバケが自然なポーズになったことがわかるかと思います。
![スクリーンショット 2023-12-24 16.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/d8df3bce-f2de-9f4c-a48d-2b201e9beb5d.png)


## 塗り絵のフォーマットを作る
　ペイントソフトでUVマップ画像を開き、それを下敷きにして塗り絵用のお化けの絵を描いていきます。UVマップ画像の上にレイヤーを追加し、ペンツールで描画します。のっぺらぼうだと前後がわかりませんし、ちょっと怖いので顔を描いてあげます。
 ![GhostFormat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/2f6f9695-16a8-4df5-9972-a8e501a0b5ff.png)


## 画像を取り込む
　ここまで作成したモデルやUVマップがうまく機能するかテストするために、塗った画像を取り込みます。PCやタブレットなど、デジタルで塗る仕組みであれば枠のズレが発生しません。まずはこの方法でやってみます。スマホを使って撮影するだけでも、アングルとフレーミングに気をつけていればそれなりに見えるはずです。
![SamplePaint2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/7a0b53d2-8973-252d-274a-c6407649d23e.png)

## マテリアルに画像を貼り込む
　Unity内で、お化けに割り当てるマテリアルを作成し、そこに画像を貼り込みます。UnityエディタのAsset内に上記の画像を取り込み、作成したマテリアルのEmission > Color にドロップします。
 ![スクリーンショット 2023-12-24 17.06.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/43fb26de-5523-707d-222a-0bb09002ac43.png)
これで、塗り絵の画像がゲーム内のキャラクターに反映されます。
![スクリーンショット 2023-12-24 17.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99567/e78db0e4-7cdf-4b81-2fa8-8daae3fafd2f.png)


## ファイル読み込みや動的な画像貼り込み処理の作成
　ここまでの開発手順で塗り絵の画像をゲーム内のアバターに反映することができましたが、実際にイベントで展示するゲームとして使用するためには、その場で撮影・スキャンした画像を読み込み、それをマテリアルに設定する処理が必要になります。今回は「streamingAsset上のpng画像を `File.ReadAllBytes()` メソッドで読み込む」「オバケのモデルに対して `GetComponent<Renderer>().material.SetTexture()` を実行する」といった処理で、ゲームの実行時に塗り絵をオバケに反映させています。

 ## まとめ
　以上が、塗り絵をゲーム内に取り込む仕組みのざっくりとした解説になります。こちらの記事を読んでどのように感じましたか？個人的には、3Dモデルについてあまり馴染みのない方だと「3Dモデルってこんなに手順が必要なんだ！」と思われるかもしれませんし、逆に3Dモデルについて知識のある方であれば「普通の3Dモデルと比べてそこまで手間をかけなくても実現可能なんだな」と言う印象になるのかな？と想像しています。
 どちらの印象が近かったか、ぜひコメントで教えてください。
 それでは、Merry Christmas and Happy New Year!