tanaka's Programming Memo

プログラミングについてのメモ。

CameraPlayのChromaticalの効果を出し続ける

CameraPlayは画面を揺らしたり、波紋を広げたりと、印象的な演出をするのにとても助かるアセットです。PostProcessingと組み合わせると素晴らしいです。

f:id:am1tanaka:20190711202054p:plain
CameraPlay - Chromatical

assetstore.unity.com (面倒なのでアフィリエイトは設定してません^^;)

使える演出の数々はUnity AssetStoreまとめさんやコガネブログさんの記事をご覧ください。

www.asset-sale.net

baba-s.hatenablog.com

1週間ゲームジャムで投稿した跳ね玉で利用したところ演出を評価してくださる方が増えまして、YOKETORU改2019でも利用して同様なお声を頂戴しました。効果を実感しています。

そんなCameraPlayですが、思った通りの設定がなかったりします。例えば古いモニターのようなかっこいい画面にできるChromaticalの使い方は以下の2通りです。

// time秒間で、演出して消える
CameraPlay.Chromatical(float time);

// 3秒間で、演出して消える
CameraPlay.Chromatical();

公式リファレンス

演出する秒数を変えられはしますが、シーン中ずっと効果を持続させるための設定がありません。今回はエンディングで利用したのですが、最初から最後までずっとこれになって欲しいのです。ということで改造したのでやりかたをご紹介します。

目次

準備

実行環境は以下の通りです。

  • Windows10
  • Unity2019.1.5
  • Visual Studio 2019 Community Edition
  • CameraPlay 1.3.2

空の3Dプロジェクトを作成して、Camera Playをインポートしました。Camera Play > Example > ExampleSceneシーンにサンプルシーンがあるので、それをもとに動作環境を構築しました。

  • Camear_GUIを無効にして、新しい空のゲームオブジェクトを作成して、ChromaticalTestというスクリプトを作成してアタッチしました。以下のような感じになります

f:id:am1tanaka:20190711133710p:plain
動作環境の作成

まずは現状のまま動作させてみます。

  • 作成したChromaticalTestスクリプトをダブルクリックしてエディターで開きます
  • Start()メソッドを以下のようにします
    void Start()
    {
        CameraPlay.Chromatical();        
    }

Playすると、3秒間で効果が表れて消えるのが確認できます。

f:id:am1tanaka:20190711202702g:plain
Chromaticalデフォルト動作

使い方はめちゃくちゃ簡単です。

効果を維持するための機能を追加する

CameraPlay_ChromaticalクラスのプロパティーTimer0.5にすれば、常時効果が常に続くようになります。解説は後述しています。もともとはprivateなので、これをpublicにして公開します。

  • ProjectウィンドウからCamera Play > Scriptsフォルダーを開いて、CameraPlay_Chromaticalをダブルクリックして、エディターで開きます
  • 20行目付近のTimerの宣言を、以下のようにpublicに変更します
// 20:
    [HideInInspector] public float Timer = 1f;

あとは利用する側で、Chromaticalを発動させたい間、上記のTimer0.5f-Time.deltaTimeを代入し続ければOKです。

  • 作成したChromaticalTestスクリプトをエディターで開きます
  • 以下のようにします
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChromaticalTest : MonoBehaviour
{
    CameraPlay_Chromatical CP = null;

    void Update()
    {
        if (CP == null)
        {
            CameraPlay.Chromatical();
            CP = CameraPlay.CurrentCamera.GetComponent<CameraPlay_Chromatical>();
        }
        if (CP != null)
        {
            CP.Timer = 0.5f - Time.deltaTime;
        }
    }
}

以上で完了です。Playすると、常にChromaticalがかかり続けます。

f:id:am1tanaka:20190711203020g:plain
ずっとChromaticalが持続

参考 CameraPlay_Chromaticalクラスを読む

参考までに、改造に至った手順を書いておきます。

まずは、どのようなコードで動いているのか覗いてみます。

  • Visual Studioで開いているChromaticalTestスクリプトに追加したコードのChromatical()の部分を右クリックして、定義へ移動を選びます
  • CameraPlayソースコードが開いて、Chromatical()メソッドの中身が確認できます。やっているのは以下の処理です
    • CurrentCameraが無効な時、現在のメインカメラを設定
    • カメラにCameraPlay_Chromaticalコンポーネントをアタッチ
    • アタッチしたCameraPlay_ChromaticalインスタンスDurationプロパティに、演出する秒数(デフォルトなら3)を代入

以上です。あとは、CameraPlay_Chromaticalクラス側が演出をしているということになるので、クラスの中身を見てみます。

  • どれでもよいので、ソースコード上のCameraPlay_Chromaticalの部分を右クリックして、定義へ移動を選びます
  • CameraPlay_Chromaticalクラスのファイルが開くので目を通します
  • OnRenderImage()メソッド内で演出の管理をしているのが確認できます

ざっくりと、以下のような感じです。

  1. シェーダーが有効か(nullじゃない)を確認
  2. TimeXは1から始めて、経過秒を足して、100を超えたら0に戻しています。シェーダーに渡しているようですが、他のパラメーターに関与してないので、ひとまず無視
  3. Timerは、経過時間です。開始直後が0Duration秒経過すると1になるようになっています
  4. _Fadeは、Timerをそのまま代入しているだけです
  5. _Fade0から1に変化する間に、fresultにアニメーションカーブを利用して、滑らかに0から1、そしてまた1から0と変化する値を代入しています
  6. fresultの値を、フェードのパラメーターとしてシェーダーに渡しています

以上から、常にfresult1になるようにすればよいことが分かります。

方法としては、常時Chromaticalとなる別のクラスを新設することが考えられますが、面倒なので単にCameraPlay_ChromaticalTimerを公開して、そこに値を代入する方法を採りました。

まとめ

Chromaticalをずっと適用できるようになりました。CameraPlayは綺麗に作られているのでソースコードを追いやすいと思います。表現の幅を拡張する一助になれば幸いです!

参考URL