Edited at

【Unity(C#)】3Dでのフェードアウト、フェードイン

  

  

 

  

この記事は

『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』

の記事です。そのつもりでお読みください。


Canvas、Panelを作る

フェードアウト、フェードインに必要なCanvas,Panelを作ります。

フェードアウト、フェードインは汎用性が高いので、何度でも使いまわせるように

Canvas,Panelがプレイ時に自動で生成されるようにしました。

(スクリプトでゲームオブジェクトを作る方法→こちら)

細かい設定はこちらを参考にさせて頂きました。

Canvasについて

Canvas faceCanvas;

Image facePanel;

//~省略~

//キャンバス生成&設定
GameObject canvas_G = new GameObject("FaceCanvas");
faceCanvas = canvas_G.AddComponent<Canvas>();
canvas_G.AddComponent<CanvasScaler>();
canvas_G.AddComponent<GraphicRaycaster>();

//レンダリングをメインカメラに
faceCanvas.renderMode = RenderMode.ScreenSpaceCamera;
faceCanvas.worldCamera = FindObjectOfType<Camera>();

//パネル生成&設定
GameObject panel_G = new GameObject("FacePanel");
facePanel = panel_G.AddComponent<Image>();

Color tmpColor = facePanel.color;
tmpColor.a = 0f;
facePanel.color = tmpColor;

//パネルをキャンバスの子に設定
panel_G.transform.parent = canvas_G.transform;

//パネルのポジションを正面に調整
Vector3 panelPosition = panel_G.transform.localPosition;
panelPosition.x = 0;
panelPosition.y = 0;
panel_G.transform.localPosition = panelPosition;

これで、自動的にCanvasとPanelがカメラの前に現れます。


フェードアウト、フェードイン

Alphaを徐々に変更することでフェードを再現します。

Panelの持つImage ComponentColorAlphaです。

コルーチンでAlphaの値を変えます。

コルーチン→こちら

 IEnumerator FadeOutCoroutine()

{
float alpha = 1;

while (panelColor.a < 1)
{
yield return new WaitForSeconds(0.1f);
panelColor.a += alpha / (fadeTime*10);
facePanel.color = panelColor;
}

panelColor.a = 1;

StopCoroutine(coroutine);
coroutine = null;
}

IEnumerator FadeInCoroutine()
{
float alpha = 1;

while (panelColor.a > 0)
{
yield return new WaitForSeconds(0.1f);
panelColor.a -= alpha / (fadeTime * 10);
facePanel.color = panelColor;
}

panelColor.a = 0;

StopCoroutine(coroutine);
coroutine = null;
}
}


最終的なコード

今回は、色とフェードする時間をInspectorで変更できるようにしてます。

確認用のテストキーも用意しました。

using System.Collections;

using UnityEngine;
using UnityEngine.UI;

public class FadeInOut : MonoBehaviour
{
Canvas faceCanvas;

Image facePanel;

Coroutine coroutine;

[SerializeField]
Color panelColor = new Color(0,0,0,0);

[SerializeField]
float fadeTime = 5;

// Start is called before the first frame update
void Start()
{
//キャンバス生成&設定
GameObject canvas_G = new GameObject("FaceCanvas");
faceCanvas = canvas_G.AddComponent<Canvas>();
canvas_G.AddComponent<CanvasScaler>();
canvas_G.AddComponent<GraphicRaycaster>();

//レンダリングをメインカメラに
faceCanvas.renderMode = RenderMode.ScreenSpaceCamera;
faceCanvas.worldCamera = FindObjectOfType<Camera>();

//パネル生成&設定
GameObject panel_G = new GameObject("FacePanel");
facePanel = panel_G.AddComponent<Image>();

Color tmpColor = facePanel.color;
tmpColor.a = 0f;
facePanel.color = tmpColor;

//パネルをキャンバスの子に設定
panel_G.transform.parent = canvas_G.transform;

//パネルのポジションを正面に調整
Vector3 panelPosition = panel_G.transform.localPosition;
panelPosition.x = 0;
panelPosition.y = 0;
panel_G.transform.localPosition = panelPosition;

}

void Update()
{
//キー押してない間はreturn
if (Input.anyKey == false)
{
return;
}

if (coroutine == null)
{
//テスト用 フェードアウト
if (Input.GetKeyDown(KeyCode.O) && panelColor.a == 0)
{
FadeOut();
}

//テスト用 フェードイン
if (Input.GetKeyDown(KeyCode.I) && panelColor.a == 1)
{
FadeIn();
}

}

}

public void FadeOut()
{
if (panelColor.a == 0)
{
coroutine = StartCoroutine(FadeOutCoroutine());
}
}

IEnumerator FadeOutCoroutine()
{
float alpha = 1;

while (panelColor.a < 1)
{
yield return new WaitForSeconds(0.1f);
panelColor.a += alpha / (fadeTime * 10);
facePanel.color = panelColor;
}

panelColor.a = 1;

StopCoroutine(coroutine);
coroutine = null;
}

public void FadeIn()
{
if (panelColor.a == 1)
{
coroutine = StartCoroutine(FadeInCoroutine());
}
}

IEnumerator FadeInCoroutine()
{
float alpha = 1;

while (panelColor.a > 0)
{
yield return new WaitForSeconds(0.1f);
panelColor.a -= alpha / (fadeTime * 10);
facePanel.color = panelColor;
}

panelColor.a = 0;

StopCoroutine(coroutine);
coroutine = null;
}
}

GifCapture-201902112346425569.gif

フェードさせたい箇所でFadeIn,FadeOutを呼び出せばいけるはずです。たぶん。

本当は、UnityEventを使い、Inspectorで色や時間の引数を渡して、

違うフェードを複数呼び出せる仕様にしたかったのですが、無理でした。

(どうやら、UnityEventの引数はInspector上では一つしか登録できないようです...)