テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】Monobehaviourを継承したクラスをAddComponentボタン経由で追加出来なくする方法

「なんの役に立つのか分からない」裏技です。

 

Monobehaviourを継承したクラスは割と問答無用でAddComponentで追加することが出来るようになります。
サンプルでコレを回避するコードを見かけたのでメモします。

f:id:tsubaki_t1:20180820003143j:plain

やり方は単純で、[AddComponentMenu("")]をクラスの頭に足すだけです。これでAddComponentボタンから追加出来なくなります。

f:id:tsubaki_t1:20180820003219j:plain

ただしドラッグ&ドロップでの登録やスクリプトでの登録は可能なので、あくまでAddComponentボタンやComponentメニューから登録できなくなるというだけです。

【Unity】Cinemachineのカメラ位置や向きを、自分のスクリプトで制御する

Cinemachineを紹介すると「自分のシステムと相性が悪い」や「使い方が難しい」といった意見をよく聞きます。
とは言えCinemachineが提供する「演出用カメラワークへのシームレスな移動」や「めり込み抑制や振動といったエフェクト」、「手ブレ」は使いたい所です。

なので今回は、可能な限り自分でカメラの回転や座標を制御しつつCinemachineの追加機能を使う方法について考えてみます。

 

 

Virtual Cameraを自分で制御したい

Cinemachineは概ね3つの機能で構成されています。後付で様々な機能が追加されていますが、根底はこの3つです。

  • Virtual Cameraの位置を制御するFollowとBody
  • Virtual Cameraの回転を制御するLookAtとAim
  • Virtual Camera同士をブレンドするCinemachine Brainコンポーネント

実際は微妙に違うと言えるかもしれませんが、大体このニュアンスでOKです。

f:id:tsubaki_t1:20180819225322j:plain

要するに、BodyとAimを無効化(Do Nothing)してしまえば、Virtual Cameraの座標・向きの変化は停止します。自分自身でVirtual Cameraを動かしても問題なくなります。

後はVirtual CameraをセットしたGameObjectのTransformを自分の好きなように動かしてやれば良いという訳です。

Virtual Cameraの動きは自分の定義したスクリプトで動かしても、

f:id:tsubaki_t1:20180819225922j:plain

またDoNothing担っている場合でも、Virtual Cameraに設定されているExtensionsは動作します。なお、幾つかのExtensionsはLookAtを要求します。

f:id:tsubaki_t1:20180819230328g:plain

 

Virtual Cameraを特定のオブジェクトと同期させる

Virtual Cameraを特定のオブジェクトと同期させるアプローチについてです。
多分コレは任意のオブジェクトを元に移動させるとか、そんな用途の機能と思われます。要するにPOVです。
もちろんUnityでは「子オブジェクトにする」というアイディアもありますが、階層が深いのは余り良くないです。

www.youtube.com

まずVirtual Cameraを別のオブジェクトと完全に同期させてみます。
特定のオブジェクトをフォローさせたい場合、Followに追跡したいGameObjectをセットしBodyはHard Lock To Target、AimはSame As Follow Targetです。

SameAsFollowTargetのみLookAtではなくFollowを要求しています。多分PostProcessingStack拡張のDOFがAIM依存なのでソレを気にしてるんじゃないかなという気もしますが、どうなんでしょう。

f:id:tsubaki_t1:20180819232611j:plain

 ところでPOV系の動画を見ると自分一発で酔う事があるんですが、自分だけですかね?デッドプール2の逆さまになって銃撃するシーンとか超しんどかった

 

座標は自分で設定したいが向きだけはCinemachineの機能を使いたい

座標は自分の指定した動きをしてもらいたいが、向きだけはCinemachineのComposerを使いたいという場合です。
例えばジブショットのような連続した動きをCinemachineでやらせようと思ったら、地味に面倒くさいですが、向きと座標込でアニメーション作るのも正直面倒くさいので移動はアニメーションやパス、向きはCinemachineにやらせるという話です。

www.youtube.com

考え方は単純で、FollowにAnimationやSplineで動かすオブジェクトを指定し、BodyにHardLockToTargetを指定。LookAtにフォーカスしたい対象を指定してComposerを使うというだけです。

f:id:tsubaki_t1:20180819235824j:plain

コレの良いところは移動中にフォーカスしたい対象を切り替えられる点です。例えば下のGif動画では、移動の途中にフォーカス対象をゆっこからユニティちゃんへ切り替えています。
「移動先を見る」だけならそれ程難しくはないのですが、見せたいものがある場合には結構良いかなという感触です。

f:id:tsubaki_t1:20180820000120g:plain

 

ちゃんとCinemachineの機能に則って動きを作りたい

CinemachineComponentBaseを継承したクラスを作ると、自分のオリジナルCinemachine動作が作れます。

Class CinemachineComponentBase | Package Manager UI website

f:id:tsubaki_t1:20180820002536j:plain

【Unity】Cinemachineで作るカメラワーク(カット割り:カメラを切り替える)

名前が正しいのか分からないのですが、カット割りでズームするアプローチの方法についてです。

 

 

カット割り

キャラクターの動きを作るとき、カットを割るというのが結構メリハリのある動きを表現する上で良いみたいです。
確かに、ズームやドリーといった動きでフォーカスを当てるのとは別の、なんとも言えない味があります。f:id:tsubaki_t1:20180818224617g:plain
また他の演出とも混ぜやすいという点もあるのかもしれません。例えば音楽に合わせてカットを切り替えたり、カットの切り替え時に光の情報を書き換えるといったアイディアです。
自分の最も好きなカットに「ダブルオークアンタの登場」というのがあるのですがそんなノリです。

 

三段ズーム(カット割り)

カット割りですが、TimelineでCinemachineを使えるなら割と簡単に実現できます。

使わない場合、Cameraを大量に用意しActiveトラックで切り替えるという、非常に面倒くさいアプローチが必要になってきます。The Phantom Knowladgeではこのアプローチでカメラを切り替えています。

 

手順はそれほど難しくありません。複数のVirtual Cameraをブレンドせず切り替えれば良いのです。
まずVirtual Cameraを複数用意します。トップのGifでは4つのVirtual Cameraを使用して表現しています。Virtual Cameraの座標は概ね同じです。但しFOVが異なります

f:id:tsubaki_t1:20180818225909g:plain

このFOVが異なるVirtual Cameraをブレンドすればズームになりますが、キッチリ分けたのでカット割りになったというだけの話です。

FOVのサイズはFollowZoomを使用すると「写って欲しいサイズ」から指定できます。ただ有効にし続けるとズームしてしまうので、欲しいサイズ設定後は外してしまうのが良いかもしれません。

tsubakit1.hateblo.jp

 

会話のカット割り

二人のキャラクターが会話をする場合、カット割りのほうが良いケースがあります。というのも、パン(カメラの首振り)でフォーカスするキャラクターを何度も切り替えると、カメラ酔いを引き起こすとされているからです。
数度程度なら位置関係を表すのに良いと思いますが、何度も繰り返されると割としんどくなります。
下のGifは写してたら酔ったので小さくしました。クリックすると大きくなるので、是非大画面でお楽しみ下さい。
f:id:tsubaki_t1:20180818233757g:plain

さて、会話のカット割りでも基本的に手順は同じで、カットの数だけVirtual Cameraを用意し、切り替えるだけです。但し、イマジナリーラインには注意する必要がありそうです。

覚えておきたい動画撮影の原則「イマジナリーライン」とは? | MOBERCIAL

イマジナリーラインとは、対話者2人の間を結ぶ仮想の線であり、その線を基軸にどちらか片方に半円(180度)を描き、そのエリア内にのみカメラをポジショニングし撮影するという作法です。

イマジナリーラインを超えてカットを動かすと、カメラの位置を直感的に把握できなくなり、見ていて面倒くさい動画になります。

f:id:tsubaki_t1:20180818234323j:plain

 

例えばイマジナリーラインを無視して作った絵です。
最初に構図を出しているので位置は分かるのですが、お互いの位置関係はパット見てわかりにくくなります。

f:id:tsubaki_t1:20180818235242j:plain

f:id:tsubaki_t1:20180818235545g:plain

イマジナリーラインを守った絵です。
向き合ってる感はこちらの方があります。

f:id:tsubaki_t1:20180819000037j:plain

f:id:tsubaki_t1:20180818235350g:plain

 

感想

カメラ左右に振り回しすぎて酔った…
特に会話系のコマを作る場合は、カット割りを積極的に使うのが良いかもしれません。演者が動くならソレに合わせてカメラを動かしても良いのですが、視点を回す為にパン使いまくると死ぬ(実感

 

参考:3Dゲームを面白くする技術

【Unity】Cinemachineで作るカメラワーク("対象を中心に回り込む"を表現する3つのアプローチ)

Cinemachineでカメラワーク、対象を回り込むように移動させる方法についてです。

 

 

対象を中心に回り込むように

仮面ライダーの初回変身シーン後やアイドルのダンスシーン、トリガー製のアニメ等で、何かを中心にカメラを回すという表現をよく見る気がします。
f:id:tsubaki_t1:20180817191833g:plain

この表現ですが、カットやカメラワーク同士を繋げて動かすCinemachineでは実は少し面倒な所があります。
この表現を行う方法は幾つかあります。

 

2点間のVirtual Cameraを対象を中心に円を描くように動かす

2つのVirtual Cameraを使用して表現するケースです。
最初と最後のカットに欲しい絵がある場合や、回り込む際に絵を崩したくない(極端にズームするような場所をなくしたい)場合には、このアプローチが良さそうです。
またVirtual Cameraのブレンドが出来るので、回り込みながらズームする的なことも簡単に実現出来ます。
その他、主人公をカメラに写したままパン(カメラ飲む気を変える)する等にも使えそうです。

 

手順を見ていきます。
まず最初に2つのVirtual Cameraを配置します。
この2つをTimeline等でブレンドしていきます。このままだと直線的にカメラをブレンドするので、途中で対象に近づきすぎてしまいます。

f:id:tsubaki_t1:20180817193110j:plain

f:id:tsubaki_t1:20180817193158g:plain

Virtual Cameraの設定です。

2つのVirtual CameraのLook Atに中心にする対処を指定します。今回の場合はユニティちゃんを指定しています。次にTransitionsのBlendHitをCylindrical Positionを指定します。

これで、Y軸を回す感じで対象を中心にカメラが移動します。

f:id:tsubaki_t1:20180817193756j:plain

f:id:tsubaki_t1:20180817193400g:plain

このアプローチの問題は、180度以上の角度を回せないという点です。最短距離で回転してしまうので、欲しい角度が180度以上の場合、上手く回ってくれません。
カメラを回すというよりは回り込ませるための機能です。カメラを回したい場合、180度ずつカメラをブレンドする的なアプローチが必要になります。

 

SphericalPositionとCylindricalPositionの違い

SphericalPositionとの違いは、Y軸だけでなくXZ軸も使用して回す点です。例えば上から円を描いて俯瞰するような場合、Cylindrical PositionだとXZ軸のみで距離を判断するので良い感じに作れません。

f:id:tsubaki_t1:20180817194748g:plain

 

対象の周囲を回るオブジェクトを用意して、ソレに載せる

絵を崩さず回り込むのではなく、とにかく対象の周囲を回りたいという場合には、このアプローチが良いです。グルングルンしたい場合。

ある意味単純なアプローチで、対象の周囲を回るオブジェクトを用意し、ソコにVirtual Cameraを載せるというアプローチもあります。
最終的な欲しい絵にするのは面倒なので、クルクル回した後に別のVirtual Cameraに繋げるとかするのが良いかなという印象です。
なお、回り込む速度やブレンド速度が分離する点に注意が必要です。

f:id:tsubaki_t1:20180817203247g:plain

 

まず親子構造を作ります。親を回せば子が対象の周辺を回る感じに作ればOKです。

f:id:tsubaki_t1:20180817201755j:plain

子(Orbit)の位置とVirtual Cameraの位置を同期します。
Followに動かす対象(Orbit)を設定し、BodyにHardLockToTargetを指定します。これでVirtual Cameraオブジェクトの階層構造を作らなくとも、対象を追跡してくれるようになります。

f:id:tsubaki_t1:20180817202107j:plain

後はオブジェクトを動かします。面倒くさいのでTimelineのアニメーションで親オブジェクトを回すアニメーションを作ってしまいます。場合によってはTween系も良いかもしれませんが、Timelineで確認出来ないと最終的な絵が欲しい物かどうか確認するのが面倒です。

f:id:tsubaki_t1:20180817202422j:plain

このアプローチでは最終的なショットに向けて移動する訳では無いので、その辺りの調整に結構時間が取られるかもしれません。

なおCinemachineCollider(当たり判定にめり込まない)と連携したい場合はHardLookToTargetではなくTransposerで相対距離を(0, 0, 0)とかにします。

f:id:tsubaki_t1:20180818105240g:plain

 

対象の周辺を走るカートを使う

次のアイディアは対象を中心としたカートを作る事です。
用意したレールの上を走らせる考えです。所謂ドリーカートです。
完全に円形ではない場合は、このアプローチが良い感じになります。

f:id:tsubaki_t1:20180817195958j:plain

このアプローチは基本的にチュートリアルで紹介されているような作り方です。
Cinemachine > Create Dolly Camera With TrackでVirtual CameraとDollyTrackを作成、パスを作ります。
後はPath Positionをアニメーション等で動かします。自動的に動いてくれるAuto Dolly設定は今回のケースでは使えません。

f:id:tsubaki_t1:20180817204103j:plain

unity3d.com

もし複数のVirtual Cameraをブレンドしたいような場合は、対象の周囲を回るオブジェクトを用意して、ソレに載せるの応用でCreate Dolly Track With CartにVirtual Cameraを接続すると良いです。