Attempting To Save With Automatic Save Structure

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
General Jewel
Posts: 10
Joined: Tue Jun 16, 2015 4:24 pm

Attempting To Save With Automatic Save Structure

Post by General Jewel »

Using this tutorial attempting to save and load objects run time objects.

http://www.moodkie.com/forum/viewtopic.php?f=4&t=522
1.Add a UniqueObjectManager and UniqueSaveManager script to the scene.
2.Add a UniqueID script to each of the prefabs you want to create at runtime and set the UniqueID's 'prefabName' field to the name of this prefab.
3.Add the prefabs to the UniqueObjectManager's 'prefab' field.
4.Add a UniqueID script to all of the scene objects you want to save, or might have child objects which need saving.
5.Add these scene objects to the scene objects array in the UniqueObjectManager
Completed these steps but now using a different script trying to spawn objects in run time

Code: Select all

using UnityEngine;
using System.Collections;

public class CreateObject : MonoBehaviour {

	
	void OnMouseDown() {

		    UniqueObjectManager.InstantiatePrefab(string Block);
	
		}
	}
getting this error. Block is the name of the prefab attempting to save which name I put in the UniqueID script. I presume referencing them all wrong due to my lack of knowledge.
Assets/BuildBox/Scripts/CreateObject.cs(12,70): error CS1525: Unexpected symbol `Block', expecting `.'

Also I wish to delete objects on the fly too there is a small delete icon players can drag objects to destroy individual objects

Code: Select all

using UnityEngine;
using System.Collections;

public class DestroyBuildObjects : MonoBehaviour
{

		
		void OnTriggerEnter (Collider col)
		{
				if (col.gameObject.tag == "EditorTouch") {


				UniqueObjectManager.DestroyObject(GameObject Block);

			       

				}
		}
}
getting this error
Assets/BuildBox/Scripts/DestroyScripts/DestroyBuildObjects.cs(13,74): error CS1525: Unexpected symbol `Block'

This tutorial seems ideal as wish to save whatever objects spawned by the players and saved when they exit the scene and also if they delete the objects the save is updated to show that. Please advise thank you.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Attempting To Save With Automatic Save Structure

Post by Joel »

Hi there,

The error you're getting is a programming error. You shouldn't specify the type name in parameters, and strings should be surrounded by quotation marks. i.e.
UniqueObjectManager.InstantiatePrefab("Block");
Unfortunately we can only help with Easy Save issues and not general programming questions, so I strongly advise you ask on the Unity forums for more information on calling methods in C#.

All the best,
Joel
General Jewel
Posts: 10
Joined: Tue Jun 16, 2015 4:24 pm

Re: Attempting To Save With Automatic Save Structure

Post by General Jewel »

Thank you for your response. Your support is amazing. I have played around with the Easy Save asset and managed to save simple things that are in the scene already. Also implemented the instantiate prefab example and it does save as well. Although I was wondering if there is a very simple way to do it that will save supported formats. I was thinking something like this

Code: Select all

using UnityEngine;
using System.Collections;

public class SaveScript : MonoBehaviour
{

		void  OnApplicationQuit ()
		{

				GameObject[] Player;
	
				Player = GameObject.FindGameObjectsWithTag ("Player");

				foreach (var i in Player)

			    ES2.Save(transform.position, "myFile.txt?tag=myPosition");  (just a example I want to save more than just transform but with colliders, components etc. basically the saving instantiated prefab example does what I want as it saves everything I need. ) 

	
		}
	
	
}

Code: Select all

using UnityEngine;
using System.Collections;

public class LoadScript : MonoBehaviour
{

		void  Start ()
		{

		// Load the position we saved and assign it to this GameObject.
		transform.position = ES2.Load<Vector3>("myFile.txt?tag=myPosition");  (just a example I want to load what I saved before more than just the transform the entire prefab. ) 


	
		}
	
	
}
Will this work? thank you.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Attempting To Save With Automatic Save Structure

Post by Joel »

Hi there,

If I understand you correctly, if you want to save other Components on a GameObject in the Saving, Loading and Instantiating Prefabs example, you should be able to do something like this in the part of the example where the ES2.Save calls are made:
for(int i=0; i<createdPrefabs.Count; i++)
{
    // Append the name of the type of data to the tag (i.e. transform) so that we can uniquely identify it.
    ES2.Save(createdPrefabs.transform, saveFile+"?tag=transform"+i);
    ES2.Save(createdPrefabs.GetComponent<SphereCollider>(), saveFile+"?tag=spherecollider"+i);
    // Add an ES2.Save call for each Component you need to save.
}


And then in the examples where the ES2.Load calls are made, you would simply do this:

for(int i=0; i<prefabCount; i++)
{
    // Create a new instance of the prefab.
    GameObject newPrefab = Instantiate (prefab) as GameObject;
           
    // Load the Transform for that particular prefab using the
    // ES2 self-assigning Load.
    ES2.Load<Transform>(saveFile+"?tag=transform"+i, newPrefab.transform);
    ES2.Load<SphereCollider>(saveFile+"?tag=spherecollider"+i, newPrefab.GetComponent<SphereCollider>() );
          
    // Add the GameObject to the list.
    createdPrefabs.Add(newPrefab);
 }


There's currently no way to automatically save all Components on an object, and to be honest you probably wouldn't need to, as you should only save the things which change. For example, unless you're procedurally modifying your collider, you shouldn't need to save it, as it won't be any different to the collider attached to your prefab.

All the best,
Joel
General Jewel
Posts: 10
Joined: Tue Jun 16, 2015 4:24 pm

Re: Attempting To Save With Automatic Save Structure

Post by General Jewel »

Hi Joe

Just to let you know using the Automated Save Structure I have got a basic save system going so thank you. I can now save instantiated prefab objects and delete them for my game's level editor etc

For those wondering

I used this to instantiate prefabs

Code: Select all

  UniqueObjectManager.InstantiatePrefab ("Block"); 
I used this to delete individual objects

Code: Select all

UniqueObjectManager.DestroyObject(Block); 
I used this to delete all objects save data

Code: Select all

ES2.Delete("createdObjectsFile.txt");

but one issue remains :lol:

the scene only saves when the application is terminated I.e when pressing stop button on the unity editor. Pressing play will load the scene again with the objects saved. This is due to this

Code: Select all

public void OnApplicationQuit()
	{		
		Save();
	}
	
	/* We also save on application pause in iOS, as OnAppicationQuit isn't always called */
#if UNITY_IPHONE && !UNITY_EDITOR
	public void OnApplicationPause()
	{
		Save();
	}
#endif
In my game I wish to save when the scene is exited i.e with player presses a button this code is called

Code: Select all

			// Reload the level
			Application.LoadLevel("TitleScreen"); 
What is the best way to call the save function when the scene is exited?
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Attempting To Save With Automatic Save Structure

Post by Joel »

Hi there,

You should simply be able to get an instance of the script containing the Save() method, and then call the Save() method when the user presses the button. You may need to make the Save() method public rather than private.

All the best,
Joel
General Jewel
Posts: 10
Joined: Tue Jun 16, 2015 4:24 pm

Re: Attempting To Save With Automatic Save Structure

Post by General Jewel »

Joel wrote:Hi there,

You should simply be able to get an instance of the script containing the Save() method, and then call the Save() method when the user presses the button. You may need to make the Save() method public rather than private.

All the best,
Joel

This is exactly what I did at first but still experienced problems.

I start the app I go into the level editor make my level I press save and exit. Back at the main menu I go into the level editor again the level loads with the objects I have saved intially it works great so far just the way I wanted it.... but this time I try to saveand get this error.
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.GameObject.GetComponent[ES2UniqueID] () (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineGameObject.cs:29)

UniqueSaveManager.SaveObject (UnityEngine.GameObject obj, Int32 i, System.String file) (at Assets/Easy Save 2/Examples/Creating an Automatic Save Structure/UniqueSaveManager.cs:81)

UniqueSaveManager.Save () (at Assets/Easy Save 2/Examples/Creating an Automatic Save Structure/UniqueSaveManager.cs:71)

BuildBoxExit.OnGUI () (at Assets/BuildBox/Scripts/BuildBoxExit.cs:44)
and if wondering how I save here is the code

Code: Select all

using UnityEngine;

/// <summary>
/// Start or quit the game
/// </summary>
public class BuildBoxExit : MonoBehaviour
{
	private GUISkin skin;
	public GameObject ExitButton;

	private GameObject SaveManager;

	
	void Start()
	{
		// Load a skin for the buttons
		skin = Resources.Load("GUISkin") as GUISkin;

		SaveManager = GameObject.Find("UniqueSaveManager");
	}

	void OnGUI()
	{
		const int buttonWidth = 170;
		const int buttonHeight = 80;

		// Set the skin to use
		GUI.skin = skin;
		
		if (
			GUI.Button(
			// Center in X, 1/3 of the height in Y
			new Rect(
			Screen.width / 2 - (buttonWidth / 2),
			(1 * Screen.height / 3) - (buttonHeight / 2),
			buttonWidth,
			buttonHeight
			),
			"Yes"
			)
			)
		{
	
			SaveManager.GetComponent<UniqueSaveManager>().Save();

			// Reload the level
			Application.LoadLevel("TitleScreen");


			Time.timeScale = 1;
		}
		
		if (
			GUI.Button(
			// Center in X, 2/3 of the height in Y
			new Rect(
			Screen.width / 2 - (buttonWidth / 2),
			(2 * Screen.height / 3) - (buttonHeight / 2),
			buttonWidth,
			buttonHeight
			),
			"No"
			)
			)
		{

			ExitButton.GetComponent<BuildBoxExit> ().enabled = false;
		}
	}
  }
very strange not entirely sure why it wont let me save the second time around. I will continue to experiment. As not sure what is destroyed as the uniquesave/object managers are still there. Thank you.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Attempting To Save With Automatic Save Structure

Post by Joel »

The error you're receiving is due to one of the objects you're saving being destroyed, but not being removed from the List of objects to save in the Save Manager. Are you destroying objects elsewhere in your code?

The quickest solution to this would be to simply check that an object hasn't been destroyed before saving it in the Save Manager's Save() method.

Hope this helps!

- Joel
General Jewel
Posts: 10
Joined: Tue Jun 16, 2015 4:24 pm

Re: Attempting To Save With Automatic Save Structure

Post by General Jewel »

Joel wrote:The error you're receiving is due to one of the objects you're saving being destroyed, but not being removed from the List of objects to save in the Save Manager. Are you destroying objects elsewhere in your code?

The quickest solution to this would be to simply check that an object hasn't been destroyed before saving it in the Save Manager's Save() method.

Hope this helps!

- Joel
Thank you once again for the great support you provide on this forum and yes that did help. When the scene changes all objects are destroyed automatically as we know. So I found out when this happens the uniquesavemanager is still tracking them thinking they are still there when they are not.

So I had to declare them when they are destroyed with this on scene change

void OnDestroy () {

UniqueObjectManager.DestroyObject (Block);
Now I can go in and out of the scene and save and load as I please. From what I understood even when the scene changes it seems like the uniquesavemanager still stores the information of the createdobjects. I was thinking since I exit the scene, all is destroyed and it will reset again and track new createdobjects to save rather than the old ones. That is what I understood how it works anyways :lol:

This code will only destroy one of the created item in my case the item with the name block. Now my level editor has over 50+ items so declaring them one by one could be time consuming. So is there a way to clear all createdobjects with one code ? Thank you.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Attempting To Save With Automatic Save Structure

Post by Joel »

Ahh I see. We store the created objects List statically, so it will carry on to other scenes.

In this case, you could either make the List non-static, or simply add this method to the UniqueObjectManager:
void OnDestroy
{
    createdObjects.Clear();
}
- Joel
Locked