あんスタ！！MVのカメラ設定とキャラクター同士の接触について

# はじめに
Happy Elements Advent Calendar 2020 12日目の記事です。

この記事では「あんさんぶるスターズ！！Music」のMVで使っている仕組みの中からキャラクターの入れ替えに関連する機能を２つご紹介します。

# カメラ設定とキャラクター同士の接触

あんスタ！！Musicは個性豊かな51人のキャラクターが登場するスマートフォン向けゲームです。アプリの主要機能であるリズムゲームでは、背景として3DのキャラクターがダンスするMVをリアルタイムで再生することができます。プレイヤーはキャラクターと衣装を自由に選択することができ、様々な組み合わせでMVを楽しんでいただけるようになっています。

51人のキャラクターの中で最も背が低いのは桃李（とうり）の153cm、最も高いのは紅郎（くろう）の181cmです。下の画像は二人の立ち絵を並べたものです。緑の枠はカメラが映す範囲のイメージです。

![tori_kuro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/6f0a38e5-8369-dd1a-f8e7-0745e18a1c6b.jpeg)

これほど身長差のあるキャラクターを自由に入れ替えるとなると、何も対策しなければ簡単に画面の端で見切れてしまいます。あんスタのMVではキャラクターができる限り見切れないように、また、カメラワークの意図を崩さないようにするため、カットごとに細かな設定を行っています。この記事ではそのカメラの仕組みを実装するためのアイデアを一部ご紹介します。

また、あんスタのMVの特徴としてキャラクター同士が手をつないだり、視線を合わせたり、馬跳びしたり（！）といった様々な接触を行っていることが挙げられます。このようなものは一見難しく思えますが、意外とシンプルな機能で実装することができています。こちらについても重要な点に絞って少し説明できればと思います。

![holy_angels_carol.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/1c5ae361-50b5-b188-c821-ee10f88b70e5.jpeg)
![kangei_2wink_zatsugidan.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/5b761ad3-2437-923c-307d-9620d5349340.jpeg)

# 標準スケールのアニメーション

各機能の仕組みを説明する前にMVで使われているアニメーションについて少し触れておきます。アニメーションのデータはあんスタの外部施策として行っているCGライブ（スタライ）のものに手を加えて使っているものと、ゲーム用として新しく制作しているものの2種類があります。制作は社内では行っておらず、協力会社のフライトユニット様、ダンデライオンアニメーションスタジオ様、マーザ・アニメーションプラネット様を始めとして、多くの人の手によって作られています。

データの由来が複数あることもあり、ゲーム用として使うにあたってまず規格を統一する作業が行われます。このとき、**全てのキャラクターを170cmにした状態で綺麗に見える** ようにアニメーションが制作されています。各キャラクターのモデルは体の倍率（スケール）を1にするとだいたい170cm程度になるように作られており、製作時はその状態で綺麗に見えるように作業が進められ、完成後に実際の体型に合わせて大きさを変えているということです。

このようなことを行っているのは後でキャラクターを入れ替えたときに調整しやすくするためです。例えば身長の低いキャラクターを使ってカメラをつけてしまうと、後で身長の高いキャラクターに入れ替えたときに差が大きくなり、調整が難しくなってしまいます。そこで一旦全員を同じ身長にした上でアニメーションとカメラを制作し、それを正しい見た目ということにしています。実際のアプリに配信するのもこの標準スケールのアニメーションだけで、そこにプレイヤーが選んだキャラクターに合わせてリアルタイムで調整を加えることで自然な見た目を作っています。

（このあたりの仕様はフライトユニット様の主導により決められています）

# カメラ設定について

次にカメラ設定の仕組みについて説明します。詳しく話すと長くなってしまうため、細かい部分については省略しています。なんとなく雰囲気を掴んでいただければ幸いです。

## 一人だけ映る場合

下の ONLY YOUR STARS! のスバルがアップになるカットについて考えてみます。この曲はあんスタ！の主題歌であり、MusicのMVとして始めて公開したものなので思い出の深い曲です。（gifが少しうるさかったので小さくしています）

<img title='only_your_stars.gif' alt='only_your_stars' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/2789a9ea-b3d8-9bc5-d378-c0a7922c2252.gif' width="100" data-meta='{"width":384,"height":216}'>

アニメーションの動きを理解する上で重要なのは原点の位置です。通常、キャラクターとカメラのアニメーションは座標 (0, 0, 0) を原点として動きが作られています。下の画像は上記のカットにおける原点の位置、キャラクターの顔の座標、カメラの座標を矢印で示したものです。

![camera-origin-scale-subaru.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/ccfe8c74-1c90-9ca6-3d69-386439e85795.jpeg)

ここで、各キャラクターの体のスケールを計算してアニメーションに掛け算することを考えます。例えば桃李は153cmなので170cmの標準スケールと比べると0.9倍になります。また、渉は180cmなので1.058倍になります。（実際に使っている数値とは少し異なります）

これらの値をアニメーションに掛け算すると下の画像のようになります。

![camera-origin-scale-tori.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/3bc8855b-37cd-fed5-c970-6b83561e5bc0.jpeg)
![camera-origin-scale-wataru.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/87b21136-bd04-b64e-a60a-6fdb40865b5b.jpeg)

アニメーションの原点が一致しているため、キャラクターとカメラに同じスケールをかけたとしても位置関係は変化しません。画像の右下に映っているのが実際のカメラの映像です。身長が変わっても顔が正しい位置で表示されていることが分かります。

3人の画像を合成すると下のようになります。

![camera-origin-scale-composite-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/113dfb23-b329-6442-9ff6-424b23bc23c5.jpeg)

これだけでもキャラクターを入れ替えたときに顔を正しい位置に映すことができました。
ただ、この方法には一つ欠点があります。

### キャラクターの顔の大きさ

アニメーションに同じスケールをかけた場合、キャラクターとカメラの位置関係は変わらないのですが、キャラクターからカメラまでの距離が変わってしまいます。カメラは背の低いキャラには近づき、背の高いキャラからは遠ざかるため、顔の大きさに差が出てしまいます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/09fb553d-d935-6929-9213-3804a8482542.png" width="300"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/0d89784d-d55d-5aa2-2e73-659f399e2120.jpeg" width="300">

これでもそれほど問題はないかもしれませんが、顔の大きさが変わると受ける印象が変わってしまうため、できれば正しい大きさで表示したいです。また、桃李だけいつも大きめで表示されるのは不平等ということもあります。

### 顔からカメラへの相対座標

そこで別の方法をとることにします。顔の大きさを変えないためには顔からカメラまでの距離を同じにすることが考えられます。実行時に以下のような手順でカメラの位置を計算すれば良さそうです。

- 体のスケールを1にした場合の、顔からカメラへの相対座標を計算する
- それを実際のスケールの顔の位置に足し算する

![camera-origin-scale-subaru-relative-camera-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/4492b1d5-8f5b-d0eb-39c2-8f2a85779177.jpeg)

これにより正しい大きさで顔を表示できるようになりました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/3e12f3db-3e90-63b2-f6ab-5ad22336563d.jpeg" width="300"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/b893d9a0-dea8-27a1-bfa8-2a34759738cf.jpeg" width="300">

### 床へのめり込み

上記の方法は良さそうですが一つ欠点があります。それは身長の低いキャラに入れ替えるとカメラが床下にめり込んでしまうということです。この方法を使って桃李で再生すると下の動画のようになります。顔のアップまでは良い感じですが、その後は見た目が崩れてしまいました。

<img title='only_your_stars_tori.gif' alt='only_your_stars_tori' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/e1217433-f898-d78d-e381-6da53f7e1d27.gif' width="100" data-meta='{"width":384,"height":216}'>

床へのめり込みを避けるためには顔のアップと床の近くで計算方法を変える必要があります。以下のような方法が考えられそうです。

- 顔のアップでは顔からカメラへの相対座標で計算する
- 床の近くでは元のカメラの位置を使う
- 途中は２つの設定をブレンドする

設定のブレンドについては「複数人が順番に映る場合」で説明します。

## 複数人が順番に映る場合

あんスタのMVでは複数のキャラクターを順番に映していくようなカメラワークが使われています。例えば Gate of the Abyss の下のカットでは4人のキャラクターの顔を映しながらカメラが移動していきます（かっこいいシーンなのでYouTubeで見てみてください）。このようなケースに対応するためには少し工夫する必要があります。

https://www.youtube.com/watch?v=7vSYWExt784&feature=youtu.be&t=66

下の画像のような状況を考えます。キャラAとキャラBがいて、時間が経過するにつれてそれぞれ位置を移動していきます。カメラは始めはキャラAの顔を映し、後でキャラBの顔を映すように移動します。 キャラAの顔を映す時刻をt1、キャラBの顔を映す時刻をt2とします。t1とt2の間ではキャラとカメラは自由に動きます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/a392a865-c102-bb2e-df2d-d5a9b73f0d22.jpeg" width="640">

ここでキャラBの身長が低くなった場合について考えます。顔を正しく映すためには時刻t2においてカメラの位置を変化させる必要があります。ここで注意したいことは、自然に見せるためには時刻t2だけではなく、t1からt2の間で少しずつ変化させる必要があるということです。下の図で言うと灰色の点線が元のカメラの道筋で赤い点線が調整後のカメラの道筋です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/87072497-37f7-f523-d649-6f2742491cc7.jpeg" width="640">

カメラを少しずつ変化させるためには **時刻t2でカメラがどのように変化するかを時刻t1で知っている** 必要があります。時刻t2のカメラの位置は上で説明したようにキャラBの顔の位置とカメラへの相対座標で決めることになります。カメラへの相対座標はキャラBの身長が変わる前後で変化しないため、必要なのは時刻t2でキャラBの顔の位置がどのように変化するかということだけです。

例えば、時刻t1において「時刻t2でキャラBの顔の位置が通常より30cm下にある」ということが分かっているとします。その場合、t1からt2の間で少しずつカメラの位置を下げていって、最終的に30cm下げてしまえば正しい位置で映すことができます。

細かい実装方法を説明すると長くなってしまうため省略しますが、このような方法で自然なカメラワークを実現しています。

# キャラクター設定について

次にキャラクター同士の接触について説明します。基本的には以下の2段階で考えています。

- 各キャラクターのスケールの原点を決める
- IKなどを使ってキャラクターの手足を調整する

### スケールの原点の移動

上記のカメラ設定の説明の中で「アニメーションの動きを理解するには原点の位置が重要」ということを言いました。アニメーションに何か数値を掛け算するとキャラクターは原点に対して近づいたり離れたりすることになります。この数値をかけると近づいたり離れたりする点のことを **スケールの原点** と呼ぶことにします。通常、スケールの原点は座標 (0, 0, 0) にあるのですが、あんスタのMVではカットごとに細かく調整できるようにしています。

例えば下の Holy Angel's Carol の手をつなぐカットでは二人の間にスケールの原点を設定しています。これにより背の低いキャラは手をつなぐ位置に少し近づき、背の高いキャラは少し遠ざかるため、結果として自然に手をつなげるようになっています。

![shake_hand_position_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/ae5f379e-3f5f-680b-2e35-82f26b3c0715.jpeg)
![shake_hand_position_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/e2562766-f7bf-e0a3-e916-d90a1d149ad2.jpeg)
![holy_angels_carol.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/2c481bfb-ad5c-e01c-66fa-929ff737d35b.jpeg)

例えばこのカットにおいてスケールの原点を腰の位置に設定してしまうと、背の低いキャラクターは頑張って手を伸ばさないといけなくなりますし、背の高いキャラクターは少し窮屈になってしまいます。

![holy_angels_carol2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/0c4399de-e05b-a7fb-f252-dd1c72d489c7.jpeg)

また、下の動画は羽ばたきのフォルティシモにおけるスケールの原点の移動です。このような複雑なカットではキャラクターが上手く歩けるように細かな設定を行っています。

![habataki_scale_origin.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40753/967ca164-ae35-8a0f-7a54-f9e41c86a559.gif)

### カメラ設定との関係

スケールの原点を移動するとキャラクターを入れ替えたときに顔の位置が変わってきてしまいますが、上で説明したカメラ設定ではそれを考慮して適切な位置を映せるような仕組みになっています。

# おわりに

この記事ではカメラ設定とキャラクター同士の接触について少し説明させていただきました。
あんさんぶるスターズ！！のMVではキャラクターがより魅力的に見えるように様々なことに取り組んでいます。
以下の記事は弊社のデザイナーがMVについて書いたものですので、興味のある方はご覧ください。

[あんスタ！！MVカメラワークのお話](https://note.com/happyelements/n/n87d377cde034)
[あんさんぶるスターズ！！のＭＶ演出と色味について](https://note.com/happyelements/n/n703cd29799b9)


# メンバー募集

Happy Elements株式会社 カカリアスタジオでは、
いっしょに【熱狂的に愛されるコンテンツ】をつくっていただけるメンバーを大募集中です！

もし弊社にご興味持っていただけましたら、是非一度
下記採用サイトをご覧ください。
[Happy Elements株式会社 採用特設サイト](https://recruit.happyelements.co.jp/)