Unity で FadeIn, FadeOut をつけてみる

シェアする

画面切り替えの際にフェードイン/アウトをしたくなったので調べたら Unify Community Wiki にあったので試してみた。

各言語毎にスクリプトが記載してあるが OnGUI メソッド内で Label もしくは Texture を表示している事は共通のようだ。

自分が利用したのはページ中ほどにある Another Fade Script in C#, Extended Singleton  というやつ。C# で書いてあるし引数にコールバックを取れるのが便利だ。

スクリプトをコピーして plugins 下に CameraFade という名前で保存しよう。

using UnityEngine;
using System;
 
public class CameraFade : MonoBehaviour
{   
	private static CameraFade mInstance = null;
 
	private static CameraFade instance {
		get {
			if( mInstance == null ) {
				mInstance = GameObject.FindObjectOfType(typeof(CameraFade)) as CameraFade;
 
				if( mInstance == null ) {
					mInstance = new GameObject("CameraFade").AddComponent<CameraFade>();
				}
			}
 
			return mInstance;
		}
	}
 
	void Awake() {
		if( mInstance == null ) {
			mInstance = this as CameraFade;
			instance.init();
		}
	}
 
	public GUIStyle m_BackgroundStyle = new GUIStyle();						// Style for background tiling
	public Texture2D m_FadeTexture;											// 1x1 pixel texture used for fading
	public Color m_CurrentScreenOverlayColor = new Color(0,0,0,0);			// default starting color: black and fully transparrent
	public Color m_TargetScreenOverlayColor = new Color(0,0,0,0);			// default target color: black and fully transparrent
	public Color m_DeltaColor = new Color(0,0,0,0);							// the delta-color is basically the "speed / second" at which the current color should change
	public int m_FadeGUIDepth = -1000;										// make sure this texture is drawn on top of everything
 
	public float m_FadeDelay = 0;
	public Action m_OnFadeFinish = null;
 
	// Initialize the texture, background-style and initial color:
	public void init() {		
		instance.m_FadeTexture = new Texture2D(1, 1);        
        instance.m_BackgroundStyle.normal.background = instance.m_FadeTexture;
	}
 
	// Draw the texture and perform the fade:
	void OnGUI() {   
		// If delay is over...
		if( Time.time > instance.m_FadeDelay ) {
			// If the current color of the screen is not equal to the desired color: keep fading!
			if (instance.m_CurrentScreenOverlayColor != instance.m_TargetScreenOverlayColor) {			
				// If the difference between the current alpha and the desired alpha is smaller than delta-alpha * deltaTime, then we're pretty much done fading:
				if (Mathf.Abs(instance.m_CurrentScreenOverlayColor.a - instance.m_TargetScreenOverlayColor.a) < Mathf.Abs(instance.m_DeltaColor.a) * Time.deltaTime) {
					instance.m_CurrentScreenOverlayColor = instance.m_TargetScreenOverlayColor;
					SetScreenOverlayColor(instance.m_CurrentScreenOverlayColor);
					instance.m_DeltaColor = new Color( 0,0,0,0 );
 
					if( instance.m_OnFadeFinish != null )
						instance.m_OnFadeFinish();
 
					Die();
				} else {
					// Fade!
					SetScreenOverlayColor(instance.m_CurrentScreenOverlayColor + instance.m_DeltaColor * Time.deltaTime);
				}
			}
		}
		// Only draw the texture when the alpha value is greater than 0:
		if (m_CurrentScreenOverlayColor.a > 0) {			
    		GUI.depth = instance.m_FadeGUIDepth;
    		GUI.Label(new Rect(-10, -10, Screen.width + 10, Screen.height + 10), instance.m_FadeTexture, instance.m_BackgroundStyle);
		}
    }
 
 
	/// <summary>
	/// Sets the color of the screen overlay instantly.  Useful to start a fade.
	/// </summary>
	/// <param name='newScreenOverlayColor'>
	/// New screen overlay color.
	/// </param>
	private static void SetScreenOverlayColor(Color newScreenOverlayColor) {
		instance.m_CurrentScreenOverlayColor = newScreenOverlayColor;
		instance.m_FadeTexture.SetPixel(0, 0, instance.m_CurrentScreenOverlayColor);
		instance.m_FadeTexture.Apply();
	}
 
 	/// <summary>
 	/// Starts the fade from color newScreenOverlayColor. If isFadeIn, start fully opaque, else start transparent.
 	/// </summary>
 	/// <param name='newScreenOverlayColor'>
 	/// Target screen overlay Color.
 	/// </param>
 	/// <param name='fadeDuration'>
 	/// Fade duration.
 	/// </param>
	public static void StartAlphaFade(Color newScreenOverlayColor, bool isFadeIn, float fadeDuration ) {
		if (fadeDuration <= 0.0f)		{
			SetScreenOverlayColor(newScreenOverlayColor);
		} else					{
			if( isFadeIn ) {
				instance.m_TargetScreenOverlayColor = new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 );
				SetScreenOverlayColor( newScreenOverlayColor );
			} else {
				instance.m_TargetScreenOverlayColor = newScreenOverlayColor;
				SetScreenOverlayColor( new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 ) );
			}
 
			instance.m_DeltaColor = (instance.m_TargetScreenOverlayColor - instance.m_CurrentScreenOverlayColor) / fadeDuration;	
		}
	}
 
	/// <summary>
	/// Starts the fade from color newScreenOverlayColor. If isFadeIn, start fully opaque, else start transparent, after a delay.
	/// </summary>
	/// <param name='newScreenOverlayColor'>
	/// New screen overlay color.
	/// </param>
	/// <param name='fadeDuration'>
	/// Fade duration.
	/// </param>
	/// <param name='fadeDelay'>
	/// Fade delay.
	/// </param>
	public static void StartAlphaFade(Color newScreenOverlayColor, bool isFadeIn, float fadeDuration, float fadeDelay ) {
		if (fadeDuration <= 0.0f)		{
			SetScreenOverlayColor(newScreenOverlayColor);
		} else					{
			instance.m_FadeDelay = Time.time + fadeDelay;			
 
			if( isFadeIn ) {
				instance.m_TargetScreenOverlayColor = new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 );
				SetScreenOverlayColor( newScreenOverlayColor );
			} else {
				instance.m_TargetScreenOverlayColor = newScreenOverlayColor;
				SetScreenOverlayColor( new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 ) );
			}
 
			instance.m_DeltaColor = (instance.m_TargetScreenOverlayColor - instance.m_CurrentScreenOverlayColor) / fadeDuration;
		}
	}
 
	/// <summary>
	/// Starts the fade from color newScreenOverlayColor. If isFadeIn, start fully opaque, else start transparent, after a delay, with Action OnFadeFinish.
	/// </summary>
	/// <param name='newScreenOverlayColor'>
	/// New screen overlay color.
	/// </param>
	/// <param name='fadeDuration'>
	/// Fade duration.
	/// </param>
	/// <param name='fadeDelay'>
	/// Fade delay.
	/// </param>
	/// <param name='OnFadeFinish'>
	/// On fade finish, doWork().
	/// </param>
	public static void StartAlphaFade(Color newScreenOverlayColor, bool isFadeIn, float fadeDuration, float fadeDelay, Action OnFadeFinish ) {
		if (fadeDuration <= 0.0f)		{
			SetScreenOverlayColor(newScreenOverlayColor);
		} else {
			instance.m_OnFadeFinish = OnFadeFinish;
			instance.m_FadeDelay = Time.time + fadeDelay;
 
			if( isFadeIn ) {
				instance.m_TargetScreenOverlayColor = new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 );
				SetScreenOverlayColor( newScreenOverlayColor );
			} else {
				instance.m_TargetScreenOverlayColor = newScreenOverlayColor;
				SetScreenOverlayColor( new Color( newScreenOverlayColor.r, newScreenOverlayColor.g, newScreenOverlayColor.b, 0 ) );
			}
			instance.m_DeltaColor = (instance.m_TargetScreenOverlayColor - instance.m_CurrentScreenOverlayColor) / fadeDuration;
		}
	}
 
	void Die() {
		mInstance = null;
		Destroy(gameObject);
	}
 
	void OnApplicationQuit() {
		mInstance = null;
	}
}

これを利用するには以下のように書く。

public class main : MonoBehaviour {
    void Start() {
        // 1秒後に1秒かけて白色でフェードイン
        CameraFade.StartAlphaFade(Color.white, true, 1f, 1f);

        // 1秒かけてフェードアウト, 終わったら LoadLevel
        CameraFade.StartAlphaFade(Color.white, false, 1f, 0f, () => { Application.LoadLevel("hoge"); });
    }
}

手軽に扱えて良いです。

Sponsored Link

シェアする

フォローする