この記事でのバージョン
Unity 2017.4.9f1
はじめに
以前、シーンの遷移とフェードを管理するクラスというのを紹介したのですが、
これはuGUIのImageを使っていたため、VRだと使えませんでした。
(前面しか暗くならない & カメラとImageの間にオブジェクトが挟まる)
なので、今回はVRでも使えるフェードのやり方をご紹介!
もちろんVRじゃない3Dや、2Dでもそのまま使えます。
ポストプロセス
今回は、タイトル通りポストプロセス(イメージエフェクト)を使います。
https://docs.unity3d.com/ja/current/Manual/PostProcessingWritingEffects.html
ポストプロセスとは
レンダリングした画像(ゲーム画面として表示される画像)にエフェクトをかけるというもので、
今回は画像フェードさせるようなエフェクトをかける感じになります。
なお、ポストプロセスを使って見栄えをよくしたい場合は以下の記事をどうぞ。
CameraFader
早速、カメラをフェードするクラスCameraFaderのコードです。
なお、CameraFaderを使うにはCameraFadeというシェーダーが必要です。
Shader "CameraFade" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1,1,1,1) } SubShader { Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); fixed4 _Color; fixed4 frag (v2f i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv)* _Color; } ENDCG } } }
CameraFaderの使い方は簡単、Cameraが付いてるオブジェクトにCameraFaderをAddし、
CameraFaderのFadeOutやFadeInを実行するだけ。
//Inspectorから設定 [SerializeField] private CameraFader _cameraFader = null; //フェードアウト public void FadeOut () { _cameraFader.FadeOut(); } //フェードイン public void FadeIn() { _cameraFader.FadeIn(); }
durationでフェード時間、isIgnoreTimeScaleでTimeScale(時間の倍率)を無視するか、
callbackでフェード終了時のコールバックを設定することも可能です。
_cameraFader.FadeOut( duration : 1, isIgnoreTimeScale : false, callback : () => {} );
ただし、上記イメージのFadeInボタンのように
CanvasのRender ModeがScreen Space - Overlayだとフェードしません。
SceneNavigator
CameraFaderはフェードさせるだけなので、シーン遷移時にフェードさせたい場合は
フェードアウト→シーン遷移→フェードインという処理を実装する必要があります。
という事で、その処理を行うSceneNavigatorというものもついでに作ったので、これもご紹介!
なお、SceneNavigatorを使うにはSingletonMonoBehaviourが必要です。
「全てのシーンに存在し、かつ、一つしか存在してはいけない」ように実装しているので、
(ゲーム開始時にSceneNavigatorが自動生成され、ゲーム終了まで破棄されない。)
特に設定などは必要ありませんし、どのシーンから始めても大丈夫です。
また、カメラにCameraFaderをAddする部分も自動でやっています。
使い方も簡単で、
SceneNavigator.Instance.ChangeSceneに遷移したいシーン名を指定して実行するだけ。
SceneNavigator.Instance.ChangeScene("Scene2");
なお、fadeDurationでフェード時間、
fadeDelayでフェード間の遅延時間(真っ暗になってる時間)を設定する事も可能ですし、
SceneNavigator.Instance.ChangeScene("Scene2", fadeDuration:2, fadeDelay:1);
IsChangingを参照することでシーン遷移中かの判定も行えます。
(「遷移中はボタンを押せないようにする」みたいな時に使える。)
//シーン遷移(フェード)中 if(SceneNavigator.Instance.IsChanging){ }
ただし、Camera.mainで取得出来るカメラをフェードしているので、
MainCameraのTagが設定されているカメラがなかったり、複数カメラがある場合はうまく動きません。