public float[] chapterTimes;
public int[] bestStars;
public int chapterUnlocked;
public int newStarsEarned;
void Start () {
//Don't destroy this script
DontDestroyOnLoad (gameObject);
chapterTimes = new float[ chapterNumbers.Length ];
bestStars = new int[ chapterNumbers.Length ];
if ( ES2.Exists ("mmData.txt?tag=time") )
{
float[] tempData1 = ES2.LoadArray<float>( "mmData.txt?tag=time" );
foreach ( int i in tempData1 )
{
chapterTimes[i] = tempData1[i];
}
}
// Load our stars data using Easy Save.
if ( ES2.Exists ("mmData.txt?tag=star") )
{
int[] tempData2 = ES2.LoadArray<int>( "mmData.txt?tag=star" );
foreach ( int j in tempData2 )
{
bestStars[j] = tempData2[j];
}
}
}
//Example on updating the value:
public void UpdateBestTime( int name ) //name is the chapter number. To call this save we say "UpdateBestTime(1)".
{
foreach ( int i in chapterNumbers ) {
if ( chapterNumbers[i] == name ) {
// If the current score is LESS than the stored high score, then do nothing
if ( chapterTimes[i] > newBestTime ) {
//Do nothing if this isn't a new best time for the chapter
return;
}
else {
chapterTimes[i] = newBestTime; // Set this time to the new time scored in this game
ES2.Save( newBestTime,"mmData.txt?tag=time" );
Debug.Log("New High Time Value = "+chapterTimes[i]);
return;
}
}
}
Debug.LogWarning( "There is no time data" );
}
The code writes the values correctly if I use UpdateBestTime(1). But then when I go to reload the data, I get the error above.
C# is my second language - I'm trying to switch from UnityScript... so not sure if it's an error in my misunderstanding of C#
The null reference exception usually occurs when you're trying to save data which is null. Also because you're using DontDestroyOnLoad, you might want to make sure that multiple copies of the same script aren't running in the same scene.
I wasn't able to test your script at my end because some of the variables you are using seem to be missing from it (tempData1, tempData2, chapterNumbers, newBestTime). If you provide me with a version with these variables included I'll see if I can work out what's happening at my end
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SaveGame : MonoBehaviour {
#region Public Variables
// Our array of chapterNumbers. Set from Inspector.
public int[] chapterNumbers; //Chapter numbers - list them all
// Whether each name has dataValues.
public float[] chapterTimes;
public int[] bestStars;
public int[] chapterOpen;
#endregion
#region Variables
public int chapterUnlocked;
public int newStarsEarned;
public float newBestTime;
#endregion
void Start () {
//Don't destroy this script
DontDestroyOnLoad (gameObject);
chapterTimes = new float[ chapterNumbers.Length ];
bestStars = new int[ chapterNumbers.Length ];
chapterOpen = new int[ chapterNumbers.Length ];
if ( ES2.Exists ("mmData.txt?tag=time") )
{
float[] tempData1 = ES2.LoadArray<float>( "mmData.txt?tag=time" );
foreach ( int i in tempData1 )
{
chapterTimes[i] = tempData1[i];
}
}
if ( ES2.Exists ("mmData.txt?tag=star") )
{
int[] tempData2 = ES2.LoadArray<int>( "mmData.txt?tag=star");
foreach ( int j in tempData2 )
{
bestStars[j] = tempData2[j];
}
}
if ( ES2.Exists ("mmData.txt?tag=unlocked") )
{
//1 = unlocked & 0 = locked
int[] tempData3 = ES2.LoadArray<int>( "mmData.txt?tag=unlocked" );
foreach ( int k in tempData3 )
{
chapterOpen[k] = tempData3[k];
}
}
}
#region Save Data
//Item 4 Best time
public void UpdateBestTime( int name ) //name is the chapter name. To call this save we say "UpdateBestTime(1)".
{
foreach ( int i in chapterNumbers ) {
if ( chapterNumbers[i] == name ) {
// If the current score is LESS than the stored high score, then do nothing
if ( chapterTimes[i] > newBestTime ) {
//Do nothing if this isn't a new best time for the chapter
return;
}
else {
chapterTimes[i] = newBestTime; // Set this time to the new time scored in this game
ES2.Save( newBestTime,"mmData.txt?tag=time" );
Debug.Log("New High Time Value = "+chapterTimes[i]);
return;
}
}
}
Debug.LogWarning( "There is no time data" );
}
//Item 3 Best Stars
public void EarnStar( int name )
{
foreach ( int i in chapterNumbers ) {
if ( chapterNumbers[i] == name ) {
if ( bestStars[i] > newStarsEarned ) {
//Do nothing if this isn't a new best for the chapter
return;
}
else {
bestStars[i] = newStarsEarned;
ES2.Save( bestStars,"mmData.txt?tag=star");
Debug.Log("New High Time Value = "+bestStars[i]);
return;
}
}
}
Debug.LogWarning( "There is no stars data" );
}
//Item 2 Unlocked Chapters
public void UnlockedChapter( int name )
{
foreach ( int i in chapterNumbers ) {
if ( chapterNumbers[i] == name ) {
// If the current score is LESS than the stored high score, then do nothing
if ( chapterOpen[i] > chapterUnlocked ) {
return;
}
else {
chapterOpen[i] = chapterUnlocked;
ES2.Save( chapterOpen,"mmData.txt?tag=unlocked");
Debug.Log("New High Time Value = "+chapterOpen[i]);
return;
}
}
}
Debug.LogWarning( "There is no unlocked chapter" );
}
#endregion
#region Retrieve data
public float GetTimes( int name ) {
foreach (int i in chapterNumbers)
{
if( chapterNumbers[i] == name ) {
if (chapterTimes != null) {
return chapterTimes[i];
} else {
return 0;
}
}
}
Debug.LogWarning("No time data for the name provided.");
return 0;
}
public int GetStars( int name ) {
foreach (int i in chapterNumbers)
{
if( chapterNumbers[i] == name ) {
if (bestStars != null) {
return bestStars[i];
} else {
return 0;
}
}
}
Debug.LogWarning("No stars data");
return 0;
}
public int GetUnlock( int name ) {
foreach (int i in chapterNumbers)
{
if( chapterNumbers[i] == name ) {
if (chapterOpen != null) {
return chapterOpen[i];
} else {
return 0;
}
}
}
Debug.LogWarning("No unlocked chapter data");
return 0;
}
#endregion
}
Hi Joel, any luck with this? I rewrote the script in UnityScript (just in case it was my dodgy C# skills that were questionable) I pretty much copied and pasted the code from a game i have on iTunes that uses the same script, but I'm getting the same error. I'm wondering though, I've updated ES2 since my last published game and would there be a difference or the problem extending from a change to the latest version?
The main error with your code which is unrelated to Easy Save is that you're using foreach loops incorrectly. When you use a foreach loop, the value of i will equal the value of the object in the array, not the position that we're currently at in the array. I think you mean to use a for loop instead. For example, your GetStars(int name) method would look like this:
public int GetStars( int name ) {
for(int i = 0; i < chapterNumbers.Length; i++)
{
if( chapterNumbers == name ) {
if (bestStars != null) {
return bestStars;
} else {
return 0;
}
}
}
Debug.LogWarning("No stars data");
return 0;
}
Or if you wanted to do it with a foreach loop, you would need to do it like this:
public int GetStars( int name ) {
foreach (int chapterNumber in chapterNumbers)
{
if( chapterNumber == name )
{
if(bestStars != null)
return bestStars[chapterNumber];
}
}
Debug.LogWarning("No stars data");
return 0;
}
As this is unrelated to Easy Save I'm afraid I'm not allowed to provide any more help with loops. However, there's a great article here which goes into detail about the differences between for and foreach loops.
With regards to where saved data is located, by default it's located at the path specified by Application.persistentDataPath. So if you do: