How can I pass score value from one scene to another?
I\'ve tried the following:
Scene one:
void Start () {
score = 0;
There is another way:
ScriptableObject
s are basically data containers but may also implement own logic. They "live" only in the Assets
like prefabs. They can not be used to store data permanently, but they store the data during one session so they can be used to share data between Scenes ... and - something I also often needed - between Scenes and an AnimatorController
!
First you need a script similar to MonoBehaviour
s. A simple example of a ScriptableObject
might look like
// fileName is the default name when creating a new Instance
// menuName is where to find it in the context menu of Create
[CreateAssetMenu(fileName = "Data", menuName = "Examples/ExamoleScriptableObject")]
public class ExampleScriptableObject : ScriptableObject
{
public string someStringValue = "";
public CustomDataClass someCustomData = null;
// Could also implement some methods to set/read data,
// do stuff with the data like parsing between types, fileIO etc
// Especially ScriptableObjects also implement OnEnable and Awake
// so you could still fill them with permanent data via FileIO at the beginning of your app and store the data via FileIO in OnDestroy !!
}
// If you want the data to be stored permanently in the editor
// and e.g. set it via the Inspector
// your types need to be Serializable!
//
// I intentionally used a non-serializable class here to show that also
// non Serializable types can be passed between scenes
public class CustomDataClass
{
public int example;
public Vector3 custom;
public Dictionary data;
}
You can create instances of ScriptableObject
either via script
var scriptableObject = ScriptableObject.CreateInstance();
or to make things easier use the [CreateAssetMenu] as shown in the example above.
As this created ScriptabeObject
instance lives in the Assets
it is not bound to a scene and can therefore be referenced everywhere!
This when you want to share the data between two Scenes or also e.g. the Scene and an AnimatorController
all you need to do is reference this ScriptableObject
instance in both.
I often use e.g. one component to fill the data like
public class ExampleWriter : MonoBehaviour
{
// Here you drag in the ScriptableObject instance via the Inspector in Unity
[SerializeField] private ExampleScriptableObject example;
public void StoreData(string someString, int someInt, Vector3 someVector, List someDatas)
{
example.someStringValue = someString;
example.someCustomData = new CustomDataClass
{
example = someInt;
custom = someVector;
data = new Dictionary();
};
for(var i = 0; i < someDatas.Count; i++)
{
example.someCustomData.data.Add(i, someDatas[i]);
}
}
}
So after you have written and stored your required data into this ExampleScriptableObject
instance every other class in any Scene or AnimatorController
or also other ScriptableObject
s can read this data on just the same way:
public class ExmpleConsumer : MonoBehaviour
{
// Here you drag in the same ScriptableObject instance via the Inspector in Unity
[SerializeField] private ExampleScriptableObject example;
public void ExampleLog()
{
Debug.Log($"string: {example.someString}", this);
Debug.Log($"int: {example.someCustomData.example}", this);
Debug.Log($"vector: {example.someCustomData.custom}", this);
Debug.Log($"data: There are {example.someCustomData.data.Count} entries in data.", this);
}
}
As said the changes in a ScriptableObject
itself are only in the Unity Editor really persistent.
In a build they are only persistent during the same session.
Therefore of needed I often combine the session persistence with some FileIO for loading and deserializing the values once at session begin (or whenever needed) from the hard drive and serialize and store them to a file once on session end (OnApplicationQuit
) or whenever needed.