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

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

ただいまの
回答率

87.77%

Unity シーンの移動で意図した通りに切り替わらない。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 598

score 1

閲覧いただきありがとうございます。

Unity初心者です。
ググってやってみたり、参考URLで確認したり、いろいろ試してみましたが解決できなかったので、質問いたしました。
初めての質問なので、説明不足などありましたらごめんなさい。

前提

・タイトルシーン

ボタン2つ設定しており、それぞれボタンを押すと、Canvasで作成した
・遊び方画面(HowToPlay) ・・・最初の画面(TitleObject)に戻るボタンを設置)
・難易度選択画面(StageSelect)・・・ 選択した難易度のシーンに移動するボタンと、最初の画面(TitleObject)に戻るボタンを設置

が表示されるようになっています。

・ゲームシーン(Easy)・・・現段階で作成した難易度はEasyのみとなっています。 

クリアorゲームオーバーになると同じくCanvasで作成した
・クリア画面(ClearObject)・・・リトライするボタンとタイトルシーンに戻るボタンを設置)
・ゲームオーバー画面(GameOver)・・・リトライするボタンとタイトルシーンに戻るボタンを設置)

が表示されます。

実現したいこと

  1. タイトルシーンの難易度選択をクリック → 難易度選択画面 → Easy → クリア画面 or ゲームオーバー画面 → タイトルシーン...

  2. クリア画面 or ゲームオーバー画面でリトライボタンをクリック → ゲームをプレイして、再びクリア画面 or ゲームオーバー画面を表示 → リトライボタンで再びゲームプレイ...

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

実現したいことの内容に関して、

・1で難易度選択画面からボタンを押して、Easyに移動すると、ゲームオーバー画面が表示された状態で読み込まれます。おそらくEasySceneに移動したときに、lifeが0になり、ゲームオーバーのフラグがfalseからtrueになってしまっていること(下記コード参照)が一つの原因かと考えられます。
また、このときリトライするボタンとタイトルシーンに戻るボタンを押しても反応しません。

・2でリトライ後にもう一回ゲームをプレイした後に、Titleに戻るボタンとリトライボタンが反応せず、それぞれ対応するシーンと画面に移動することができません。2回目以降OnClickがうまく機能してくれていないようです。

参考にしたURLはこちらです。
Unity入門【初心者でもゼロから作れるUnity使い方講座】
https://dkrevel.com/makegame-beginner/

該当のソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.EventSystems;

public class GameManager : MonoBehaviour
{
    #region//インスペクターで設定
    [Header("GameManager")]public static GameManager instance = null;
    [Header("ライフ")] public int life;
    [Header("Target1がゴールした数")] public int target1CountScore;
    [Header("Target2がゴールした数")] public int target2CountScore;
    [Header("クリア変数")] public bool isClear = false;
    [Header("ゲームオーバー変数")] public bool isGameover = false;
    [Header("TitleObject")] public GameObject TitleObject;
    [Header("HowToPlay")] public GameObject HowToPlay;
    [Header("StageSelect")] public GameObject StageSelect;
    #endregion

    #region//プライベート変数
    private Rigidbody2D rb;
    private bool isHowToPlay = false;
    private bool isStageSelect = false;
   // private bool isEasyScene;
    #endregion
    // Start is called before the first frame update

    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        else
        {
            Destroy(this.gameObject);
        }

       /* DontDestroyOnLoad(TitleObject);
        DontDestroyOnLoad(HowToPlay);
        DontDestroyOnLoad(StageSelect);*/

    }
    void Start()
    {   
        //タイトルシーンが読み込まれた時の状態
        TitleObject.SetActive(true);
        HowToPlay.SetActive(false);
        StageSelect.SetActive(false);

        rb = GetComponent<Rigidbody2D>();

        //Easyを読み込んだ時のlife
        if (SceneManager.GetActiveScene().name == "Easy")
        {
            life = 5;
        } /*else if (SceneManager.GetActiveScene().name == "Normal")
        {
            LoadNormalScene();
        }
        else if (SceneManager.GetActiveScene().name == "Hard")
        {
            LoadHardScene();
        }*/

    }

    // Update is called once per frame
    void Update()
    {

    }

    #region//リトライ
    public void RetryGame()
    {
        target1CountScore = 0;
        target2CountScore = 0;
        isClear = false;
        isGameover = false;
        if(SceneManager.GetActiveScene().name == "Easy")
        {
            LoadEasyScene();
            life = 5;
        } /*else if (SceneManager.GetActiveScene().name == "Normal")
        {
            LoadNormalScene();
        }
        else if (SceneManager.GetActiveScene().name == "Hard")
        {
            LoadHardScene();
        }*/
    }
    #endregion

    #region//タイトルシーンに移動
    public void LoadTitleScene()
    {
        if (SceneManager.GetActiveScene().name == "Easy")
        {
            SceneManager.LoadScene("TitleScene");
        }

    }
    #endregion

    #region//Easy読み込み
    public void LoadEasyScene()
    {

        SceneManager.LoadScene("Easy");
        if (isStageSelect)
        {
            isStageSelect = false;
        }
    }
    #endregion

    /*public void LoadNormalScene()
    {
        SceneManager.LoadScene("Normal");
    }

    public void LoadHardScene()
    {
        SceneManager.LoadScene("Hard");
    }*/

    #region//StageSelect画面に移動
    public void GoStageSelect()
    {
        TitleObject.SetActive(false);
        isStageSelect = true;
        StageSelect.SetActive(true);
    }
    #endregion

    #region//HowToPlay画面に移動
    public void GoHowToPlay()
    {
        TitleObject.SetActive(false);
        isHowToPlay = true;
        HowToPlay.SetActive(true);
    }
    #endregion

    #region//タイトルシーンの最初の画面に移動
    public void GoTitleObject()
    {
        TitleObject.SetActive(true);
        if (isHowToPlay)
        {
            isHowToPlay = false;
            HowToPlay.SetActive(false);
        } else if (isStageSelect)
        {
            isStageSelect = false;
            StageSelect.SetActive(false);
        } 
    }
    #endregion


}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LifeTextScript : MonoBehaviour
{
    #region//インスペクターで設定
    public GameObject GameOver;
    #endregion

    #region//プライベート変数
    private Text lifeText;
    private int oldLife;
    #endregion

    // Start is called before the first frame update
    void Start()
    {   
        lifeText = GetComponent<Text>();
        GameOver.SetActive(false);

        if(GameManager.instance != null)
        {
            lifeText.text = "Life " + GameManager.instance.life;
        }
        else
        {
            Destroy(this);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if(oldLife != GameManager.instance.life)
        {
            lifeText.text = "Life " + GameManager.instance.life;
            oldLife = GameManager.instance.life;
        } else if(GameManager.instance.life <=0)
        {           
            lifeText.text = "Life 0";
            GameOver.SetActive(true);
            GameManager.instance.isGameover = true;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Target1GoalScript : MonoBehaviour
{
    #region//インスペクターで設定
    [Header("ゴールするまでの数")]public int Target1Score;
    [Header("Target1をカウントする")] public int Target1Count;
    [Header("Target2をカウントする")] public int Target2Count;
    [Header("ClearObject")] public GameObject ClearObject;    
    #endregion

    // Start is called before the first frame update
    void Start()
    {

        ClearObject.SetActive(false);
    }

    // Update is called once per frame
    void Update()
    {

    }

    #region//ゴールした時の処理
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.CompareTag("Burden"))
        {
            //Debug.Log("Target1Goal");
            Destroy(collision.gameObject);
            GameManager.instance.target1CountScore += Target1Score;
            if(GameManager.instance.target1CountScore >= Target1Count && GameManager.instance.target2CountScore >= Target2Count)
            {               
               //Debug.Log("12Ok");
                ClearObject.SetActive(true);
                GameManager.instance.isClear = true;

            } 
        } 
    }
    #endregion
}

*Targe1GoalScriptの他にほぼ同じ内容のTarget2GoalScriptもあります。

・ButtonのOnClick()をすべて設定してあることは確認済みです。
・Build Settingの方もTitleSceneとEasyが入っていました。
・Easyから読み込んでTitleSceneに戻った時もHowToPlayやStageSelectに移動できなくなっていました。

初心者なので拙いコードで申し訳ありませんが、解決方法や、改善点などよろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Windows 10
Unity 2020.4.1f1使用

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • sakura_hana

    2020/10/23 09:50

    Debug.Logを各所に仕込んでどうなっているか確認してください。(特に「isStageSelect」等のフラグ類)
    「ボタンがクリックできない(=OnClickに設定されたメソッドが呼ばれない)」のか、「クリックはできてOnClickに設定されたメソッドは呼ばれるがその中身が実行されない」のかでは考えられる原因と対策が異なるのでそこをはっきりさせてください。

    キャンセル

  • Aruku

    2020/10/23 17:46 編集

    ご回答ありがとうございます。
    Debug.Logを差し込んだところ、OnClickに設定したメソッドそのものが呼び出されていないようでした。

    キャンセル

回答 2

check解決した方法

0

遅くなりました。

もう一回自分で調べたりしながら、以下の方法でなんとか解決することができました。
Normal, Hardも作りましたが、それぞれのシーン分岐もできました。
みなさんありがとうございました!

  1. タイトルシーンに新たにカラのTitleSceneGameObjectCtrlを作る。
  2. 以下のスクリプトを作成 

参考URL
https://xr-hub.com/archives/11782

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TitleSceneGameObjectCtrlScript : MonoBehaviour
{
    [SerializeField] GameObject TitleObject;
    [SerializeField] GameObject HowToPlay;
    [SerializeField] GameObject StageSelect;   

    // Start is called before the first frame update
    void Start()
    {
        GoBackToTitle();
    }

    // Update is called once per frame
    void Update()
    {

    }

    #region//StageSelect画面に移動
    public void GoStageSelect()
    {
        StageSelect.SetActive(true);
        HowToPlay.SetActive(false);
        TitleObject.SetActive(false);
    }
    #endregion

    #region//HowToPlay画面に移動
    public void GoHowToPlay()
    {   
        HowToPlay.SetActive(true);
        StageSelect.SetActive(false);
        TitleObject.SetActive(false);

    }
    #endregion

    public void GoBackToTitle()
    {
        TitleObject.SetActive(true);
        HowToPlay.SetActive(false);
        StageSelect.SetActive(false);
    }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

症状からおそらくとしか言えないのですが
とりあえずライフ5のときに問題ないか確認のために初期値をいれて試してみてください。これでいきなりGameOverにならないと思います。

 [Header("ライフ")] public int life = 5;


つぎに各所にある
if (SceneManager.GetActiveScene().name == "Easy")
の分岐に入れてないように思えます。
とりあえずはStartメソッドでDebug.logで通っているか試して見てください。
通らなかったらシーンの名前の比較が上手くいっていないことになります。

   void Start()
    {   
        //タイトルシーンが読み込まれた時の状態
        TitleObject.SetActive(true);
        HowToPlay.SetActive(false);
        StageSelect.SetActive(false);

        rb = GetComponent<Rigidbody2D>();

        //Easyを読み込んだ時のlife
        if (SceneManager.GetActiveScene().name == "Easy")
        {
       Debug.log("Set Life");
            life = 5;
        } 

あとはリトライメソッドでライフを5にしてからシーンをロードしないとダメそうに見えます。

 #region//リトライ
    public void RetryGame()
    {
        target1CountScore = 0;
        target2CountScore = 0;
        isClear = false;
        isGameover = false;
        if(SceneManager.GetActiveScene().name == "Easy")
        {
       life = 5;
            LoadEasyScene();

    } 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/10/25 18:57

    ご回答ありがとうございます。

    まず、いきなりGameOverになってしまう件です、ライフの初期値を入れてみたところ、無事GameOverにならずシーン遷移ができました!ありがとうございました。

    次に、if (SceneManager.GetActiveScene().name == "Easy")の分岐についてですが、上記の通り試してみたところ、TitleScene→Easyに切り替わるときに、Debug.Logが表示されておりませんでした。

    また、リトライメソッド中で、ライフを入れてみたのですが、状況に変化は見られませんでした。

    質問への情報追記、修正にも書きましたが、おそらくOnClickに入っているメソッドそのものが呼び出されていないようです。

    キャンセル

  • 2020/10/25 22:41 編集

    Debug.logが表示されないのなら

    if(SceneManager.GetActiveScene().name == "Easy"){
    //ここの処理が実行されていない
    // ここのLife設定やシーンロードの処理が実行されていない
    }
    のように見えます。

    OnClickにメソッド設定されているのならメソッド自体は実行されているはずです。気になるならメソッドを違うものに変えて設定してためしてみてください。

    public void ClickTest(){
    Debug.log(" Click Test ");
    }

    あとEasyのみでテストしているのであればこの分岐は今は不要だと思うので
    すべてコメントアウトして試してみてはいかがでしょうか?

    (リトライメソッド)
    //Easyを読み込んだ時のlife
    if(SceneManager.GetActiveScene().name == "Easy")
    {
       life = 5;
    LoadEasyScene();

    }

    上記を以下だけのコードにして試してみてください。
     life = 5;
    LoadEasyScene();

    他にも  if (SceneManager.GetActiveScene().name == "Easy") を記述している部分があるので全て同様に。

    キャンセル

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

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る