クリアメモリ

プログラミングやモーショングラフィックス、便利なアプリケーションなど雑多に記録するブログ

【Unity】フェードイン・フェードアウトを実装してゲームっぽさアップ!動画あり

f:id:clrmemory:20170812025821j:plain

Unityでゲームを作っていると、タイトル画面からステージ選択画面などへシーンを切り替えることがあると思います。

 

そんな時にパッと切り替わっても良いのですが、少し味気ないですよね。そのような時はフェードイン・フェードアウトを実装してみましょう。

 

 

はじめに

 

まずフェードインとフェードアウトの説明をします。既に知っている方は飛ばしてください。

 

フェードイン・フェードアウトとはシーンの切り替え時や再読み込み時に、ゆっくりと画面を暗くしたり逆にゆっくり明るくしたりという処理です。

音楽の編集などでも再生終了に近づくと少しづつ音量が小さくなりますよね。それと同じと考えていただければわかりやすいと思います。

 

詳しくは動画を撮影しましたのでこちらから確認してください。

 

 

今回作成する処理では必要になるものは「黒い画像」「コード」だけです。コードもわかってしまえば簡単なものなので、ぜひ試してみてください。

 

ではまず黒い画像の配置から説明します。

 

オブジェクトを配置しよう

 

まずはフェードに使うオブジェクトを配置しなければなりません。

黒い画像(無ければ背景画像の色を黒に変更したもの)を用意します。そのオブジェクトをカメラが映る範囲と同じサイズにしてください。

 

念のためカメラの範囲より少し大きくしておくと良いかもしれません。

 

スクリーンショット 2016-02-26 8.44.46

 

Unityでの操作はこれだけで一旦完了です。簡単ですね。続いて、コードを作成していきましょう。

 

コードを作成

 

Fadeなど適当な名前のスクリプトを新規作成してください。新規作成したスクリプトに以下のコードを追加します。

 

using UnityEngine;
using System.Collections;

public class Fade : MonoBehaviour {

    GameObject fadeObj;

    float startTime;

    public int fadeTime;
    Color alpha;
    string fadeStart;

    // Use this for initialization
    void Start () {

        fadeObj = GameObject.Find ("Fade");
        startTime = Time.time;
        fadeStart = "FadeIn";

    }

    // Update is called once per frame
    void Update () {

        switch (fadeStart) {
        case "FadeIn":
            alpha.a = 1.0f - (Time.time - startTime) / fadeTime;
            fadeObj.GetComponent ().color = new Color (0, 0, 0, alpha.a);
            break;
        case "FadeOut":
            alpha.a = (Time.time - startTime) / fadeTime;
            fadeObj.GetComponent ().color = new Color (0, 0, 0, alpha.a);
            break;
        }

        if (Input.GetButtonDown ("Jump")) {
            fadeStart = "FadeOut";
            startTime = Time.time;
            Invoke ("Load", 1.5f);
        }
    }
    public void Load(){
        Application.LoadLevel (Application.loadedLevelName);
    }
}

 

fadeTimeにはフェードイン・フェードアウトが完了するまでにかかる時間を設定してください。

 

また、フェードアウトを実行している間に次のシーンが読み込まれてしまっては意味がないので、今まで呼び出していた次シーンはLoad( ) に書くようにしてください。

このコードがフェードイン・フェードアウトさせるものになっています。

 

フェードインやフェードアウトは最近のゲームでは必ずと言って良いほど実装されています。そうすることがゲームっぽさをより引き出すということに繋がるので、ぜひ実装してみてください。

フェードイン・フェードアウトを実装することで、シーン切り替えのタイミングがわかりやすくもなりますしね。

 

では詳しい解説を見ていきましょう。

 

 

コードの説明

 

「fadeObj」-> 黒い画像

 

「startTime」-> 現在の時間

 

「fadeTime」-> フェードイン・フェードアウトが完了するまでの時間

 

「alpha」-> 画像の色

 

「fadeStart」-> フェードインなのかフェードアウトなのかの判定

 

 

になっています。自分でわかりやすい名前に変更してみてください。

 

Start(){ }

 

fadeObjを取得。

 

 

startTime -> シーンが開始されてから経過した時間を入れる。

fadeStart -> シーンの初回起動時にフェードインを実行。

 

Update(){ }

 

 

Update内がより重要な項目なので、細かく解説していきます。

 

switch(fadeStart){ }

 

 

-> fadeStartが"FadeIn”だったらフェードインを実行し、

“FadeOut"だったらフェードアウトを実行する。

 

 

case "FadeOut":

 

 

-> 画像のalpha値を徐々に0に近づける。※この計算については後述します。

 

fadeObj.GetComponent<SpriteRenderer>().color = new Color(0,0,0,alpha.a);

 

-> 画像のalpha値を設定。alpha以外の色は0,0,0なら黒、1,1,1なら白です。

 

case"FadeIn"については同じような処理なので、割愛。計算については同じように後述します。

 

 

また、Input.GetButtonDown(“Jump”)はシーンの再読み込みに使っているので、実際にはGameOverなどのタイミングに変更してください。

 

fadeStart = "FadeOut";

 

->フェードアウトを実行。

 

startTime = Time.time;

 

->時間を初期化。

 

Invoke("Load", ○○)

 

-> ○秒後にLoadを呼び出す。

 

public void Load( ) { }

 

シーンを再読み込みする。

 

計算式の解説

 

先ほどのコードの中に計算式がありました。この計算は少しややこしい処理になっているので、重点的に説明します。

 

 

まず計算式を確認してください。

 

フェードインの場合

 

alpha.a = 1.0f - (Time.time - startTime) / fadeTime;

 

これはフェードインで使った計算式なので「Time.time」=「startTime」になっています。(Start内でstartTime = Time.timeとなっているため)

 

つまり

 

alpha.a = 1.0f - 経過時間 / フェードインが完了する時間

 

になりますよね。

 

仮にfadeTimeが1秒だったとするとフェードが完了した時は「1.0f - 1秒 / 1秒」になります。1/1は1なので、1-1は0になりalpha.aも0になります。

  

スクリプト上のalpha値は0〜1の間で指定されるので、0はalpha値0、1はalpha値255ということになります。

 

フェードインはTime.timeとstartTimeの値が同じなので少しわかりやすいと思いますが、フェードアウトではTime.time と startTimeの値が変わります。

 

フェードアウトの場合

 

alpha.a = (Time.time - startTime) / fadeTime;

基本的な動作は同じなのですが、startTimeの値は「シーンを切り替えるタイミング」で変わります。

シーンを切り替えるタイミングでstartTime = Time.timeにすることを忘れないようにしてください。

  

仮にシーンを起動してから10秒経ったとします。

そのタイミングで、startTime = Time.timeをすることでstartTime = 10になりますね。

時間は経過していくのでTime.timeは11秒12秒と増えていきますが、startTimeは10のままなので11秒 と 10秒の差は1秒となります。

 

1秒 / 1秒は1なのでalpha.a = 1となり、フェードアウトが完了します。フェードインと違って1.0fが無くなったのは最終的な値が1になるようにするためですね。

  

もしフェード完了時間を2秒にしたい時はfadeTimeの値を2に変更することで、(12秒 - 10秒) / 2 = 1になるという計算です。

最終的に1になるか0になるか判断するだけなので、計算がわかってしまえば簡単な処理ですね。

 

ここまで理解できたら、実際に動作を確認しましょう。

 

まとめ

 

今回の方法を使えばフェードイン・フェードアウトを簡単に実装することができます。

ただ動くゲームを作るだけでなく、シーンの切り替えにフェードアウトさせたりすることでより一層ゲームっぽさが出せるかと思います。

 

まだフェードを実装していない人はぜひ使ってみてください。

 

www.clrmemory.com

 

ではまた。

 

新着記事