質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1794閲覧

【Unity】フェードを利用したシーン切り替えを行いたい。

kei0105

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2023/06/13 07:02

編集2023/06/18 14:01

実現したいこと

  • フェードを利用したシーン切り替えを行いたい。

前提

私は現在2Dゲーム制作を行っており、
ブログ及び動画 https://dkrevel.com/makegame-beginner/make-2d-action-scene-change/
を参考にさせて頂いております。

制作中ゲームでは実遊戯を想定したシーン切り替えを行いたいと考えております。
実装目標はステージシーンやステージクリアからタイトル画面へ戻り、
"再度"ステージシーンへの遷移です。
(初回のタイトル画面からステージシーンへのフェードを利用したシーン切り替えは動く)

発生している問題・エラーメッセージ

<シーンが切り替わらない>
現在、
ステージ→中断(ポーズ画面)→タイトル画面
を作成したのですが、
タイトル画面へ切り替え後、”再度”ステージシーンへの切り替え(再度ゲームプレイ)をすることができません。

FadeImage.csの改修が必要であると考えますが私には改良方法が不明であった為、
その方法をご教示頂きたく思います。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class FadeImage : MonoBehaviour 7{ 8 [Header("最初からフェードインが完了しているかどうか")] public bool firstFadeInComp; 9 10 private Image img = null; 11 private int frameCount = 0; 12 private float timer = 0.0f; 13 private bool fadeIn = false; 14 private bool fadeOut = false; 15 private bool compFadeIn = false; 16 private bool compFadeOut = false; 17 18 /// <summary> 19 /// フェードインを開始する 20 /// </summary> 21 public void StartFadeIn() 22 { 23 if (fadeIn || fadeOut) 24 { 25 return; 26 } 27 fadeIn = true; 28 compFadeIn = false; 29 timer = 0.0f; 30 img.color = new Color(1, 1, 1, 1); 31 img.fillAmount = 1; 32 img.raycastTarget = true; 33 } 34 35 /// <summary> 36 /// フェードインが完了したかどうか 37 /// </summary> 38 /// <returns></returns> 39 public bool IsFadeInComplete() 40 { 41 return compFadeIn; 42 } 43 44 /// <summary> 45 /// フェードアウトを開始する 46 /// </summary> 47 public void StartFadeOut() 48 { 49 if (fadeIn || fadeOut) 50 { 51 return; 52 } 53 fadeOut = true; 54 compFadeOut = false; 55 timer = 0.0f; 56 img.color = new Color(1, 1, 1, 0); 57 img.fillAmount = 0; 58 img.raycastTarget = true; 59 } 60 61 /// <summary> 62 /// フェードアウトイン変数の中身確認 63 /// </summary> 64 /// <returns></returns> 65 public bool CheckFadeOut() 66 { 67 return fadeOut ; 68 } 69 public bool CheckFadeIn() 70 { 71 return fadeIn; 72 } 73 74 /// <summary> 75 /// フェードアウトを完了したかどうか 76 /// </summary> 77 /// <returns></returns> 78 public bool IsFadeOutComplete() 79 { 80 return compFadeOut; 81 } 82 83 /// <summary> 84 /// フェードアウト完了フラグの変更 85 /// </summary> 86 /// <returns></returns> 87 public void ChengeFadeOutComplete() 88 { 89 compFadeOut = true; 90 } 91 92 void Start() 93 { 94 img = GetComponent<Image>(); 95 if (firstFadeInComp) 96 { 97 FadeInComplete(); 98 } 99 else 100 { 101 StartFadeIn(); 102 } 103 } 104 105 106 void Update() 107 { 108 //シーン移行時の処理の重さでTime.deltaTimeが大きくなってしまうから2フレーム待つ 109 if (frameCount > 2) 110 { 111 if (fadeIn) 112 { 113 FadeInUpdate(); 114 } 115 else if (fadeOut) 116 { 117 FadeOutUpdate(); 118 } 119 } 120 ++frameCount; 121 } 122 123 //フェードイン中 124 private void FadeInUpdate() 125 { 126 if (timer < 1f) 127 { 128 img.color = new Color(1, 1, 1, 1 - timer); 129 img.fillAmount = 1 - timer; 130 } 131 else 132 { 133 FadeInComplete(); 134 } 135 timer += Time.deltaTime; 136 } 137 138 //フェードアウト中 139 private void FadeOutUpdate() 140 { 141 if (timer < 1f) 142 { 143 img.color = new Color(1, 1, 1, timer); 144 img.fillAmount = timer; 145 } 146 else 147 { 148 FadeOutComplete(); 149 } 150 timer += Time.deltaTime; 151 } 152 153 //フェードイン完了 154 private void FadeInComplete() 155 { 156 img.color = new Color(1, 1, 1, 0); 157 img.fillAmount = 0; 158 img.raycastTarget = false; 159 timer = 0.0f; 160 fadeIn = false; 161 compFadeIn = true; 162 } 163 164 //フェードアウト完了 165 private void FadeOutComplete() 166 { 167 img.color = new Color(1, 1, 1, 1); 168 img.fillAmount = 1; 169 img.raycastTarget = false; 170 timer = 0.0f; 171 fadeOut = false; 172 compFadeOut = true; 173 } 174} 175
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class title : MonoBehaviour { [Header("フェード")] public FadeImage fade; [Header("ゲームスタート時に鳴らすSE")] public AudioClip startSE; private bool firstPush = false; private bool goNextScene = false; bool checkIn; bool checkOut; bool checkOutComplete; // スタートボタンを押されたら呼ばれる public void PressSrart() { Debug.Log("Press Start"); if (!firstPush) { GManager.instance.PlaySE(startSE); // 次のシーンへ行く命令 Debug.Log("Go Next Scene!"); checkIn = fade.CheckFadeIn(); Debug.Log("FadeIn is" + checkIn); checkOut = fade.CheckFadeOut(); Debug.Log("FadeOut is" + checkOut); fade.StartFadeOut(); checkIn = fade.CheckFadeIn(); Debug.Log("FadeIn is" + checkIn); checkOut = fade.CheckFadeOut(); Debug.Log("FadeOut is" + checkOut); firstPush = true; } firstPush = false; } private void Update() { goNextScene = false; if (!goNextScene && fade.IsFadeOutComplete()) { Debug.Log("Go Scene1 again"); SceneManager.LoadScene("stage1"); goNextScene = true; } } }

試したこと

  • 再度ゲームプレイ時のタイトル画面のフェードアウトから動作しません。
  • フェードアウトが完了していないので title.cs の Update() の if (!goNextScene && fade.IsFadeOutComplete()) 以降は動いていない。
  • タイトル画面のstartボタン押下時のSE音は動作します。
  • fade.StartFadeOut(); がうまく動作していない?
  • 変数 FadeOut は再度ゲームプレイ(start再押下)時前に false になっている。

補足情報

Unity2021.3.23f1

※補足
各所スクリプトはブログ・動画を想定下さい。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

bool型のgoNextScene変数はfalseだったらシーン遷移をするためにtrueにする処理しかありません。
おそらくtrueになったままで再度この処理が走った時にtrueだったらif文に入らないとなっているのではないでしょうか?
Start関数でfalseに戻しておくことで解決すると思います。
ポーズ画面でどんな処理を行っているのか時間を止めているのかが気になります。Time.timeScaleを使っているならポーズUIがDestroyされたらTime.timeScale = 1f;に戻すという処理が必要になります。

フェードアウトフェードインは一方通行のシーン遷移で実装して、タイトルに戻るときは通常のシーン遷移を実装するのが良いと思います。一応おしゃれフェードが簡単に実装できるサイトのurlを載せておきます。こちらでは双方向のおしゃれフェードが実装出来たのを確認しました。
シーン移動時の演出
urlの本題から下の部分試しましたか?
"titleScene"はstring型なので変数(sceneName)を作り、inspectorから設定できるようにするのが良いと思います。
または、シーン名をinspectorから設定するのが面倒な場合はこれが参考になります。
【Unity】Inspector で変数にシーンファイルを設定できるようにする「SceneObject」紹介
Fade.csを開いて、以下を追加。

C#

1void ImageFill() 2{ 3 cutoutRange = 1.0f; 4 fade.Range = cutoutRange; 5}

呼び出しは、同スクリプトの関数の最初

C#

1IEnumerator FadeoutCoroutine (float time, System.Action action)

投稿2023/06/13 10:12

編集2023/06/25 14:53
isimasa

総合スコア301

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei0105

2023/06/13 13:26

ご回答ありがとうございます。 goNextScene変数はif文以前に false になるようにしています。 また、回答いただいた、Start関数でfalseに戻しておくこと、も試しましたが挙動は変わらず解決に至りませんでした。
kei0105

2023/06/13 14:19

ポーズUIがDestroyされたらTime.timeScale = 1f;に戻すようにしています。 ``` using System.Collections; using System.Collections.Generic; using UnityEngine; public class PauseScript : MonoBehaviour { [SerializeField] // ポーズした時に表示するUIのプレハブ private GameObject pauseUIPrefab; // ポーズUIのインスタンス private GameObject pauseUIInstance; // Update is called once per frame void Update() { if (Input.GetKeyDown("q")) { if (pauseUIInstance == null) { pauseUIInstance = GameObject.Instantiate(pauseUIPrefab) as GameObject; Time.timeScale = 0f; } else { Destroy(pauseUIInstance); Time.timeScale = 1f; } } } } ```
kei0105

2023/06/14 08:01

恐れ入ります。 ご回答いただいた、firstFadeInComp = true; の追記を弊環境にて試しましたが挙動は変わりせんでした。 尚、中断(ポーズ画面)→タイトル画面の間のフェードアウトフェードインは現在実装していません。
isimasa

2023/06/17 13:44 編集

お力になれず…。 フェードアウトフェードインは一方通行のシーン遷移で実装して、タイトルに戻るときは通常のシーン遷移を実装するのが良いと思います。纏めると現在のシーンがfirstFadeInComp=trueで遷移先のシーンがfirstFadeInComp=falseでないと上手く機能しない様です。その辺りSetActiveを切り替えて出来ないか試していたのですが。ほかに試したことは、firstFadeInCompのチェックの切り替えです。bool型の切り替えは自分も混乱することが多いです。int型で0か1かで判別するのが分かりやすいです。一応おしゃれフェードが簡単に実装できるサイトのurlを載せておきます。こちらでは双方向のおしゃれフェードが実装出来たのを確認しました。タイトル画面からフェードが始まってしまうのは少し違和感がありますが、色を変えたり、画像を変更して見映え良くすればオリジナルになると思いました。
kei0105

2023/06/23 11:56 編集

ご提示いただいたサイトの手段も初級者の私なりに省かれた部分なども考えつつ取り組んだ結果、タイトル画面→ステージ画面→タイトル画面へ切り替え後、”再度”ステージシーンへの切り替えもフェード込みですることができたのですが、こちらのサイトの手段は、ポーズ画面UIの任意ボタンを押したときだけ映る仕組みと喧嘩してしまうようで、ステージ画面で常時ポーズ画面UIが表示されるようになってしまいました。力不足で申し訳ないです。。。 ※追記 >>こちらのサイトの手段は、ポーズ画面UIの任意ボタンを押したときだけ映る仕組みと喧嘩してしまうようで、ステージ画面で常時ポーズ画面UIが表示されるようになってしまいました。 ->または、タイトル画面→ステージ画面はこの手段で遷移できるのですが、ステージ画面→タイトル画面はこの手段で遷移できずエラーとなります。 エラー: NullReferenceException: Object reference not set to an instance of an object ChangeTitle.PressTitle () (at Assets/Script/ChangeTitle.cs:26) ChangeTitle.cs:25~29 //フェードを掛けてからシーン遷移する fade.FadeIn(fadeTime, () => { SceneManager.LoadScene("titleScene"); });
isimasa

2023/06/26 04:49 編集

public class PauseManager : MonoBehaviour { [SerializeField, Header("ポーズした時に表示するUIのプレハブ")] // ポーズした時に表示するUIのプレハブ private GameObject pauseUIPrefab; bool paused = false; void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { pauseUIPrefab.SetActive(!pauseUIPrefab.activeSelf); if (paused) { ResumeGame(); } else { PauseGame(); } paused = !paused; } } public void PauseGame() { Time.timeScale = 0; } public void ResumeGame() { Time.timeScale = 1; } } これを試してみてください。開発が上手くいく事を願っています。
kei0105

2023/06/23 12:21

ご回答ありがとうございます。 試させていただきました結果、ステージ画面で常時ポーズ画面UIが表示される状態は変わらず、cで停止→タイトルボタン押下→fで再開、でゲーム停止状態が解かれつつ、ステージ画面→タイトル画面へ遷移しました。 ステージ画面で常時ポーズ画面UIが表示されるようになってしまったのは、私が解決のためPauseUIのプレハブをステージシーンのヒエラルキーに追加した為と思われます。 したがって、前コメント追記分が正確な現問題と思われます。
kei0105

2023/06/25 09:00

>>または、シーン名をinspectorから設定するのが面倒な場合はこれが参考になります。 ->これを参考にInspector で変数にシーンファイルを設定できるようにさせていただきましたが変わらず同じコード部分で NullReferenceException: Object reference not set to an instance of an object となりました。 PreFab、PauseUIにてChangeTitle.csを使っているのですが、inspectorにてFadeが設定できない(ドラック&ドロップを何も受け付けない)為でしょうか。
isimasa

2023/06/25 09:38

NullReferenceExceptionになる理由は2つあります。まず、インスペクターにFadeが設定できない理由は、ヒエラルキー(ゲームに表示するオブジェクトを置く場所)と、プロジェクトビュー(素材を置く場所)の違いについて理解する必要があるからです。本題ですが、1つ目の理由は、inspectorにデータがセットできず参照が出来ていないためです。これを踏まえてPauseUIのPrefabをヒエラルキーに配置します。この操作で、inspectorにFadeが設定できるようになります。2つ目の理由は、シーン移動時の演出についてのサイトの手順を踏んでいないためだと考えられます。※回答参照
kei0105

2023/06/25 10:53

恐れ入ります。挙げていただいた理由のために「ステージ画面で常時ポーズ画面UIが表示されるようになってしまったのは、私が解決のためPauseUIのプレハブをステージシーンのヒエラルキーに追加した為と思われます。」を行っていました。2つ目の理由は実施済みでした。 よって、話が戻ってしまいますが、Q,2023/06/23 20:56 編集 の 「ステージ画面で常時ポーズ画面UIが表示されるようになってしまいました。」の状態となりました。
isimasa

2023/06/26 11:53 編集

ポーズ画面でタイトルボタンを押したとき時間を再開する。ボタンにPauseManagerのResumeGame()関数を設定する。
kei0105

2023/06/27 08:52 編集

試しましたが変わらず、ステージ画面で常時ポーズ画面UIが表示されるようになっています。 PauseUIのPrefabをヒエラルキーに配置するか否かに起因していそうです。 SetActive()でPauseUIを表示非表示にできてそうなのですが、ステージ画面中、常にアクティブとなっています。
kei0105

2023/06/27 09:31

長々とご回答ありがとうございました。 挙げていただいたコードを参考に解決。 ヒエラルキーのPauseUIの入れ物を用意。 private GameObject PauseUI; Start()にてPauseUIを、 PauseUI = GameObject.Find("PauseUI"); PauseUI.SetActive(false); でスクリプトで非アクティブ。 ポーズ画面ボタン押下後PauseUIをアクティブに。    PauseUI.SetActive(true); 以下、   pauseUIPrefab.SetActive(!pauseUIPrefab.activeSelf); if (paused) { ResumeGame(); } else { PauseGame(); } paused = !paused;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問