きっポグ

- kitposition's weblog -

Timelineによる映像メイキング【ゆるふわアドカレ2018】

この記事は Unityゆるふわサマーアドベントカレンダー2018  の最終日(8/31)の記事です。

今回は、現在制作中の動画「きっポジ艦隊(仮)」のメイキングをつらつら書きます。基本我流なのでマトモじゃないやり方もあるかもしれません。

動画の構想だけは結構壮大なのですが、本業の合間に気が向いたら作っている程度なので現状できているのは「艦隊がワープアウトして出現する」シーンだけです。4K動画*1をYouTubeで公開していますのでよければご覧ください(音出ます)。


きっポジ艦隊 made with Unity - PART I -

 今回はこれをサンプルとして、Timelineを用いたワープシーンの作り方を見ていきます。ボリュームの都合上、すべての説明ではなく重要ポイントの紹介といった趣でいきますのでよろしくです。
(Unityのバージョンは2018.2.3f1を使用しています。)

単艦のワープシーンを作成する

ワープは架空の技術で体験した人なんていないので、SF映画では好き勝手な幅広い映像表現がなされます。きっポジ艦隊では宇宙戦艦ヤマト2199を手本に、「空間にあいた穴から戦艦がニョキニョキ出てくる」表現を目指しました(この動画の0:56くらい)。実現するにはオブジェクトの一部をマスクしつつ、マスクの範囲をリアルタイムで変化させる必要があり、Unityの3Dでやろうとすると多分シェーダー一択かなという気がします。

①ワープシェーダーの作成

とはいえ、常日頃プログラミング苦手を公言している僕がシェーダーなど書けるはずもないのですが、Unity2018では新たに「Shader Graph」というノードベースのツールが実装され、コードを書かなくてもシェーダーが作れるようになりました!凄い!

この記事ではShader Graph自体の詳しい説明はしませんが、*2

  • Unity2018以降
  • レンダーパイプラインをLWRPまたはHDRPに設定 *3
  • Package ManagerからShader Graphを導入

で使えますのでぜひ試してみてください。旧バージョンのUnityを使いたい、またはレガシーのレンダーパイプライン(Forward/Deferred)を使いたいという場合は、ShaderForgeAmplify Shader Editorなどの外部アセットを使用するのがよいでしょう。*4

で、作ったシェーダーがこれです。
公式のサンプルを参考に見よう見まねで作ったのでマトモな設計なのかわかりませんがw

図1

f:id:kitposition:20180830145158p:plain

公式のサンプルはこちら↓

github.com

公開プロパティ「WarpThreshold」を調節することで、マスクの範囲を動かすことができます。

図2

f:id:kitposition:20180830151741g:plain

が、どうも座標の取得に利用しているPositionノードは絶対座標を出力するらしく、艦隊の戦艦モデルはそれぞれサイズが違うのでこのままだと汎用的に利用できません。 *5

そこで今回は、簡単なヘルパースクリプトを書いてモデルの全長に応じた相対座標から変換することにしました。このスクリプトのThresholdを-1から1まで動かせば、モデルのサイズに関係なく先端から後端までマスク範囲が動きます。*6

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WarpShaderController : MonoBehaviour {

    [Range(-1, 1)]
    public float Threshold = 1;
    public float Adjust = 0;

    float ZLength;
    Material material;

    // Use this for initialization
    void Start () {
        material = GetComponent<Renderer>().material;
        ZLength = GetComponent<MeshFilter>().mesh.bounds.size.z;
    }
	
    // Update is called once per frame
    void Update () {
        material.SetFloat("_WarpThreshold", Threshold * (ZLength + Adjust) / 2 * -1);
    }
}

なお、この時スクリプトから参照する名前は、Shader Graph上でプロパティ名とは別に設定した参照用の名前を使わなければならないので注意が必要です。

 図3

f:id:kitposition:20180831014119p:plain

 

②Timelineでマスクの範囲を動かす

ではTimelineを見ていきます。後述しますが、今回は個々の戦艦がワープアウトする子Timelineを作成し、それを親Timelineで一括制御します。そのため、まず個々の戦艦自体にTimelineを持たせますが、これら単艦TImelineのTimeline Asset自体は共通のものを使い回すようにします。

図4

f:id:kitposition:20180830230323p:plain

単艦Timeline上で先程のスクリプトのThresholdを制御する方法は簡単で、「Animation Track」でアニメーションさせればOKです。

図5

f:id:kitposition:20180830160253p:plain

ここは意外と知られていない気もするのですが、Timelineに限らず、Unityのアニメーション機能は「オブジェクトの位置を変える」「キャラを動かす」といういわゆる世間一般的な「アニメーション」だけではなくて、「時間経過に応じてクラスのパラメーターの値を変える」ことも可能です。要するに値が可変のものはだいたい動かせる*7のです。これは動画はもちろん、ゲーム中のあらゆる制御に応用できるので超便利ですよ!

後は、アセットストアで購入したいい感じのパーティクルをモデルの前端に配置し、「Control Track」を使ってTimelineの再生中のみ出現するようにすると、下の動画のようになります。このように必要な時だけオブジェクトを表示させるには通常「Activation Track」を使うのですが、パーティクルについては「Control Track」を使った方が、再生ヘッドを動かすとエフェクトも同期して巻き戻り・早送りの状態になるので細かいタイミングの調整に便利です(動画の後半参照)。

図6

f:id:kitposition:20180830165537g:plain

 

③Transform Tween Trackでモデルを前進させる

最後に、マスク範囲が広がるタイミングと同期させてモデルを前に動かすと、いかにも光の穴から戦艦が出てくるように見えるはずです。

が、1つ問題があります。モデルが完全に見えない状態から全て見える状態になるまでの時間は、先ほどのパラメーターのアニメーションで7秒と設定したので決め打ちです。しかし、前述の通り戦艦のモデルはそれぞれサイズが大きく異なっているので、同じ7秒間でちょうど穴から出現させるにはモデルごとに移動距離(速度)を変える必要があります。Timelineを使い回す前提の場合、これは通常のAnimation Trackでは困難です。

図7

f:id:kitposition:20180830171858p:plain

そこで、Asset Storeで配布されているTimelineの機能追加ツール「Default Playables」を導入し、それによって追加される「Transform Tween Track」を利用します。*8

使い方はおなじみテラシュールブログさんが以前記事にされていますのでそちらをご覧ください。今回の実装はほぼこのまんまです。一言でいえば、「スタート地点とゴール地点にマーカーとしてオブジェクトを配置すると、指定の時間でスタートからゴールまで移動する」というものです。

tsubakit1.hateblo.jp

これなら、モデル毎に異なるスタートとゴールのオブジェクトを用意しておけば、参照先さえ変えればどのモデルでも同じTimelineが使い回せます。(この時、親オブジェクトを用意して戦艦とスタートとゴールを全部ぶら下げてしまえば事実上一体で扱えるのでシーンのどこにでも置けます)

図8

f:id:kitposition:20180831051336p:plain

後はサウンドなどを追加して、単艦のTimelineの完成です。

図9

f:id:kitposition:20180830183201g:plain

 以上を応用するとワープインなんかもできます。次の動画は今回使うシーンではありませんが、シェーダーの頂点の座標をパラメーター制御でずらして、モデルの後ろ半分をニューッと伸ばしています。

  

親子Timelineで艦隊を編成する

前章で作成した単艦のTimelineはこれで完結しているので、プレハブにするなりしてシーンに複数配置し、必要に応じてモデルやスタートとゴールの参照を差し替えればいくらでも戦艦を増やせます。
ただし、それだけだと各々の再生タイミングを制御できないので、前述の通り親タイムラインを作り、そこから個々の単艦Timelineを再生するようにします。

使うのは先ほどパーティクルを制御したのと同じ「Control Track」ですが、これまたテラシュールブログさんの記事があるので詳細はこちらをご覧ください(そればっかり)

tsubakit1.hateblo.jp

今回は5種類計15隻の戦艦を配置し、こんな感じで何段階かに分けて出現させるようにしました。

図10 ※倍速で再生してます

f:id:kitposition:20180830185901g:plain

 

カメラワークを設定する

次に、親Timelineに「Cinemacine Track」を設置してカメラを置いていきます。

Cinemachineは機能が多く、素人でもプロ顔負けの様々な表現を行うことができます。
が、これがくせもので、乱用するとアニメーションだらけのパワポのごとく訳の分からないものになります。VR用映像だったりするとVR酔いを誘発しかねません。
個人的にはなるべく派手な機能は使わずに普通のカメラのように扱い、ここぞというポイントでCinemachineらしい機能を入れるのがいいと思います。*9

今回の動画も、大部分はただ静止したカメラを切り替えているだけですが、そういう時の各カメラの位置決めは以下の繰り返しです。

  1. シーンビューで視点を変えて好みの位置を見つける
  2. メニューの「GameObject → Align With View(Ctrl + Shift + f)」でシーンビューの視点とゲームビューのカメラの視点を一致させる

この「Align With View」も知る人ぞ知るという感じで時々Tips的に紹介されますが、基本的に神視点*10をシーンビューでしか動かせないUnityでは、構図を思い通りにしようと思ったらTipsどころかもうこれ以外ないでしょというくらい必須の操作なので、Unityさんにはもっとマニュアルに大きく書いていただきたいですw*11

図11

f:id:kitposition:20180830204853g:plain

では「ここぞというポイント」としてCinemachineの機能を使ったのはどこかというと次の部分です。

図12

f:id:kitposition:20180830202031g:plain

この「目の前を通過する戦艦の横っ腹を追う」構図は宇宙もののSFではとてもよく使われます。巨大感が出て迫力満点!

これはCinemachineの最も基本的な機能の1つである「エイム(カメラの位置は止まったままで、自動的に首を振ってターゲットを追跡する)」だけで実現できます。ついでに、これもCinemachineに用意された「ノイズ」を追加してゴゴゴゴ…とカメラを揺らしました。これは「ヤマト2199」や「リブート映画版スター・トレック」など、比較的最近のものによく使われますね。

Cinemachineのもう1つの基本機能「フォロー(ターゲットを追跡してカメラ自体が動く)」も便利で特にゲームでは非常に有用ですが、カメラの位置を手動で制御できなくなるので最初のうちは難しいです。個人的には、ある程度「エイム」に慣れてから使うのがおススメです。

図13

f:id:kitposition:20180830210702p:plain

それからCinemachineとは関係ないのですが、例えばこんなとこもちょっとしたこだわりです。

図14

f:id:kitposition:20180830210857g:plain

主力の大型艦のワープアウトをアップで撮った後にカメラを切り替え、全体を映して小型間のワープを捉えています。この時、2つ目のカメラに切り替わった時点でも主力艦は完全に停止していないのがわかるでしょうか?

「アニメーションの切り替え」と「カメラの切り替え」はつい同期させてしまいがちなのですが(僕だけかな)、あえてちょっとずらすことで連続感が出てダイナミックになります。そしてこの「ちょっと」のサジ加減がコードのパラメーターでは調節が面倒なところで、クリップをつまんで動かすTimelineが力を発揮する場面だと思います。

 

仕上げ・完成

最後にライティングやポストエフェクト、背景などを設定して完成です*12。真面目に語ると1年くらいかかるので詳細は書きませんが、ポストエフェクトで個人的に注意していることだけ書いておきます。我流と主観が入りまくってるので話半分で聞いておいてください。

①Bloomは効果大、DoFは要注意

Unity標準の「Post Processing Stack」からアセットストアで販売されているエフェクトまで、ほぼ全てに実装されていてかつ効果がわかりやすいエフェクトといえば、「Bloom(光ってるものを輝かせる)」「Depth of Field(DoF、被写界深度)」でしょう。
派手なのでポストエフェクトを使い始めるとついついこれらを使いたくなります。

このうちBloomについては、とりあえず光らせとけば美しさ1割増しくらいにはなるのでお勧めですが、DoFの使いどころは要注意です。

DoFとはピントが合って見える範囲を示す用語ですが、エフェクトとしては要するに一眼レフカメラなどで人気の「背景ボケ」を実現するものです。いわゆるこんな写真ですね。*13

図15

f:id:kitposition:20180830213649j:plain

被写体の存在感を際立たせるのでスナップ写真等では人気のテクニックですが、基本的にこれが活きるのは「被写体が比較的小さく、背景に比べてカメラに近い場合」です。

例えば、都会の交差点に立ってビルを見上げたとして、1階だけピントが合って上の階がボケたりはしません(僕は全部ボケて見えますがそれはただの乱視です)

図16

f:id:kitposition:20180830214424j:plain

人間の目はこういう構造なので、逆に巨大な対象にDoFをかけると脳が誤認識するのか、サイズが小さく見えてしまうようです。

今回の「きっポジ艦隊」の旗艦はオレ設定上宇宙戦艦ヤマトの波動砲くらいなら弾き飛ばして体当たりでヤマトを粉砕できる巨大戦艦ということになっているのですが、うっかりDoFをかけるとこうなります。

 図17

f:id:kitposition:20180830214958p:plain

DoFをかけた方はなんだかおもちゃぽく見えませんか?見えなければそれはそれでいいんですがw
このようにDoFは使うべきでないところで使うと迫力が大きく損なわれるので要注意です。*14

また、ものにもよりますがポストエフェクトの中でもDoFは重いです。廉価版スマホとかでリアルタイムで使ってfpsを出そうと思ったら色々工夫しないと難しいです。

 

②効果絶大な「Color Grading」

公式のPost Processing Stackの中で「なんだかわからんけど適当に使ったら絵がガラッと変わる」という意味でおススメなのは「Color Grading」です。パラメーターが多くて僕もよくわかっていないのですが、とりあえず適当に勘でガチャガチャ設定するだけでも結構変わります。

図18

f:id:kitposition:20180830221016p:plain

うーむ、絶大と言った割には使い方が下手でただ暗くなったようにしか見えんかなw もっと極端に使うと次の動画のような感じです。「ユニティちゃんがゆにはめ波を撃つ」という全く意味不明の動画ですが、後半エネルギーの輝きで画面全体が水色になるところで、同種のエフェクトを使っています(作ったのだいぶ前なので忘れたけど多分)。

 

まとめ

いかがでしたか?「オレ作ってるのゲームだし!」「ムービー入れないし!」というも多い(というか多分みんなそう思っ(ry)と思うんですが、Cinemachineやポストエフェクトはゲームでも非常に役に立ちますし、Timelineもその気になればゲームの進行制御に用いることもできるので、慣れる意味でも映像づくりなんかしてみると結構面白いですよ。

また、TimelineについてはタイミングよくTipsをブログに書いてくれた方がいるので最後にリンクを貼っておきます。もちろんテラシュールさんですが。もうこのリンクだけ貼っとけば良かったんじゃないかと思いつつ今回は以上です!

tsubakit1.hateblo.jp

※「きっポジ艦隊」使用アセットなどのご購入はぜひこちらからお願いします!↓

*1:Asset Storeで配布されている公式の「Unity Recorder」を使うと、なんと4Kの動画も撮れてしまいます。使い方は公式アセットアドカレのこちらの記事が詳しいです。

*2:Shader Graphについてはこのゆるふわアドベントカレンダーの22日目の記事でNitudonさんが紹介しています。

*3:レンダーパイプラインとはシェーディングやライティングの計算など、画面をレンダリングする技術や手順の総称で、従来Unityでは「Forward」「Deferred」の2種類しか選べませんでした。2018より、開発者がC#で記述してパイプラインをカスタマイズできる「Scriptable Render Pipeline」が導入され、同時にあらかじめUnity公式がカスタマイズした設定が2種類用意されました。それがモバイル・VR向けの「LWRP(軽量レンダーパイプライン)」とハイエンド機向けの「HDRP(HDレンダーパイプライン)」で、2018.2以降のShader Graphはこの両方に対応しています。今回のプロジェクトは試しにHDRPを使っていますが、知識がないのでその恩恵はほとんどないですw

*4:ShaderForgeは現在アセットストアから引き上げられてGitHubでの公開となり、無料で入手できますが更新は期待できないです。一方Amplify Shaderはレガシーパイプラインに加えてLWRPやHDRPにも対応したようでやる気満々な感じなので、値段はそこそこしますがこっちの方がおススメかな?

*5:例えばどんなメッシュでも前端を+1、後端を-1みたいに相対値で取得できるノードとかあると便利なんですが。知っている方いましたら教えてください。

*6:なお、このコードではTimelineの美味しいところである「非プレイモード時での動作」はできません。それをするにはもっと色々メンドクサイことしないとだめっぽいですが、今回は結果の着地点がはっきりしていてプレイモードで調整できれば十分なのでパスしました。

*7:たまに動かせないパラメーターもありますが何が違うのかよく知りません。判別の方法としては、やってみて動けば動かせます。

*8:Default Playablesには他にも色々なものが含まれていて、特にTimeline上でカスタムのスクリプトを動かすための独自のPlayableを作成したい場合、手順が煩雑でこのアセットに含まれる専用ウィザードを使わないとちょっとやる気が起きないレベルです。デフォルトっていうんなら初めからつけ(ry

*9:つまりはシーンの大部分は普通のCameraでも用が足りるという理屈になるのですが、そもそもTimelineは基本的にCinemachineを使う作りになっていて、普通のカメラだとできないことが多いです。また、「ここぞというポイント」がどこになるかは作りながら発見することも多いので、カメラ自体は全部Cinemachineにしたうえで、むやみに機能を使わないようにします。

*10:ゲームの視点とは別に作業をしている開発者から見た視点。今命名

*11:厳密にいうとこのAlign With Viewは、「カメラとか関係なくとにかく今選択しているオブジェクトを神の位置に移動させる」操作です。なので、例えばカメラではなくCubeを選択して行えばCubeが神の位置に動きます。ただカメラを動かす以外に役に立つ使い道が思いつきませんw

*12:説明の都合上こういう順番になっていますが、実際はモデルを配置する時点からカメラワークや仕上げを念頭に置く必要があるので、脳内では同時並行的です。

*13:理屈はよく知りませんがスマホのような小型カメラだと難しく、これをやりたくて一眼を買う人も多いようです。ただ最近はスマホでもアプリによる画像処理で、あとから背景をボケさせることが可能になっていますね。

*14:逆に、あえて過剰にDoFをかける(ピントを絞る)ことでおもちゃっぽさを出すことも可能で、「ミニチュアカメラアプリ」と言われるものはそういう処理を写真に施しているわけです。