iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
自我挑戰組

用unity製作2DRPG雛形-沒有大野狼的小紅帽系列 第 15

15.unity變數傳遞(下)場景間數據傳遞

上一篇提到改變其他腳本的全域變數
這一篇針對場景間保留數據的方法作探討。

在unity換場景(scene)時,會重新加載腳本,不會保留在前一個場景中所做的改變。
所以,依照原本將變數存放在一般class的做法,會因為重新加載場景而遺失資料。因此,小紅帽撿5幾顆蘋果,換場景到奶奶家蘋果就會歸零。

如果希望在換場景的時候,想保留道具紀錄,應該怎麼做呢?

1. Static class,用靜態類別來實現。
供靜態類別須符合︰
- 僅包含靜態成員。 (全部都要static)
- 無法具現化。(無法instantiated)
- 已密封。(要封裝好)
- 不能包含執行個體建構函式。(不能使用建構式)

靜態類別,讓整個遊戲都能使用這個類別裏面的變數。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public static class ScoreBoard // 不能繼承MonoBehaviour,不能掛在物件上面
    {
      public static int score;

      static ScoreBoard(){    //初始化,開啟應用程式時會執行一遍。
      score=0;          //初始化靜態類別成員
      }
    }

※此靜態類別不能掛在物件上面,因為沒有繼承MonoBehaviour,該腳本存在Assets就會執行到唷。

在其他腳本調用變數(腳本名.變數)

    private int s = ScoreBoard.score; //將全域變數存下來
    ScoreBoard.score++; //直接修改全域變數
    s++;  //修改存下來的全域變數值
    ScoreBoard.score=s; //存回全域變數

2. DontDestroyOnLoad的使用
直接從根本上解決問題,不要把角色刪掉就好了!
但是這樣做會有一個問題,如果回到原本的場景,場景仍會加載,再次創一個角色。
所以在使用DontDestroyOnLoad的時候,要注意不要讓角色重複生成。

官方舉例:背景音樂重複使用(播放不中斷)

DontDestroy.cs

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

public class DontDestroy : MonoBehaviour
{
    void Awake()
    {
		//用陣列取得所有tag"music"物件,希望只有objs[0]一項,objs.Length=1
        GameObject[] objs = GameObject.FindGameObjectsWithTag("music");
				
		//如果陣列不只一項(第二次加載時重複新增該物件)
        if (objs.Length > 1)
        {
			//就刪除該次加載場景建立物件
            Destroy(this.gameObject);
        }

		//如果陣列只有一項,就不要刪掉這個物件(首次加載)
        DontDestroyOnLoad(this.gameObject);
    }
}

以上可在場景間傳遞變數,但仍然不能保存遊戲進度,如果關閉應用程式再次開啟,數據會刷新。

更多方法請參考教學


上一篇
14.unity變數傳遞(上)記分板
下一篇
16.unity介面按鈕
系列文
用unity製作2DRPG雛形-沒有大野狼的小紅帽30

尚未有邦友留言

立即登入留言