2023年10月5日 星期四

【筆記】- Unity Scene (場景)間的參數傳遞(實測)

 (1) 先在 Scene 「A」的 MainCamera 平行的階層下方建一個「RootGameObject(自訂名稱)」的空物件,然後,建立一個「RootGameObject.cs」的 C# Script,並將該 RootGameObject.cs 拉到 RootGameObject 物件裡.


正確的 RootGameObject 物件擺置:



RootGameObject.cs 內容如下:


using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class RootGameObject : MonoBehaviour

{

    public static RootGameObject Instance { get; private set; }

    public int param { get; set; } // 參數


    void Awake() {

        if(Instance == null) {

            Instance = this;

            DontDestroyOnLoad(gameObject); // 保留 Scene 物件

        } else {

            gameObject.SetActive(false);

            Destroy(gameObject);

        }

    }

}


(2) 然後在 Scene「A」載入 Scene「B」前,設定要給予的參數值 param.範例如下:


using UnityEngine;

using UnityEngine.UI;

using UnityEngine.SceneManagement;


public class MutiScenseBtnClickAction : MonoBehaviour

{

    private void Awake() {

        GetComponent<Button>().onClick.AddListener(OnClickCallBack);

    }


    private void OnClickCallBack() {

        if(gameObject.tag == "SelectSixGetOneButton") {

            //Debug.Log("SelectSixGetOneButton OnClick !!!");

            RootGameObject.Instance.param = 1; // 參數

            SceneManager.LoadScene("ShakeViewScene");

        }

        if(gameObject.tag == "SelectSixGetThreeButton") {

            //Debug.Log("SelectSixGetThreeButton OnClick !!!");

            RootGameObject.Instance.param = 2; // 參數

            SceneManager.LoadScene("ShakeViewScene");

        }

        if(gameObject.tag == "SelectThreeGetThreeButton") {

            //Debug.Log("SelectThreeGetThreeButton OnClick !!!");

            RootGameObject.Instance.param = 3; // 參數

            SceneManager.LoadScene("ShakeViewScene");

        }

        if(gameObject.tag == "MutiReturnButton") {

            //Debug.Log("MutiReturnButton OnClick !!!");

            RootGameObject.Instance.param = 0; // 參數

            SceneManager.LoadScene("MainScene");

        }

    }

}


(3) 載入 Scene「B」後,就可在 Scene「B」內取用原 Scene「A」內設定的 param 參數.範例如下:


public class ShakeVieweScene : MonoBehaviour

{

    private string _statusNow;


void Start()

    {

        if(RootGameObject.Instance == null) {

            _choiceAttribute = 2;

        } else {

            _choiceAttribute = RootGameObject.Instance.param;  

        }

}

}


(PS) 勿將 MainCamera 放到 RootGameObject 之下,因為 MainCamera 會自動包含一個 Audio Listener,若是將 MainCamera 包入 RootGameObject 內,載載入另一個 Scene 時,會出現「Audio Listener」超過 2 個的錯誤訊息,並會終止程式執行. 若在 Unity 內執行時在 Hierarchy 內搜尋 Audio Listener,則會出現 2 個以上的 Audio Listener,而 Unity 僅允許同時執行 1 個 Audio Listener!在本例中會分別在 MainScene 與 DontDestroyOnLoad 中的 MainCamera 中出現「Audio Listener」的錯誤訊息:

There are 2 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene.




沒有留言:

張貼留言