Save spawned object prefab and it's position
Save spawned object prefab and it's position
Hay there. I'm making a UI based game. It's essentially a cork board app like Corkuluss or what you would find in the game Shadows Of A Doubt. I have a sticky note prefab that I want to spawn onto my board and when I save and reload it is still in the world. It also has a string function to it too, connecting one pin to another. I'd like to keep those connections too. Is there a way to do this? If you need a video to help explain let me know.
Re: Save spawned object prefab and it's position
Hi,
Yes, the save system can handle that.
If an instance of the sticky note starts inactive in the scene and the player activates it through gameplay, you can add an ActiveSaver or MultiActiveSave component to an active GameObject (e.g., empty GameObject) in the scene and assign the sticky note to its Target(s) list. You can also add a PositionSaver to save its position on the board.
If you're spawning sticky notes from prefabs at runtime, add SpawnedObject component to the prefab. Then set up a SpawnedObjectManager in your scene.
If the player can arbitrarily create strings from one note to another, you could handle them the same way, or you could write a custom saver. Custom savers are fairly simple to write: How To: Write Custom Savers
Yes, the save system can handle that.
If an instance of the sticky note starts inactive in the scene and the player activates it through gameplay, you can add an ActiveSaver or MultiActiveSave component to an active GameObject (e.g., empty GameObject) in the scene and assign the sticky note to its Target(s) list. You can also add a PositionSaver to save its position on the board.
If you're spawning sticky notes from prefabs at runtime, add SpawnedObject component to the prefab. Then set up a SpawnedObjectManager in your scene.
If the player can arbitrarily create strings from one note to another, you could handle them the same way, or you could write a custom saver. Custom savers are fairly simple to write: How To: Write Custom Savers
Re: Save spawned object prefab and it's position
I'll give it a look. Thank you very much!
Re: Save spawned object prefab and it's position
Glad to help! If you have questions about specifics, let me know.
Re: Save spawned object prefab and it's position
For the string that the sticky notes can connect string to each other it relies on a script that is recording the transforms of objects. So I'm wanting to save my public transforms for each sticky note that may be saved on my board. The cords all rely on the data from this script.
the script is this
public class DrawLine : MonoBehaviour
{
[Header("Draw Line")]
[SerializeField] private LineRenderer lr;
public Transform point_0;
public Transform point_1;
...than the logic is below this point...
Would it be possible to each sticky note to save it's own data and not rely on an external object? If each sticky note could remember it's own data that would be nice. Otherwise I guess I'd have to draw data from the spawn object manager.
the script is this
public class DrawLine : MonoBehaviour
{
[Header("Draw Line")]
[SerializeField] private LineRenderer lr;
public Transform point_0;
public Transform point_1;
...than the logic is below this point...
Would it be possible to each sticky note to save it's own data and not rely on an external object? If each sticky note could remember it's own data that would be nice. Otherwise I guess I'd have to draw data from the spawn object manager.
Re: Save spawned object prefab and it's position
Oh shoot, and i'll need the sticky note to remember what text i wrote on it too. Any ideas on how to get this to work as well? Really, I'll need to record the state of any script or component I attach to this thing.
Re: Save spawned object prefab and it's position
I agree with you. It's probably best if each sticky note saves its own data. You can do this with a custom saver. (See the link above.) You'll still want to use a SpawnedObject component on the sticky note and use a SpawnedObjectManager in the scene, too.
Re: Save spawned object prefab and it's position
I'm sorry to bother you with the same question but I'm stuck. So my code looks like this:
using System;
using UnityEngine;
using PixelCrushers;
[RequireComponent(typeof(DrawLine))]
public class Component_Saver : Saver
{
public DrawLine drawLine;
[Serializable]
public class Data
{
//public Transform point_0;
public Transform point_1;
}
public override string RecordData()
{
//var drawLine = GetComponent<DrawLine>();
var data = new Data();
//data.point_0 = drawLine.point_0;
data.point_1 = drawLine.point_1;
print(data.point_1.name + data.point_1.transform.position);
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
var data = SaveSystem.Deserialize<Data>(s);
//var drawLine = GetComponent<DrawLine>();
if (data != null)
drawLine.point_1 = data.point_1;
if (drawLine.point_1 != null)
{
print("Load: point_1 has data");
//print(drawLine.point_1.transform.position);
}
else
{
print("Load: point_1 is empty");
}
}
}
The drawLine var the DrawLine script I wrote which as the name suggests handles the drawing of lines between 2 Transforms in my scene. So the Transform I want to remember and save over "public Transform point_1;" is a physical object that was spawned into the scene. The good news is that the object in question has the spawn saver and when I load it remains in the scene. However I don't think that I am actually recording the "public Transform point_1;" data at all, because the line disappears. Which means that the saver is not putting it's "public Transform point_1;" in the DrawLines "public Transform point_1;". It is blank when I load. Am I setting this script up right to fill in my DrawLine scripts "public Transform point_1"?
using System;
using UnityEngine;
using PixelCrushers;
[RequireComponent(typeof(DrawLine))]
public class Component_Saver : Saver
{
public DrawLine drawLine;
[Serializable]
public class Data
{
//public Transform point_0;
public Transform point_1;
}
public override string RecordData()
{
//var drawLine = GetComponent<DrawLine>();
var data = new Data();
//data.point_0 = drawLine.point_0;
data.point_1 = drawLine.point_1;
print(data.point_1.name + data.point_1.transform.position);
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
var data = SaveSystem.Deserialize<Data>(s);
//var drawLine = GetComponent<DrawLine>();
if (data != null)
drawLine.point_1 = data.point_1;
if (drawLine.point_1 != null)
{
print("Load: point_1 has data");
//print(drawLine.point_1.transform.position);
}
else
{
print("Load: point_1 is empty");
}
}
}
The drawLine var the DrawLine script I wrote which as the name suggests handles the drawing of lines between 2 Transforms in my scene. So the Transform I want to remember and save over "public Transform point_1;" is a physical object that was spawned into the scene. The good news is that the object in question has the spawn saver and when I load it remains in the scene. However I don't think that I am actually recording the "public Transform point_1;" data at all, because the line disappears. Which means that the saver is not putting it's "public Transform point_1;" in the DrawLines "public Transform point_1;". It is blank when I load. Am I setting this script up right to fill in my DrawLine scripts "public Transform point_1"?
Re: Save spawned object prefab and it's position
Even when I try saving text on the sticky note object it dose not carry it over if I load the save. Script is here:
////////////////////////////////////////////////////////////////////////////////////////////
using System;
using UnityEngine.UI;
using TMPro;
using UnityEngine;
using PixelCrushers;
public class TextSaver : Saver
{
[SerializeField] TMP_InputField textMesh;
[Serializable]
public class Data
{
//public Transform point_0;
public string myText;
}
public override string RecordData()
{
//var drawLine = GetComponent<DrawLine>();
var data = new Data();
data.myText = textMesh.text;
print(data + data.myText);
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
var data = SaveSystem.Deserialize<Data>(s);
//var drawLine = GetComponent<DrawLine>();
if (data != null)
textMesh.text = data.myText;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
What I'm i missing that is preventing it from caring my saved data over?
////////////////////////////////////////////////////////////////////////////////////////////
using System;
using UnityEngine.UI;
using TMPro;
using UnityEngine;
using PixelCrushers;
public class TextSaver : Saver
{
[SerializeField] TMP_InputField textMesh;
[Serializable]
public class Data
{
//public Transform point_0;
public string myText;
}
public override string RecordData()
{
//var drawLine = GetComponent<DrawLine>();
var data = new Data();
data.myText = textMesh.text;
print(data + data.myText);
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
var data = SaveSystem.Deserialize<Data>(s);
//var drawLine = GetComponent<DrawLine>();
if (data != null)
textMesh.text = data.myText;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
What I'm i missing that is preventing it from caring my saved data over?
Re: Save spawned object prefab and it's position
Ok good news I got the text to work. Apparently it only works if the object with the text is a spawned in object. So now the question is why is the scripts where I'm trying to get my DrawLine script to remember which object its connected to is not loading rite. So to recap I spawn in my pin (Pin_0) object which has a DrawLine script on it which handles the drawLine function. I then spawn in another pin object (Pin_1). Then I select Pin_0 and then select Pin_1. Now the DrawLine script on Pin_0 has its var point_1 (Which is what im trying to carry over when I load) is now Pin_1. With Pin_0's DrawLine var point_1 filled up the DrawLine script automaticly dose it's thing.
When I hit the save button it prints out the data that should be stored, but when I load Pin_0's point_1 is empty, even though both Pin_0 & Pin_1 are both in the scene together because both have that Spawned Object Saver. Is it "technically" working but when the Load button is hit it is just not finding the object I selected for it ie Pin_1? Any ideas what's wrong?
Updated Script...
using System;
using UnityEngine;
using PixelCrushers;
[RequireComponent(typeof(DrawLine))]
public class Component_Saver : Saver
{
public DrawLine drawLine;
[Serializable]
public class Data
{
public Transform point_1;
}
public override string RecordData()
{
var data = new Data();
if (drawLine.point_1 != null)
{
data.point_1 = drawLine.point_1;
print(data.point_1.name + data.point_1.transform.position);
}
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
if (string.IsNullOrEmpty(s)) return; // If we didn't receive any save data, exit immediately.
var data = SaveSystem.Deserialize<Data>(s);
if (data == null) return; // Serialized string isn't valid.
drawLine.point_1 = data.point_1;
}
}
When I hit the save button it prints out the data that should be stored, but when I load Pin_0's point_1 is empty, even though both Pin_0 & Pin_1 are both in the scene together because both have that Spawned Object Saver. Is it "technically" working but when the Load button is hit it is just not finding the object I selected for it ie Pin_1? Any ideas what's wrong?
Updated Script...
using System;
using UnityEngine;
using PixelCrushers;
[RequireComponent(typeof(DrawLine))]
public class Component_Saver : Saver
{
public DrawLine drawLine;
[Serializable]
public class Data
{
public Transform point_1;
}
public override string RecordData()
{
var data = new Data();
if (drawLine.point_1 != null)
{
data.point_1 = drawLine.point_1;
print(data.point_1.name + data.point_1.transform.position);
}
return SaveSystem.Serialize(data);
}
public override void ApplyData(string s)
{
if (string.IsNullOrEmpty(s)) return; // If we didn't receive any save data, exit immediately.
var data = SaveSystem.Deserialize<Data>(s);
if (data == null) return; // Serialized string isn't valid.
drawLine.point_1 = data.point_1;
}
}