Unity初心者でも簡単に画像をフェードイン・アウトさせる方法

ゲームを作っているとキャラクターなどを徐々に消滅させたり、徐々に現れたりさせたい場合があると思います。
今回はシンプルにフェードイン、フェードアウトさせていくやり方を紹介したいと思います。
これを使えばキャラクター以外にもUIをふわっと表示させたり、非表示にしたりすることもできるようになります。

Unityスキルアップ、
始めるなら今

パズル、脱出、RPG...目標のゲームを完成させよう!

人気のUnity講座はこちら

Udemy講座

フェードに必要なものを準備

それでは早速フェードに必要なものを配置していきましょう。
と言っても最初はGameObjectとC#スクリプトだけでOKです。
HierarchyとProjectです。


C#スクリプトはFadeControllerとしました。
一旦これで準備はOKです。

フェードの実装

どのようにしてフェードさせるか

フェードイン、アウトをどのようにして実装するか考えてみましょう。
そもそもフェードアウトとは徐々に色が透明になっていくこと、フェードインはその逆で徐々に色が不透明になっていくことです。
それをコントロールするにはAlpha値というものを利用します。
Alpha値とは透明度を表す値です。
今回はSpriteRendererコンポーネントがアタッチされたゲームオブジェクトを使いますので、そのcolorプロパティのAlpha値を変化させていくことで実装してみます。
インスペクターのColorでは0から255の値で変化させます(「8ビットカラー表現」や「256階調表現」と呼ばれます)が、スクリプト上では0から1の間で変化させます。
この値が小さいほど透明になっていき、大きければ大きいほど色が不透明になりはっきり見えてくるという感じです。
今回はスクリプトで徐々にAlpha値を変化させていきます。

スタート時にフェードアウトさせてみる

ではスクリプトの方を書いていきましょう。
まずは起動と同時にキャラクターをフェードアウトさせます。
FadeControllerクラスに必要な変数を用意します


using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class FadeController : MonoBehaviour
{
    SpriteRenderer sp; 
    Color spriteColor;
    float duration = 1f;

  /* 略 */    

SpriteReneder型のspはフェードの対象となるGameObjectのSpriteRendererを格納しておくための変数です。
Color型のspriteColorは対象のゲームオブジェクトの現在のcolorを保持するために使います。
float型のdurationという値はフェードが完了するまでの時間です。
今回は1秒かけてフェードアウトさせるようにします。

続いてStartメソッドとフェードさせるコルーチンを書いていきましょう。



public class FadeController : MonoBehaviour
{

  /* 略 */    
    void Start()
    {
        sp = GetComponent();
        spriteColor = sp.color;
    StartCoroutine(Fade(0));
    }
    
    IEnumerator Fade(float targetAlpha)
    {
        while (!Mathf.Approximately(spriteColor.a, targetAlpha))
        {
            float changePerFrame = Time.deltaTime / duration;
            spriteColor.a = Mathf.MoveTowards(spriteColor.a, targetAlpha, changePerFrame);
            sp.color = spriteColor;
            yield return null;
        }
    }

このような感じになりました。
簡単に説明していきます。
Startメソッド

・SpriteRendererコンポーネント取得
・現在のcolorを保持
・Fadeコルーチン開始(引数は0)

コルーチンの0の値はalpha値を0にしていくために引数として渡す必要があります。

続いてFadeコルーチンです。ざっくりとした流れは以下の通りです。
Fade

・変化させたいAlpha値を受け取る
・現在の値と目標の値が近くなるまでwhileのループ
・1フレームで変化するAlpha値を計算
・新しいAlpha値を取得
・現在のColorに反映

この部分は少し詳しくふれておきます。
Fadeコルーチンではfloatの値をtargetAlpahを受け取りwhile文でループさせています。
spriteColor.a(キャラクターのAlpha値)と受け取った値(この場合は0)が限りなく近くなるまでループをします。
Mathf.Approximatelyメソッドは引数の2つの値が浮動小数点数としての計算誤差の範囲内で等しいとみなされる場合にtrueを返します。
シンプルに言えば2つの値が超近ければtrueになると覚えておいてください。
この場合は!Mathf.Approximately(spriteColor.a, targetAlpha)となっているので2つの値が異なる場合、条件が一致し、ループを続けます。

そしてループ内の処理です。
初めにTime.deltaTimeをdurationで割っています。
これは経過時間(Time.deltaTime)を実行完了までの時間(duration)で割る事により、変化させていく値を計算しています。
その値をchangePerFrame に格納しています。
changePerFrameは、1フレームで変化するアルファ値になります。これにより、duration秒(今回は1秒)かけてアルファ値が目標値(この場合は0)に徐々に近づいていきます。

続いてspriteColor.aをMathf.MoveTowardsメソッドで変化させていきます。
Mathf.MoveTowardsは3つの引数を取ります。
最初の引数は現在の値、ここではspriteColor.aです。
2番目の引数は目標の値で、フェードアウトを実現するためにここでは0を指定しています。
最後の引数は最大変化量で、1フレームあたりどれだけ値を変化させるかを定義します。
ここでは先程のchangePerFrameを使っていています。
この処理でspriteColor.aは毎フレーム、目標値に一定の割合で近づいていきます。
ループ内でこのメソッドを呼び出すことで、spriteColor.aは徐々に0に近づき、最終的には透明になります。
説明が長くなったので、Debug.LogでspriteColor.aの値がどう変化していくのか見てみましょう。

このように最後は0になりました。
ここで変化したspriteColorを対象のゲームオブジェクトのカラーに代入すれば徐々に透明になっていきます。
実際に実行した結果です。

このようにキャラクターはフェードアウトしました。

フェードイン

ここまでできればどうすればフェードインができるかは簡単ですね。
Startメソッド内で呼び出すコルーチンの引数を1にすれば徐々にキャラクターが現れて来ます。
では実際にやってみましょう。
まずUnityエディターでキャラクターを透明にしておきます。

続いてスクリプトを修正しておきましょう。



public class FadeController : MonoBehaviour
{

  /* 略 */    
    void Start()
    {
        sp = GetComponent();
        spriteColor = sp.color;
    StartCoroutine(Fade(1)); //引数を0から1に修正
    }
    
  /* 略 */    

これで実行すれば徐々に女の子のキャラクターが出てくるはずです。

期待した通りフェードインしてくれました。
インスペクターのColorプロパティが徐々に変化しているのも確認できるかと思います。

ボタンクリックでフェードイン、アウトを切り替える

ここで終わっても良いのですが、せっかくなのでボタンをクリックしたらフェードイン、アウトするという仕組みを作ってみます。

イベント発火用ボタン配置

ではフェードイン、アウトのイベント発火となるボタンを設置します。
このようにしておきました。

FadeControllerのネームスペースとプロパティ追加

つづいてFadeControllerを修正していきます。
必要となるネームスペースと、プロパティを追加します。


using System.Collections;
using UnityEngine;
using UnityEngine.UI; //UIを使うので追加
public class FadeController : MonoBehaviour
{
    SpriteRenderer sp;
    float duration = 1f;
    Color spriteColor;
    /*以下を追加*/
    bool isFadingOut,isFading;
    [SerializeField] Button fadeButton;
   
  /* 略 */    

bool型のフィールドが2つ追加されましたので説明しておきます。
isFadingOut:フェードアウトしているかどうか判別する。フェードアウトとフェードインを切り替えるために使う
isFading:フェード中かどうか判別する。ボタンクリックでフェード中は処理をさせないようにする。
これらを使って制御します。

Startメソッドの修正とToggleFaedeメソッド

続いてStartメソッドの修正とクリック時に呼ばれるメソッドを追加します。


public class FadeController : MonoBehaviour
{
    void Start()
    {
        sp = GetComponent();
        spriteColor = sp.color;
        fadeButton.onClick.AddListener(()=> ToggleFade()); //追加 ボタンクリック時に呼ばれるメソッドを登録
    }
    
     /*追加*/
     void ToggleFade()
    {
        if (isFading) return;
        StartCoroutine(Fade(isFadingOut ? 1:0));
        isFadingOut = !isFadingOut;
    }
  /* 略 */ 

こんな感じで良いでしょうか。
ボタンクリック時にToggleFadeメソッドが呼ばれ、isFadingがtrueだったらreturnされます。
次にFadeコルーチンを呼び出しますが、この時にisFadingOut がtrue(フェードアウト中)だったら1を、そうでなければ0を引数として渡しています。
そしてisFadingOutを反転しています。

Fadeコルーチン修正

仕上げにFadeコルーチンを修正していきます。
フェードが実行中にボタンをクリックしても反応させないようにする処理を追加する感じです。
具体的には以下のようにします。


public class FadeController : MonoBehaviour
{
  /* 略 */ 
    IEnumerator Fade(float targetAlpha)
    {
        isFading = true;
        fadeButton.interactable = false;
        while (!Mathf.Approximately(spriteColor.a, targetAlpha))
        {
            float changePerFrame = Time.deltaTime / duration;
            spriteColor.a = Mathf.MoveTowards(spriteColor.a, targetAlpha, changePerFrame);
            sp.color = spriteColor;
            yield return null;
        }
        isFading = false;
        fadeButton.interactable = true;
    }

簡単に説明しますと、whileループに入る前にフェード中フラグをtrueに、fadeButtonをクリック出来ないようにinteractableをfalseにしておきます。
ループが終わったらその逆でフェード中フラグをfalseに、そしてinteractableをtrueにしています。
ここまで出来たらUnityエディタからボタンをアタッチしておきましょう。

では実行してボタンクリックでフェードイン・アウトが切り替わるか見てみましょう。

このようにボタンクリックでフェードインとアウトを切り替えることが出来ました。
DOTweenを使ってフェードイン・アウトの実装も簡単に出来ますが、今回のようなやり方でも実装出来ます。
今回はSpriteRendererを使いましたがUIのImageでも応用できると思います。

またボタンのクリックに関しては別の記事で詳しく触れていますので良ければご覧ください。

以上簡単ではありましたが、フェードイン・アウトの実装でした。
今回の内容はGithubにアップしておきますので、よかったら参考にしてみてください。
GitHub : FadeTest

関連記事

最後までご覧頂いてありがとうございました。

セール中!

Unity講座 対象コースが¥1,500~

期間限定 セール開催中!今が学びのチャンス♪