Page 1 of 1

[Manually] Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Jun 20, 2018 5:32 pm
by Joel
This is an example of saving and loading prefabs which are instantiated at runtime using your own manager. In most cases you are better off following the following guide unless you absolutely need to create your own manager:

https://moodkie.com/forum/viewtopic.php?f=16&t=2692

This uses a single script: ES3PrefabManager.cs. The script is fully-commented, so it is recommended that you read the script to understand how this example works.

Important: In most cases it is much easier to follow the Saving and Loading Prefab Instances guide, rather than creating your own manager as described in this example.

The script loads any saved prefabs when the scene is loaded, and saves instantiated prefabs when the application is quit or paused. Any prefabs which you wish to save at runtime should be instantiated using the script's InstantiatePrefab() method, which replaces Unity's Instantiate() method.

Note that separate ES3PrefabManager is required for each type of prefab you wish to save.

Note:
  • Easy Save should be installed in your project before importing this example. The example is located in Assets/Easy Save 3/Examples/.
  • All examples are only provided as an educational sample, and may need modification for your purposes. They are provided without warranty.

Code: Select all

using UnityEngine;
using System.Collections.Generic;

/*
 * 
 * This class will manage the creation of prefabs, including loading and saving them.
 * It will also store a list of all of the prefabs we've created.
 * 
 */
public class ES3PrefabManager : MonoBehaviour 
{
	// The prefab we want to create.
	public GameObject prefab;
	// An automatically-generated unique identifier for this type of prefab.
	// We will append this to our keys when saving to identifiy different types
	// of prefab in the save file.
	public string id = System.Guid.NewGuid().ToString();
	
	// A List which we'll add the Transforms of our created prefabs to.
	private List<Transform> prefabInstances = new List<Transform>();

	/*
	 * This is called whenever the application is quit.
	 * This is where we will save our data.
	 */
	void OnApplicationQuit()
	{
		// Save the number of created prefabs there are.
		ES3.Save<int>(id+"count", prefabInstances.Count);
		// Save our Transforms.
		ES3.Save<List<Transform>>(id, prefabInstances);
	}

	/* We also call OnApplicationPause, which is called when an app goes into the background. */
	void OnApplicationPause(bool isPaused)
	{
		if(isPaused)
			OnApplicationQuit();
	}

	/*
	 * This is called when the scene first loads.
	 * This is where we load our prefabs, if there are prefabs to load.
	 */
	void Start() 
	{
		int count = ES3.Load<int>(id + "count", 0);
		// If there are prefabs to load, load them.
		if(count > 0)
		{
			// For each prefab we want to load, instantiate a prefab.
			for(int i = 0; i < count; i++)
				InstantiatePrefab();
			// Load our List of Transforms into our prefab array.
			ES3.LoadInto<List<Transform>>(id, prefabInstances);
		}
	}

	/*
	 * 	Creates an instance of the prefab and adds it to the instance list.
	 */
	public GameObject InstantiatePrefab()
	{
		var go = Instantiate(prefab);
		prefabInstances.Add(go.transform);
		return go;
	}

	/*
	 * Instantiates the prefab at a random position and with a random rotation.
	 */
	public void CreateRandomPrefab()
	{
		var go = InstantiatePrefab();
		go.transform.position = Random.insideUnitSphere * 5;
		go.transform.rotation = Random.rotation;
	}

	/*
	 *  Deletes all prefab instances from the scene and from the save file.
	 */
	public void DeletePrefabs()
	{
		// Delete the keys relating to this prefab.
		ES3.DeleteKey(id);
		ES3.DeleteKey(id+"count");
		// Destroy each created prefab, and then clear the List.
		for(int i=0; i<prefabInstances.Count; i++)
			Destroy (prefabInstances[i].gameObject);
		prefabInstances.Clear();
	}
}

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Apr 03, 2019 12:44 pm
by cocche
Sorry if it's a stupid question but when I run this test and try to add a test variable to the sphere prefab, and then exit the scene and load it back the sphere loads correctly but the test variable doesn't. How can I load the values of the variable with the prefabs ?

To be more specific: in my case I added a simple "public int test" to the sphere prefab, changed the value during runtime, stopped the Scene, and restarted the scene. I know that I have to specify the variables that I want to be saved but I don't understand where and how should I do it.

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Apr 03, 2019 6:40 pm
by Joel
cocche wrote:Sorry if it's a stupid question but when I run this test and try to add a test variable to the sphere prefab, and then exit the scene and load it back the sphere loads correctly but the test variable doesn't. How can I load the values of the variable with the prefabs ?

To be more specific: in my case I added a simple "public int test" to the sphere prefab, changed the value during runtime, stopped the Scene, and restarted the scene. I know that I have to specify the variables that I want to be saved but I don't understand where and how should I do it.
Hi there,

You do this by finding your type in the Window > Easy Save 3 > Types pane, and selecting the variable from there. More info can be found here: https://docs.moodkie.com/easy-save-3/es ... -es3types/

All the best,
Joel

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Aug 28, 2019 3:04 pm
by Jorge
Thanks for the example. I have a question. Let's say I have instantiated 10 prefabs and I want to delete just 1? The delete function you posted, deletes I think all prefabs right?

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Aug 28, 2019 3:08 pm
by Joel
Hi there,

The easiest way to delete a single instance would simply be to destroy that instance in the game. Then when you re-save the game, this instance will no longer be in the data.

All the best,
Joel

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Aug 28, 2019 3:13 pm
by Jorge
hmm that is not working. I think somewhere I have to remove from the list and then save
edit: got it. Added this function to a UI button click and it works. After removing the actual object transform from the list, I can then save.

Code: Select all

public void DeletePrefab(GameObject objToRemove)
    {
        prefabInstances.Remove(objToRemove.transform);
    }

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Wed Nov 13, 2019 10:34 pm
by MASC
Hi,

I'm trying this example deleting one by one instead of delete all of them and it works, but when I exit and load again the objects are instantiated, but at the origin, not in the same place where were deleted.

I tried removing one element from the list and in that case works but just for 1 object (e.g. the cube) and the others (e.g. cylinder and sphere) continuing experiencing the same thing. Being instantiated at the origin when the scene is loaded again.

Any suggestion to delete the objects one by one and at the same time remove properly the element from the list.

Thanks in advance.

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Thu Nov 14, 2019 8:25 am
by Joel
Hi there,

Generally you are going to run into issues by deleting a single prefab because we're using the position of the prefab in the List as it's identifier. This means that if we delete a single prefab in the middle of the List, the prefab with the final index will be lower than the Count of the List, so this will never be loaded.

Instead you would need to assign IDs to each of your prefabs and maintain a Dictionary of IDs and prefab instances, rather than identifying them using a List. This is essentially what the method described in the Saving and Loading Prefab Instances section of the Saving GameObjects guide does for you, without you having to maintain your own list of IDs: https://docs.moodkie.com/easy-save-3/es ... s-prefabs/

All the best,
Joel

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Sat Dec 07, 2019 8:26 pm
by ProjectMarbles
Hello!

Sorry if this is going to sound stupid or ridiculous but I'm really confused about how this works. I've brought over the scripting completely over into unity and have had a look at the script and examples in the package however the game objects that I'm attempting to save aren't saving at all. When I debug the count on application quit its saying 0 and there's at least five gameobjects on screen I'm attempting to save. Am I missing / misunderstanding on how to tell the system what gameobjects to save?

I've also enabled the prefabs for EasySave using the documentation on saving and loading gameobjects. Thank you!

Re: Saving and Loading Prefabs Instantiated at Runtime

Posted: Mon Dec 09, 2019 8:04 am
by Joel
Hi there,

This guide is intended for if you are manually creating your own save system. If you simply use ES3.Save<GameObject> as documented here then it will lead to much simpler code than in this example.

If you've tried doing it that way, please could you create a new project which replicates it with and PM it to me with instructions?

All the best,
Joel