原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】カメラワークによる演出を考える

ふと思い出す

12月に入ったのに気温が高くて全然冬になった気分にはなりませんが、確か昔、このぐらいの時期にひょんなことから足を骨折したことがあって、病院でギブスを巻き、なれない松葉杖をなんとか使いながら自宅に戻る途中で上司に本日は休みを取る旨の電話をしたら、「はぁ?おまえなぁ、有給ってのは病気したとか大怪我したとか、そういう時に使うものだぞ!」ってな感じで延々と説教された出来事を、バカリズムに似た芥川賞作家センセの「いい加減、国に与えてもらった休日に、みんなで一斉に休むとか止めればいいのに」といった高等遊民的なTweetを目にして思い出した今日この頃、私もいつの日か「ゴールデンウィーク?ww、みんな好きなときに好きなだけ休めばいいのにー(鼻ほじー)」みたいなことを言える立場になってみたいものです。

 

減衰・FoV・手振れ

そんな感じで私もナチュラルに上から目線で物を言えるような地位を確立すべくゲーム製作を頑張っている訳ですけれども、アレやコレや試行錯誤していく中で、つい最近では@yoship1639氏の書かれた記事が非常に有用で参考になりました。

 

qiita.com

ゲーム中のカメラワークについての手法に関する記事なんですが、記事の中で紹介されている「Lerp減衰・FoV変動・PerlinNoise手ブレ」を取り入れると、かなりダイナミックが表現が可能となります。

 

それぞれの手法については上記の記事で詳しく書かれているのですが、掻い摘んで説明すると

 

  • Lerp減衰:カメラとカメラの被写体の動きをピッタリ同時にするのではなく、カメラ側が少し遅れて被写体を追随するような動きをさせる手法。これにより被写体の動きが俊敏かつ大きく見える

 

  • FoV変動:カメラの画角(FieldOfView)を変化させて画面をダイナミックに変化させる手法。カメラのProjection(投影方法)がPerspective(透視投影)の場合は特に効果が大きい

 

  • PerlinNoise手ブレ:文字通り「手ブレ」を表現する。カメラを揺らすことで被写体が激しく動いているように見える。アクションゲームとかRPGなどではダメージを受けた時の表現にも使われる。

 

となっています。

 

FoV変動を取りれよう

一般的なレースゲームではマシンにブースとが掛かったり急加速したりするときに、一瞬大きな引きの画になったりしますが、それはカメラの画角(FieldOfView以下、FoV)をあげている為です。

 

FoVを上げるとはカメラに写る範囲を広げる、という意味で、一般的に大きく引いた画を撮るときにこのFoV値を上げて画面に表示される範囲を広く取ります。

 

もちろん、カメラ自体を奥行き方向に移動させて画角を広く取るという手法もありますが、カメラの投影方法がPerspective(透視投影)の場合、このFoV値が大きくなると画面の端に行くほど歪みが大きな画像になり、被写体は引き伸ばされて映し出されます。

逆に中央に行くほど歪みは小さいものになるので、結果、奥行きが強調された画面になります。

 

通常時の画面

f:id:Karvan:20181204223558p:plain

 

カメラを奥行き方向に移動させて画角を広く取った場合(FoV値は変えない)

f:id:Karvan:20181204223630p:plain

 

FoV値を大きくして画角を広く取った場合(カメラの位置は移動しない)

f:id:Karvan:20181204223710p:plain

 

どちらも引いた画になりますが印象はずいぶん違ってきます。

 

実装してみた

FoV変動の実装は簡単でCamera.fieldOfViewの値をスクリプトで徐々に変えるだけです。今回はLerpを使って変化させてみます。

 

Camera.fieldOfView = Mathf.Lerp(Camera.fieldOfView, fov, Time.deltaTime * 2.0f);

 

第二引数のfovが最終的に変化させたいFoVの値です。
Lerpの第3引数にフレーム間の差分時間であるTime.deltaTimeを使い、目標値へ滑らかに変化するようにしています

 

上記の処理後に同じようにLerpを使って徐々に変化させながら元のFoV値へ戻します。
これで、一瞬大きく引いた画になったかと思うと、一気に元の画に戻る、という演出が行えます。

 

public class CameraController : MonoBehaviour 
{
    public float FoVTarget = 145;
    public float DefaultFoV;
    
    void Start () {
        m_Camera = GetComponentInChildren<Camera>();
        DefaultFoV = m_Camera.fieldOfView;
    }
    
    void LateUpdate()
    {
        ZoomControl();
    }

    /// <summary>
    /// ズーム処理
    /// </summary>
    void ZoomControl()
    {
        if (inZoom)
        {
            m_Camera.fieldOfView = Mathf.Lerp(m_Camera.fieldOfView, FoVTarget, Time.deltaTime * 2);
        }
        else
        {
            m_Camera.fieldOfView = Mathf.Lerp(m_Camera.fieldOfView, DefaultFoV, Time.deltaTime * 4);
        }
    }
    
    /// <summary>
    /// FoC変更
    /// </summary>
    void OnFoVChange()
    {
        StartCoroutine(DoZoomEffect(1.2f));
    }


    /// <summary>
    /// ズームエフェクト
    /// </summary>
    /// <returns></returns>
    IEnumerator DoZoomEffect(float duration)
    {
        inZoom = true;
        yield return new WaitForSeconds(duration);
        inZoom = false;
    }
}

  

で、ゲーム中の実際の動作はこんな感じになります。

 

 f:id:Karvan:20181204224653g:plain

 

実はFoVを元に戻すときに「PerlinNoise手ブレ」も動作しているのですが、サンプリングの関係なのか手ブレの効果については上のGIFでは良く分かりませんね。カメラが急にワープしたかのように見えるし。

 

「PerlinNoise手ブレ」については次回のブログで記事にしようと思います。

 

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。