Unity初心者でも簡単に画像をフェードイン・アウトさせる方法
ゲームを作っているとキャラクターなどを徐々に消滅させたり、徐々に現れたりさせたい場合があると思います。
今回はシンプルにフェードイン、フェードアウトさせていくやり方を紹介したいと思います。
これを使えばキャラクター以外にもUIをふわっと表示させたり、非表示にしたりすることもできるようになります。
フェードに必要なものを準備
それでは早速フェードに必要なものを配置していきましょう。
と言っても最初は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メソッド
・現在のcolorを保持
・Fadeコルーチン開始(引数は0)
コルーチンの0の値はalpha値を0にしていくために引数として渡す必要があります。
続いてFadeコルーチンです。ざっくりとした流れは以下の通りです。
Fade
・現在の値と目標の値が近くなるまで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開発おすすめPC
NEXTGEAR JG-A5G5A

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 3050
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
Lenovo LOQ Essential Gen 9 - ルナグレー

CPU : インテル® Core™ i7-12650HX
グラフィックス : NVIDIA® GeForce RTX™ 4050 Laptop GPU 6GB GDDR6
メモリ標準容量 : 16 GB DDR5-4800MHz
ストレージ : 512 GB SSD M.2 2242 PCIe-NVMe Gen4 QLC
ディスプレイ :15.6" FHD液晶 (1920 x 1080) IPS, 光沢なし, マルチタッチ非対応, 100%sRGB, 300 nit, 144Hz
内蔵カメラ :720p HDカメラ (プライバシーシャッター付)
無線 :Wi-Fi 6対応 (IEEE 802.11ax/ac/a/b/g/n準拠) 2x2 & Bluetooth®
保証期間 : 1 年間 Legion Ultimate Support
LOQ Tower 17IRR9 :カスタマイズモデル

CPU : インテル® Core™ i5-14400F プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 3050 6GB GDDR6
メモリ標準容量 : 16 GB DDR5-4800MHz (UDIMM) - (2 x 8 GB)
ストレージ : 512 GB SSD M.2 2280 PCIe-NVMe Gen4 TLC
保証期間 : 1 年間 Legion Ultimate Support
NEXTGEAR JG-A5G60(ホワイトカラーモデル)

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 4060
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
NEXTGEAR JG-A5G60(1周年記念モデル)

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 4060
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
G TUNE FG-A7A7X

CPU : AMD Ryzen™ 7 9800X3D プロセッサ
グラフィックス : AMD Radeon™ RX 7700 XT
メモリ標準容量 : 32GB (16GB×2 / デュアルチャネル
M.2 SSD : 2TB (NVMe Gen4×4)
ドライブ仕様 :DVDスーパーマルチドライブ
無線 :Wi-Fi 6E( 最大2.4Gbps )対応 IEEE 802.11 ax/ac/a/b/g/n準拠 + Bluetooth 5内蔵
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
関連記事

TextMeshProでリンクを作成する方法とそのバグの解消法
今回はTMPのリンクを生成するLinkタグについて紹介したいと思います。
ちょっとしたハマりポイントもあるのでそちらについても触れていきたいと思います。

UnityでCSVを活用したメッセージウィンドウの作り方
メッセージの内容を変更したい時や、新しいメッセージを追加したい時にCSVファイルを使えば、メッセージの編集や追加が簡単になり、開発がスムーズになります。

Unity2D ドット絵の簡単なアニメーションを作ってみる
Unity2Dで簡単なドット絵のアニメーションを作成します。スプライトを切り替えることでプレイヤーが歩いているように見えるアニメーションを作成してみます。
この方法を応用することでキャラクターに色んな動きや表示を付け加えることができると思います。

ChatGPTの指示通りUnityゲームを作ってみる
最近ではChatGPTを始め様々な大規模言語モデルの対話型AIが公開されていますね。
そこで今回はChatGPTの指示に従ってゲームを作ってみる実験をしてみます。

Unityで9-sliceテクニックを使った効果的なUI作成方法
UI作成時に非常に便利なテクニック9-sliceをやってみます。
とても簡単に使える技です。

Transform.RotateとQuaternion.Eulerでオブジェクト回転
Unity2Dで簡単なゲームオブジェクトの回転を実装してみたいとおもいます。
Transform.RotateとQuaternion.Eulerの二種類の回転方法を実験します。
ルーレットとか、方位をコンパス。またはプレイヤーがやられた時に回転させるなどに使えそうです。
最後までご覧頂いてありがとうございました。
宜しければコメントをどうぞ