今回はタイトル画面からゲーム画面へと遷移する時の読み込み中(NowLoading)の画面を作成していきます。
シーンの読み込みが終わるまで後どのぐらいか?というのがわかると親切ですね。
今回の機能を作成するにあたりコルーチンを使っていますので、コルーチンって何!?という方は
を参照してください。
また今回の機能はUnityのライブトレーニング
を参考にさせて頂きました。
タイトル画面用のシーンを作成する
まずはタイトル画面用のシーンを作成し、ボタンを押すと次のシーンを読み込むスクリプトを作ります。
タイトル画面のUIを作成する
ヒエラルキー上で右クリック→UI→Canvasを選択します。
子要素に右クリック→UI→Button、UI→Panelを選択し名前をBackgroundとします。
Buttonは押した時に次のシーンの読み込みを開始するスクリプトを実行させます(設定は後で行います)。
Backgroundは次のシーンを読み込んでいる間に表示する背景にします。
Backgroundの子要素に右クリック→UI→Sliderを選択しスライダーを作成します。
Sliderの値はスクリプトから操作するのでinteractableのチェックは外しておきます。
Sliderの子要素のHandle Slide Areaは使わないので削除するかインスペクタで名前の横のチェックを外し見えないようにしておきます。
↑がヒエラルキーになります。
Backgroundを選択し、インスペクタのImageのColorの色部分を選択し色を変更します。
↑のように背景色を黒で透明度を0にして透けて見えないようにしておきます。
FillAreaのサイズを調整します。
↑のような感じでスライダーの背景部分を調整します。
スライダーの値を表すFillも調整します。
SliderのValueを1にした時にFillがFillAreaを満たすようにFillのRectTransformを調整します。
ここでSliderのValueが1の時にFillが満たされる状態に作っておかないと100%の時もスライダーの値が満たされる事がありません。
↑が出来上がったローディング中の画面になります。
Slider子要素のFill Area/FillのImageのColorも赤色に変更してローディングメーターが赤くなるようにしました。
BackgroundはButtonを押した時にアクティブにして表示するようにする為、最初はインスペクタの横のチェックを外し見えないようにしておきます。
次のシーンを読み込むLoadingスクリプトの作成
次にButtonを押した時に次のシーンを読み込むスクリプトを作成していきます。
スクリプトはMain Cameraに取りつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Loading : MonoBehaviour { // 非同期動作で使用するAsyncOperation private AsyncOperation async; // シーンロード中に表示するUI画面 [SerializeField] private GameObject loadUI; // 読み込み率を表示するスライダー [SerializeField] private Slider slider; public void NextScene() { // ロード画面UIをアクティブにする loadUI.SetActive(true); // コルーチンを開始 StartCoroutine("LoadData"); } IEnumerator LoadData() { // シーンの読み込みをする async = SceneManager.LoadSceneAsync("Load1"); // 読み込みが終わるまで進捗状況をスライダーの値に反映させる while(!async.isDone) { var progressVal = Mathf.Clamp01(async.progress / 0.9f); slider.value = progressVal; yield return null; } } } |
NextSceneメソッドはButtonをクリックした時に呼び出す関数でロード画面UIをアクティブにしコルーチンを開始しています。
LoadDataメソッドでは指定したシーンを読み込みasyncに入れています。
今回はLoad1という名前のシーンを読み込んでいます。
asyncは非同期動作であるコルーチンで使用するAsyncOperationの値で読み込みの状況を把握する事が出来ます。
whileループで読み込みが終了していない間はスライダーの値にasync.progressの値を入れています。
async.progressはfloat型の値で0~1の値が得られます。
Sliderの値はデフォルトでは0から1のfloat型の値となっているのでそのままslider.valueに入れる事で進捗状況がわかるようになっています。
ただasync.progressが0.9を越えると実際のシーン移動がアクティブになる?ようなのでMathf.Clamp01を使ってasync.progressの値を0~1の間に補正します。
次にButtonを選択しOn Click()にこのLoadingスクリプトのNextScene関数を設定しましょう。
↑のようにCanvasの子要素にあるButtonを選択しNextScene関数を設定します。
これで次のシーンを読み込むタイトルシーンが出来上がりました。
出来たシーンをLoadingという名前で保存しておきます。
またProjectタブのAssetsフォルダで右クリック→Create→Folderを選択し名前をScenesにしてこの中にLoadingシーンを入れておきます。
読み込まれるシーンの作成
次に読み込まれるシーンを作成していきます。
読み込まれるシーンのゲームオブジェクトを作成する
ProjectタブのAssetsフォルダのScenesフォルダ内で右クリック→Create→Sceneを選択し名前をLoad1とします。
ヒエラルキー上で右クリック→3D Object→Cubeを選択しサイズを変えStaticにチェックを入れます。
↑のように変更します。
このCubeをコピーし10個ほど作成しておきます。
次にヒエラルキーで右クリック→Canvasを選択し名前をFadeInとします。
子要素に右クリック→Panelを選択し作成します。
Panelを選択し、インスペクタのImageのColorを黒の透明度をなしにしておきます。
↑が出来上がったヒエラルキーになります。
フェードイン処理を行うFadeInスクリプトの作成
新しいシーンLoad1が読み込まれた時に黒い背景から段々透明になるフェードインの処理を追加しましょう。
FadeInゲームオブジェクトにFadeInというスクリプトを作り取りつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using UnityEngine; using System.Collections; using UnityEngine.UI; public class FadeInScript : MonoBehaviour { // フェードインのおおよその秒数 [SerializeField] private float fadeInTime; // 背景Image private Image image; void Start () { image = transform.Find("Panel").GetComponent<Image>(); // コルーチンで使用する待ち時間を計測 fadeInTime = 1f * fadeInTime / 10f; StartCoroutine("FadeIn"); } IEnumerator FadeIn() { // Colorのアルファを0.1ずつ下げていく for(var i = 1f; i >= 0; i -= 0.1f) { image.color = new Color(0f, 0f, 0f, i); // 指定秒数待つ yield return new WaitForSeconds(fadeInTime); } } } |
インスペクタでおおよその透明化する為の時間を設定出来るようにしてます。
Start関数内でfadeInTimeの値を書き換えコルーチンでの待ち時間を計算しています。
FadeIn関数内ではfor文を使いPanelのImageのColorのAlpha(透明度)を変更し、背景色を変えていきます。
作成したシーンを登録する
シーンが2つ出来たので登録しましょう。
UnityメニューのFile→Build Settings…を選択します。
新しい画面が表示されるのでScene In Buildに作成したLoadingとLoad1シーンをドラッグ&ドロップします。
Loadingシーンを上に移動します。
シーンは上から順番に再生されますので最初にLoading(タイトルシーン)が再生されます。
上のようにシーンを登録しました。
ローディング画面とフェードインを確認する
機能が完成したのでローディング画面とフェードインが出来ているかどうか確認しましょう。
読み込み率がパパッと変わってしまってうまく動作しているかちょっとわかり辛いですね・・・。
読み込むシーンの容量が小さいからという理由だけではなく、わたくしのパソコンだと綺麗にローディングが進むのを確認出来ませんでした・・・(^_^;)
fadeInTimeは1を設定したのでだいたい1秒ぐらいで画面が黒から透明に変わっています。
ローディング時にエラーが出て実行出来ない!?
さきほど挙げたローディングの進み具合の件ではなく、コルーチンを使用して進捗処理をしているスクリプトでエラーが出て同じように出来ない事があります。
Unity2017.3.1f1で確認したところエラーは発生しませんでした。
↑のようにエラーが出てシーンの読み込みが出来ません。
エラーの内容はメインスレッドでのみGetLocalizedStringは実行されます。シーンをロードする時にコンストラクタやイニシャライザは実行されます。
という事でAwakeかStartを使ってくださいみたいな内容です。
んー・・・・初期化はAwakeかStartを使ってといわれても何の事を言ってるのかわかりません。
読み込むシーンによってこのようなエラーが出てしまいます。
2つ目に表示されたエラーを選択し、下の方を見てみると、
↑のようなエラーが出ます。
TreeEditorがなんちゃらと出ています。
このTreeEditorは
で使ったUnityに付いている木を作るツールです。
そこで思ったんですが、読み込んだシーンではこのTreeEditorを使って作成した木を設置していたんです。
試しにこの木をヒエラルキーから削除して読み込みをしてみたら問題なく読み込めました・・・・。
自前の木を設置してると読み込みが出来ないんですかね・・・・(^_^;)
わたくしのUnityは5.3.4f1なんですがバージョンアップすると問題は出ないんですかね・・・(わたくしのパソコンではもうバージョンアップ出来ない・・・)。
今のところ解決出来ていないので自前の木は設置しない方向でいきます・・・・(^_^;)