如何在 Unity 中的场景之间传递数据(和引用)

A:

How can I pass score value from one scene to another?
如何将分数值从一个场景传递到另一个场景?

I’ve tried the following:
我尝试过以下方法:

Scene one:  场景一:

void Start () {
    score = 0;
    updateScoreView ();
    StartCoroutine (DelayLoadlevel(20));
}

public void updateScoreView(){
    score_text.text = "The Score: "+ score;
}

public void AddNewScore(int NewscoreValue){
    score = score + NewscoreValue;
    updateScoreView ();
}

IEnumerator DelayLoadlevel(float seconds){        
    yield return new WaitForSeconds(10);
    secondsLeft = seconds;
    loadingStart = true;
    do {        
        yield return new WaitForSeconds(1);
    } while(--secondsLeft >0);

    // here I should store my last score before move to level two
    PlayerPrefs.SetInt ("player_score", score);
    Application.LoadLevel (2);
}

Scene two:  场景二:

public Text score_text;
private int old_score;

// Use this for initialization
void Start () {    
    old_score = PlayerPrefs.GetInt ("player_score");
    score_text.text = "new score" + old_score.ToString ();      
}

but nothing displayed on screen, and there’s no error.
但屏幕上没有显示任何内容,也没有错误。

Is this the correct way to pass data ?
这是传递数据的正确方法吗?

I am using Unity 5 free edition, develop game for Gear VR (meaning the game will run in android devices).
我正在使用 Unity 5 免费版,为 Gear VR 开发游戏(意味着游戏将在 Android 设备上运行)。

Any suggestion?   有什么建议吗?

Q:

There are many ways to do this but the solution to this depends on the type of data you want to pass between scenes. Components/Scripts and GameObjects are destroyed when new scene is loaded and even when marked as static.
有很多方法可以做到这一点,但解决方案取决于您想要在场景之间传递的数据类型。当加载新场景时,甚至标记为static时,组件/脚本和游戏对象都会被销毁。

In this answer you can find
在这个答案中你可以找到

  1. Use the static keyword
    使用static关键字

1. Use the static keyword.
1.使用static关键字。

Use this method if the variable to pass to the next scene is not a component, does not inherit from MonoBehaviour and is not a GameObject then make the variable to be static.
如果要传递到下一个场景的变量不是组件、不是MonoBehaviour继承并且不是 GameObject,请使用此方法,然后将该变量设置为static 。

Built-in primitive data types such as intboolstringfloatdouble. All those variables can be made a static variable.
内置原始数据类型,例如int 、 bool 、 string 、 float 、 double 。所有这些变量都可以成为static变量。

Example of built-in primitive data types that can be marked as static:
可以标记为 static 的内置原始数据类型的示例

static int counter = 0;
static bool enableAudio = 0;
static float timer = 100;

These should work without problems.
这些应该可以正常工作。


Example of Objects that can be marked as static:
可以标记为 static 的对象示例

public class MyTestScriptNoMonoBehaviour
{

}

then  然后

static MyTestScriptNoMonoBehaviour testScriptNoMono;

void Start()
{
    testScriptNoMono = new MyTestScriptNoMonoBehaviour();
}

Notice that the class does not inherit from MonoBehaviour. This should work.
请注意,该类不是从MonoBehaviour继承的。这应该有效。


Example of Objects that cannot be marked as static:
不能标记为 static 的对象示例

Anything that inherits from ObjectComponent or GameObject will not work.
任何继承自Object 、 ComponentGameObject的东西都不起作用

1A.Anything that inherits from MonoBehaviour
1A .任何继承自MonoBehaviour的东西

public class MyTestScript : MonoBehaviour 
{

}

then  然后

static MyTestScript testScript;

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

This will not work because it inherits from MonoBehaviour.
不起作用,因为它继承自MonoBehaviour 。

1B.All GameObject:
1B . GameObject :

static GameObject obj;

void Start()
{
    obj = new GameObject("My Object");
}  

This will not work either because it is a GameObject and GameObject inherit from an Object.
这也不起作用,因为它是GameObject并且GameObject继承自Object 。

Unity will always destroy its Object even if they are declared with the static keyword.
Unity 将始终销毁其Object即使它们是使用static关键字声明的。

See #2 for a workaround.
请参阅#2了解解决方法。


2.Use the DontDestroyOnLoad function.
2.使用DontDestroyOnLoad函数

You only need to use this if the data to keep or pass to the next scene inherits from ObjectComponent or is a GameObject. This solves the problem described in 1A and 1B.
仅当要保留或传递到下一个场景的数据继承自Object 、 Component或者是GameObject时,才需要使用此选项。这解决了图1A图1B中描述的问题。

You can use it to make this GameObject not to destroy when scene unloads:
您可以使用它来使该游戏对象在场景卸载时不被破坏:

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

You can even use it with the static keyword solve problem from 1A and 1B:
您甚至可以将它与static关键字一起使用来解决1A1B中的问题:

public class MyTestScript : MonoBehaviour 
{

}

then  然后

static MyTestScript testScript;

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

The testScript variable will now be preserved when new scene loads.
现在,当新场景加载时,将保留testScript变量。

3.Save to local storage then load during next scene.
3.保存到本地存储,然后在下一个场景中加载。

This method should be used when this is a game data that must be preserved when the game is closed and reopened. Example of this is the player high-score, the game settings such as music volume, objects locations, joystick profile data and so on.
当这是关闭并重新打开游戏时必须保留的游戏数据时,应使用此方法。例如,玩家的高分、游戏设置(例如音乐音量、物体位置、操纵杆配置文件数据等)。

Thare are two ways to save this:
有两种方法可以保存它:

3A.Use the PlayerPrefs API.
3A . PlayerPrefs API。

Use if you have just few variables to save. Let’s say player score:
如果您只有很少的变量需要保存,请使用。假设玩家得分:

int playerScore = 80;

And we want to save playerScore:
我们想要保存playerScore:

Save the score in the OnDisable function
将分数保存在OnDisable函数中

void OnDisable()
{
    PlayerPrefs.SetInt("score", playerScore);
}

Load it in the OnEnable function
OnEnable函数中加载它

void OnEnable()
{
    playerScore  =  PlayerPrefs.GetInt("score");
}

3B.Serialize the data to json, xml or binaray form then save using one of the C# file API such as File.WriteAllBytes and File.ReadAllBytes to save and load files.
3B .将数据序列化为 json、xml 或 binaray 形式,然后使用 C# 文件 API 之一(例如File.WriteAllBytesFile.ReadAllBytes保存和加载文件。

Use this method if there are many variables to save.
如果要保存的变量很多,请使用此方法。

General, you need to create a class that does not inherit from MonoBehaviour. This class you should use to hold your game data so that in can be easily serialized or de-serialized.
一般来说,您需要创建一个不继承自MonoBehaviour的类。您应该使用此类来保存游戏数据,以便可以轻松地序列化或反序列化。

Example of data to save:
要保存的数据示例:

[Serializable]
public class PlayerInfo
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
    public int life = 0;
    public float highScore = 0;
}

Grab the DataSaver class which is a wrapper over File.WriteAllBytes and File.ReadAllBytes that makes saving data easier from this post.
这篇文章中获取DataSaver类,它是File.WriteAllBytesFile.ReadAllBytes的包装器,可以更轻松地保存数据。

Create new instance:  创建新实例:

PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;

Save data from PlayerInfo to a file named “players”:
将 PlayerInfo 中的数据保存到名为“players”的文件中:

DataSaver.saveData(saveData, "players");

Load data from a file named “players”:
从名为“players”的文件加载数据:

PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");
912sy.com下载资源均来源于网络,仅供学习和参考使用,版权归原作者所有,勿作商业用途,请在下载后24小时之内自觉删除。
本站发布的内容若无意中侵犯到您的权益,请联系我们,本站将在一个工作日内删除。如遇到任何问题请联系客服QQ:2385367137
912sy » 如何在 Unity 中的场景之间传递数据(和引用)