はじめに
Unityで普通に画面遷移すると、とても質素で安っぽくなってしまいます。画面遷移時に一瞬だけ暗転するとそれだけで結構いい感じになります。
アセットのようなものもあるみたいですが、それ程難しくない気がしたので今回は自作してみました。
完成イメージ
環境
Windows10
Unity2019.3.12f1
構成
今回はシーン1とシーン2を用意してここに実装します。スクリプトは以下を用意します。
- SceneController:MainCameraにくっつけます
- FadeManader:暗転パネル用Canvasにくっつけます
一応シーン1は赤、シーン2は青にしてあります。
あとスクショにはありませんが、シーン切り替え用のボタンも配置してあります。
流れ
先におおまかな流れを書いておくと、
1.暗転用のパネルを作る
2.暗転用のパネルを召喚
3.パネルのフェードイン、アウトの仕組みを作る
4.シーン切り替え時にフェードするようにする
の4本立てとなります。
実装
暗転用パネル
まずは暗転用のパネルをつくります。
イメージでも良いんですがパネルのほうが好きなので今回はパネルでいきます。
パネルは毎シーンごとに用意する方法もあるかと思いますが、一応シーンを跨ぐので最初にPrefabから呼び出してDontDestroyOnLoadで保持することにします。
DontDestroyOnLoadはCanvas以下のUIには適応できないので、別のCanvasを作ってそこにPanelを置きCanvasごとPrefab化します。以下の感じ。
それと、このCanvasが一番上に来るようにソート順を0から1に上げておきます。
ついでに見つけやすくするためタグも変更しておきます。
中のPanelは色を黒にして、「レイキャストターゲット」のチェックを外しておきます。
「レイキャストターゲット」をOFFにしておくことで下にあるBotton等を触れるようになります。
ここまで一旦CanvasごとPrefab化しておきます。
暗転用パネル召喚
Prefab化した暗転用パネルを呼び出してDontDestroyOnLoadします。
まずは暗転用パネルをインスタンス化します(今回は面倒だったのでMainCameraにアタッチしたSceneControllerを使って暗転用パネルを召喚します)。
publicclassSceneController:MonoBehaviour{publicGameObjectfade;//インスペクタからPrefab化したCanvasを入れるvoidStart(){if(!FadeManager.isFadeInstance)//isFadeInstanceは後で用意する{Instantiate(fade);}}}次にインスタンス化したCanvasをDontDestroyOnLoadします。
FadeManagerはPrefab化したCanvasにアタッチします(Panelではないので注意してください)。
publicclassFadeManager:MonoBehaviour{publicstaticboolisFadeInstance=false;//Canvas召喚フラグvoidStart(){if(!isFadeInstance)//起動時{DontDestroyOnLoad(this);isFadeInstance=true;}else//起動時以外は重複しないようにする{Destroy(this);}}}あとはインスペクタ上でしっかり設定すれば開始時にCanvasが召喚されてDontDestroyOnLoadになると思います。
フェード
そしたら次はCanvas内のPanelの透過率を変化させてフェードする仕組みをつくります。
usingUnityEngine.UI;//追加publicclassFadeManager:MonoBehaviour{publicstaticboolisFadeInstance=false;publicboolisFadeIn=false;//フェードインするフラグpublicboolisFadeOut=false;//フェードアウトするフラグpublicfloatalpha=0.0f;//透過率、これを変化させるpublicfloatfadeSpeed=0.2f;//フェードに掛かる時間voidStart(){//省略}voidUpdate(){if(isFadeIn){alpha-=Time.deltaTime/fadeSpeed;if(alpha<=0.0f)//透明になったら、フェードインを終了{isFadeIn=false;alpha=0.0f;}this.GetComponentInChildren<Image>().color=newColor(0.0f,0.0f,0.0f,alpha);}elseif(isFadeOut){alpha+=Time.deltaTime/fadeSpeed;if(alpha>=1.0f)//真っ黒になったら、フェードアウトを終了{isFadeOut=false;alpha=1.0f;}this.GetComponentInChildren<Image>().color=newColor(0.0f,0.0f,0.0f,alpha);}}publicvoidfadeIn(){isFadeIn=true;isFadeOut=false;}publicvoidfadeOut(){isFadeOut=true;isFadeIn=false;}}this.GetComponentInChildren().colorはCanbasの子であるPanelのImageコンポーネントを操作しています。
これでisFadeInやisFadeOutのフラグを操作することでパネルのフェードインやアウトができます。
あとはこのフラグ操作をシーンチェンジのタイミングに合わせてで行うだけです。
シーン切り替え
usingSystem.Threading.Tasks;//追加usingUnityEngine.SceneManagement;//追加publicclassSceneController:MonoBehaviour{publicGameObjectfadeCanvas;//操作するCanvas、タグで探すvoidStart(){//省略Invoke("findFadeObject",0.02f);//起動時用にCanvasの召喚をちょっと待つ}voidfindFadeObject(){fadeCanvas=GameObject.FindGameObjectWithTag("Fade");//CanvasをみつけるfadeCanvas.GetComponent<FadeManager>().fadeIn();//フェードインフラグを立てる}publicasyncvoidsceneChange(stringsceneName)//ボタン操作などで呼び出す{fadeCanvas.GetComponent<FadeManager>().fadeOut();//フェードアウトフラグを立てるawaitTask.Delay(200);//暗転するまで待つSceneManager.LoadScene(sceneName);//シーンチェンジ}}InvokeやDelayの時間はFadeManagerのfadeSpeedと合わせて調整してください。

