上一篇提到改變其他腳本的全域變數
這一篇針對場景間保留數據的方法作探討。
在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);
}
}
以上可在場景間傳遞變數,但仍然不能保存遊戲進度,如果關閉應用程式再次開啟,數據會刷新。
更多方法請參考教學