2022/10/21新しく処理を追記
いよいよ2019始動しました。
去年からUnityの勉強を復活してボチボチ進めてきたのですが、
スクリプトも少し書けるようになってきたので、今年こそは”リリース”を目標に
頑張って行こうと思います。
平成も終わりを迎えるので、
新元号になる前に1本くらいはリリースできるといいのですが…
今年の最初の記事は、フェードイン・アウトの実装です。
今どきフェードイン・アウトの無いゲームは少ないので、
実装は必須かと思います。
フェードイン・アウトと言っても、いろいろな方法があります。
今回は、スクリプトの勉強も兼ねて自作に挑戦してみようと思います。
準備として
Android用の画面を用意
シーン移動用のボタン設置
ここからフェード用のパネルを追加します。

PanelはCanvasサイズに依存するので、自動的にCanvasと同じ大きさになります。
追加したパネルのcollarをクリックするとパレットが開きます。

パレットのA(alpha値)を操作すると透明度が変わるので
これをスクリプトから操作すればフェードができるかと思います。
最初はフェードインさせたいのでA値を255にしておきます。
まずは、フェードインのスクリプトを考えてみます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FadeManager : MonoBehaviour {
public GameObject Panelfade; //フェードパネルの取得
Image fadealpha; //フェードパネルのイメージ取得変数
private float alpha; //パネルのalpha値取得変数
// Use this for initialization
void Start () {
fadealpha = Panelfade.GetComponent<Image>(); //パネルのイメージ取得
alpha = fadealpha.color.a; //パネルのalpha値を取得
}
// Update is called once per frame
void Update () {
alpha -= 0.01f;
fadealpha.color = new Color(0, 0, 0, alpha);
}
}
まずImageを操作するのでusing UnityEngine.UIが必要になります。
A値はスクリプト上から操作する時、Rangeとして入力する必要があります。
Rangeは0~1の間なので注意が必要です。
フレーム毎に0.01づつ数値を下げて行くようにしています。
この減算値を変えればフェードスピードが変わります。
一応フェードインの感触は掴めたのですが、
このままでは、問題点があります。
・alpha値の計算が無限ループしている
・パネルが最前列にあるのでボタン操作ができない
問題点を修正していきます。
まずalpha値の無限ループを止めるためにフラグを用意します。
フラグが立っている間だけフェードするようして、
alpha値が0になったらパネルを消すようにします。
public class FadeManager : MonoBehaviour {
public GameObject Panelfade; //フェードパネルの取得
Image fadealpha; //フェードパネルのイメージ取得変数
private float alpha; //パネルのalpha値取得変数
private bool fadein; //フェードインのフラグ用変数
// Use this for initialization
void Start () {
fadealpha = Panelfade.GetComponent<Image>(); //パネルのイメージ取得
alpha = fadealpha.color.a; //パネルのalpha値を取得
fadein = true; //シーン読み込み時にフェードインさせる
}
// Update is called once per frame
void Update () {
if (fadein == true)
{
FadeIn();
}
}
void FadeIn()
{
alpha -= 0.01f;
fadealpha.color = new Color(0, 0, 0, alpha);
if (alpha <= 0)
{
fadein = false;
Panelfade.SetActive(false);
}
}
}
これでパネルが透明になったら計算のループをストップして
パネルを消す事ができます。
これでフェードインは出来るようになったので、
フェードアウトを考えてみます。
フェードアウト時に必要になるのは、
・Panelfade呼び出し
・画面の移動メソッド
・フェードアウトのフラグ
・フェードアウトのメソッド
これを形にすると
void FadeOut()
{
alpha += 0.01f;
fadealpha.color = new Color(0, 0, 0, alpha);
if (alpha >= 1)
{
fadeout = false;
SceneManager.LoadScene("Fade" + SceneNo);
}
}
public void SceneMove()
{
fadeout = true;
Panelfade.SetActive(true);
}
少し説明すると、Sceneの名前をFade1とFade2としています。
SceneMoveメソッドをボタンに割り当ててフェードアウトのフラグとPanelfadeを呼び出します。
Unity上で移動先Sceneのナンバーを入力できるようにして、
Update関数からフェードアウトのフラグを検知できるようにすれば完成です。
最終的にできたのがこちら
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class FadeManager : MonoBehaviour
{
public GameObject Panelfade; //フェードパネルの取得
Image fadealpha; //フェードパネルのイメージ取得変数
private float alpha; //パネルのalpha値取得変数
private bool fadeout; //フェードアウトのフラグ変数
private bool fadein; //フェードインのフラグ変数
public int SceneNo; //シーンの移動先ナンバー取得変数
// Use this for initialization
void Start()
{
fadealpha = Panelfade.GetComponent<Image>(); //パネルのイメージ取得
alpha = fadealpha.color.a; //パネルのalpha値を取得
fadein = true; //シーン読み込み時にフェードインさせる
}
// Update is called once per frame
void Update()
{
if (fadein == true)
{
FadeIn();
}
if (fadeout == true)
{
FadeOut();
}
}
void FadeIn()
{
alpha -= 0.01f;
fadealpha.color = new Color(0, 0, 0, alpha);
if (alpha <= 0)
{
fadein = false;
Panelfade.SetActive(false);
}
}
void FadeOut()
{
alpha += 0.01f;
fadealpha.color = new Color(0, 0, 0, alpha);
if (alpha >= 1)
{
fadeout = false;
SceneManager.LoadScene("Fade" + SceneNo);
}
}
public void SceneMove()
{
fadeout = true;
Panelfade.SetActive(true);
}
}
スクリプトができたので、エディターでSceneを追加しFade2とします。
移動先のSceneナンバーを設定したらプレイです。
再生できない場合、ダウンロードは🎥こちら
無事にフェードイン・アウトするようになりました。
フェードパネル単体で稼働させるようにすれば、Game部分のスクリプトと分離できるかと
ざっくりと作ったので、まだまだ修正できる部分があるかと思います。
上のスクリプトをコピペするとfadealpha = Panelfade.GetComponent<Image>();
Imageを挟む<>が全角になっているのでエラーが掛かります。
半角の<>にすると消えてしまうので、全角で書いています。
このくらい修正できないでどうするの(~-~;)ヾ(-_-;) オイオイ
まだまだ先が思いやられます。
【><。】 エーン
2019/5/11更新
コード内の<>を半角に修正しました。
コピペしても大丈夫かと思います。
2022/10/20追記
シーン移動時のフェードを簡単に行えるAsset、
FadeCamera2を新記事にて紹介しています。
FadeCamera2 シーン移動時の演出←クリックするとページが開きます。
フェードだけでなく、ルール画像を使った演出ができるので、
おすすめのAssetになります。
2022/10/21新規スクリプト更新
記事を読み返して、
説明不足・スクリプトの修正が必要と感じたので、
新しく処理を作りました。
以下にまとめます。
・シーンの作成

Androidプラットフォームで作成しています。
Canvasを追加して、
・背景Image
・シーン遷移ボタン
・シーン名テキスト
・パネル
Canvas内に4つのUIを設定しました。
パネルは、フェード用なので、他のUIより前面に配置します。
これをFade1シーンとして保存します。
続いて、シーン追加からFade2シーンを作成します。

Fade1と同じ構成で、シーンを作ります。
背景は、分かりやすいように色を変えておきます。
各シーン、真ん中のボタンを押すとフェード処理後にシーンを移動させます。
UIの準備ができたので、スクリプトを作成します。
新規スクリプトを立ち上げて、FadeManagerとしておきます。
FadeManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class FadeManager : MonoBehaviour
{
[SerializeField]
private GameObject panelFade; //フェードパネル
[SerializeField,Range(0,1)]
private float alpha; //アルファ値、0~1にRangeを設定
private Image panel_fadeImage; //フェードパネルのImage
private bool fadeout, fadein; //フェードのフラグ
private int scenNumber; //シーンナンバー
// Start is called before the first frame update
void Start()
{
panel_fadeImage = panelFade.GetComponent<Image>();
PanelEnabled();
FadeIn();
}
// Update is called once per frame
void Update()
{
if (fadein)
FadeInOperation();
if (fadeout)
FadeOutOperation();
}
//フェードイン呼び出し
private void FadeIn()
{
if (alpha != 1)
alpha = 1f;
fadein = true;
}
//フェードアウト呼び出し
private void FadeOut()
{
if (alpha != 0)
alpha = 0f;
fadeout = true;
}
//フェードイン操作
private void FadeInOperation()
{
alpha -= 0.01f;
var tempColor = panel_fadeImage.color;
tempColor.a = alpha;
panel_fadeImage.color = tempColor;
PanelEnabled();
if (alpha <= 0)
fadein = false;
}
//フェードアウト操作とシーン遷移
private void FadeOutOperation()
{
alpha += 0.01f;
var tempColor = panel_fadeImage.color;
tempColor.a = alpha;
panel_fadeImage.color = tempColor;
PanelEnabled();
if (alpha >= 1)
{
fadeout = false;
SceneManager.LoadScene("Fade" + scenNumber);
}
}
//フェードパネルの表示状態管理
private void PanelEnabled()
{
if (alpha <= 0)
panelFade.SetActive(false);
else
panelFade.SetActive(true);
}
//シーン遷移時のボタン操作
public void SceneMove(int num)
{
scenNumber = num;
FadeOut();
}
}
以前の処理で足りなかった部分を追加しました。
足りなかった点
・FadePanelをOFFにする処理が、FadeIn関数内にしか無かった
・alpha値が0~1の間で止まった場合の処理がない
FadePaneの表示・非表示
フェードイン・アウトは、全面に設定したパネルの透明度を操作する事で、
フェード処理を行っています。
パネルが表示状態だと、パネルより後面のUIにアクセスできません。
ボタンやEventTriggerを設定する場合は、パネルを非表示にする必要があります。
以前の処理では、FadeInさせた時だけパネルが非表示になる仕様だったので、
処理を追加しました。
//フェードパネルの表示状態管理
private void PanelEnabled()
{
if (alpha <= 0)
panelFade.SetActive(false);
else
panelFade.SetActive(true);
}
alpha値を使って、パネルの表示・非表示をコントロールします。
0以下なら非表示。
0より大きければ表示。
この関数を、Start内から呼び出します。
シーン開始時は、alpha値が0から始まるので、自動的にパネルを非表示にしてくれます。
これで、FadeIn関数を使わなくても、パネルがない状態でスタートできます。
以前の処理では、フェード処理中にパネルは表示されてる前提で処理していたので、
新しく、alpha値の計算後にパネルの状態を管理できるようにしました。
//フェードイン操作
private void FadeInOperation()
{
alpha -= 0.01f;
var tempColor = panel_fadeImage.color;
tempColor.a = alpha;
panel_fadeImage.color = tempColor;
PanelEnabled(); ←この部分
if (alpha <= 0)
fadein = false;
}
//フェードアウト操作とシーン遷移
private void FadeOutOperation()
{
alpha += 0.01f;
var tempColor = panel_fadeImage.color;
tempColor.a = alpha;
panel_fadeImage.color = tempColor;
PanelEnabled(); ←この部分
if (alpha >= 1)
{
fadeout = false;
SceneManager.LoadScene("Fade" + scenNumber);
}
}
これでフェード処理中にパネルの表示トラブルが回避できると思います。
フェード処理前のalpha値の管理
フェード処理開始時にalpha値がズレていたら…
機能が不完全に作動する事になります。
手動で数値を変えたなどです。
そこで、フェード処理の前に数値が必ず、0か1になるようにしてから
フェード処理に入るように変更しました。
//フェードイン呼び出し
private void FadeIn()
{
if (alpha != 1)
alpha = 1f;
fadein = true;
}
//フェードアウト呼び出し
private void FadeOut()
{
if (alpha != 0)
alpha = 0f;
fadeout = true;
}
これで必ず、どちらかの数値になるようにできます。
安定して処理が行えるかと思います。
ボタンを使ってシーン遷移させる説明が不十分だったので、
説明を追加しておきます。
シーン遷移は、フェードアウト後に遷移する事を前提にしてるので、
フェードアウト処理内に組み込んでいます。
シーン遷移は、SceneManager.LoadScene関数を使いますが、
ストリング形式でシーン名を指定する必要があります。
今回は、Fade1・Fade2とシーンを用意しました。
このシーン名の数値部分を半角で登録した場合、"Fade"+数値で指定する事ができます。
なので、int型のsceneNumberを設定しました。
SceneManager.LoadScene("Fade" + scenNumber)
ボタンから呼び出す関数は、
//シーン遷移時のボタン操作
public void SceneMove(int num)
{
scenNumber = num;
FadeOut();
}
SceneMove関数に引数を設定しました。
この引数は、Inspector上で設定します。

ボタンのクリック時に割り当てを行いますが、
SceneMove関数を設定すると、関数名の下に数値が入力できるようになります。
これが引数numです。
ここを遷移させたいシーン番号にすれば、sceneNumberに登録できます。
あとは、FadeOut関数を呼び出せば、フェードアウト処理が実行されます。
今回の追加処理は以上となります。
使いたい所で、FadeIn・FadeOut関数を呼び出せば、発動するはずです。
FadeIn関数は、Startで呼び出していますが、
別になくてもOKになります。
ただ、PanelEnabled関数は、必ずStartで呼び出して下さい。
パネルが消えずに残る事になります。
以前の処理よりは使いやすくなったのではないかと思います。
なにかあればコメント頂ければ幸いでっす。m(_ _)m
この記事へのコメント
ぴーなっつ
現在、CanvasにButtonとフェードアウト用のPanelを作成し、Buttonにスクリプトをアタッチして、ボタンがクリックされるとフェードアウト→シーン遷移というものをやろうとしているのですが、うまくいきません…
動画を見るとボタンを押すことでフェードが開始されているように見えるのですが、そのコードはどの部分でしょうか…?
ぴーなっつ
フェードアウトのみ行いたいので、フェードアウトのコードのみ記述して実行しているのですが、ボタンを押しても何も反応しません…
この記事と同様、ボタンを押すとフェードアウトをtrueにし、Update部分にif(fadeout == true){FadeOut()}で実行できるようにしています。
ボタンを押す動作を介さなければフェードしてくれるのですが、ボタンを押すことを挟むとうまくいきません。
説明だけだとわかりにくくて申し訳ありませんが、何か対処法はありますでしょうか…?
kero
ボタンを押すと上手く行かないとの事ですが、
考えられる原因
・ボタンにスクリプトの割り当てができてない
・ビルド設定にシーンの登録ができてない
・SceneNoの変数が設定できてない
この辺りがあやしいかと思います。
少し記事を読み返して、
説明不足・スクリプトの修正が必要と感じたので、
追記記事を発行予定です。
解決の手がかりになればいいのですが、
追記するまで少々お待ちください。
kero
追加記事をアップしました。
追加記事を書いてる時に気付いたのですが、
フェードインを使わないとの事で、フェードパネルが表示状態になってるのではないでしょうか?
パネルが前面にあると後面のUIにアクセスできなくなります。
追加記事にも書いておいてので、その辺りが解決策になるかと思います。
上手く回避できたらコメント頂けると嬉しいです。
ぴーなっつ
あの後何度かやってみたところ、うまく動いてくれるようになりました。わかりやすい記事で、とても助かりました。ありがとうございます!
kero
無事に解決できたみたいで、なによりです。
また何かあれば気軽にコメント頂ければ嬉しいです。
それでは、よりよいunityライフを。