Error I can't work out

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
Locked
Oceans
Posts: 7
Joined: Fri Jan 24, 2014 12:04 am

Error I can't work out

Post by Oceans »

Hi

I'm not sure what I'm doing wrong, but I'm getting the following error pop up on loading the game:
Couldn't extract exception string from exception (another exception of class 'NullReferenceException' was thrown while processing the stack trace)
And then an empty error underneath it (i.e the red exclamation mark but no text)


This is what I'm doing....

On my save game script I have the following:

Code: Select all

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#

Thanks!
User avatar
Joel
Moodkie Staff
Posts: 4852
Joined: Wed Nov 07, 2012 10:32 pm

Re: Error I can't work out

Post by Joel »

Hi there,

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 :)

All the best,
Joel
Oceans
Posts: 7
Joined: Fri Jan 24, 2014 12:04 am

Re: Error I can't work out

Post by Oceans »

Thanks Joel :)

Re the "DontDestroy"... i only have the one scene running at the moment - that line is there for future use once I activate other game scenes.

Also, where on my Mac to I locate the save files so I can delete them during testing?

Here is the full script

Code: Select all

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
}

Oceans
Posts: 7
Joined: Fri Jan 24, 2014 12:04 am

Re: Error I can't work out

Post by Oceans »

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?
User avatar
Joel
Moodkie Staff
Posts: 4852
Joined: Wed Nov 07, 2012 10:32 pm

Re: Error I can't work out

Post by Joel »

Hi there,

I've found some errors in your code, some of which aren't related to Easy Save. The ones which are related to Easy Save are as follows:
  1. You're saving newBestTime when you're meant to be saving chapterTimes. So the line:
    ES2.Save( newBestTime,"mmData.txt?tag=time" );
    Should be:
    ES2.Save( chapterTimes,"mmData.txt?tag=time" );
  2. This is more of a suggestion than an error. When you load, you don't need the for loop to load the data back into the array. You can simply do:
    if ( ES2.Exists ("mmData.txt?tag=time") ) 
    {
    	chapterTimes = ES2.LoadArray<float>( "mmData.txt?tag=time" );
    }
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:

Debug.Log(Application.persistentDataPath);


… it'll log the path to the console for you.

Hope this helps!

All the best,
Joel
Oceans
Posts: 7
Joined: Fri Jan 24, 2014 12:04 am

Re: Error I can't work out

Post by Oceans »

Thanks Joel - Got it all working now.

I have no idea why, but I had in my head that you couldn't use for loops in C# and had to use foreach instead. No idea why LOL!

Thank so much
Locked