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オンライン学習

一人でゲーム開発が不安な方はオンラインスクールで学習すると効率が良いと思います。
以下に当てはまる人は検討してみると良いかもしれません。

「ゲーム作りけど何から初めればいい?」
「入門書をの次に何をしたらいいの?」
「疑問や問題を一人で解決出来ない。。」
「ゲームを完成させる自信がない。。」
「気軽に質問できる環境が欲しい。。」

自分で学習することに限界を感じたら
オンライン学習しましょう!

Udemy

Udemy
特徴:教材動画買い切り型
レッスン方法:動画教材/Q&Aで質問
習得スキル:教材動画によって異なる
コース概要: ピンポイントで作りたいゲームジャンルの動画を見つけることができるかもしれません。 また頻繁にセールを開催していますのでゲーム開発講座が1500円~で購入することも可能です。
ゲームジャンル別おすすめ講座はこちら Udemy 詳細

テックアカデミー

テックアカデミー
特徴:現役エンジニア伴走型レッスン
レッスン方法:チャット(週2回)/テキストチャット/課題レビュー
習得スキル:オリジナルゲームアプリの作成
コース概要: 途中で挫折しないためにメンター(相談者)が週2回、マンツーマンであなたの質問・相談に答えてくれるので、ゲーム開発・プログラミング未経験の人でも安心してゲーム開発に取り組めます。転職したい人向けのサポートもあります。無料体験もあります。
テックアカデミー 詳細

テックスタジアム

テックスタジアム
特徴:ゲーム開発の為のオンラインスクール
レッスン方法:動画教材,Slackでの質問(24時間)
習得スキル: Unity,UnrealEngine、CG、企画、サーバー、AI、XR等
コース概要: ゲーム業界で必須な技術の習得が可能です。Slack上で待機している先生への24時間、何度でも質問できます。またIT・ゲーム業界への就職サポートが無料で受けられます。
ゲーム開発に特化したオンラインスクールですので、Unityはもとより、他のゲームエンジンやゲーム業界に興味がある方にはオススメです。
テックスタジアム 詳細

デジハリONLINE

デジハリONLINE
特徴:動画カリキュラム型レッスン
レッスン方法:動画講座/Slack/予約制Zoom相談
習得スキル:Unity基礎,実践/ハイクオリティ3Dゲーム
コース概要: デジタルハリウッド大学・大学院などを通じたデジタルコンテンツ業界とのつながりを活かし、最新かつ実践的なカリキュラムを提供しています。【基礎編】【実践編】とカリキュラムが分かれていて、それぞれに課題があり、ご自身の理解度を把握できます。最終的にはハイクオリティの3Dゲームが作れるようになります。
デジハリONLINE 詳細

関連記事

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

ノンフィールドRPG

基礎からリリースまで!

オリジナルRPGを作ってストアに公開しよう!