This should be a fairly simple problem to solve however I've tried several ways of doing it but the results are always the same.
I'm trying to copy a list containing GameObjects into another list. The problem is it seems I'm copying the references since any changes done to the GameObjects of the original list, also affect the ones on the new list, something that I don't want to happen. From what I've read I'm doing a shallow copy instead of a deep copy, so I tried to use the following code to clone each object:
public static class ObjectCopier
{
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static GameObject Clone<GameObject>(GameObject source)
{
if (!typeof(GameObject).IsSerializable)
{
throw new ArgumentException("The type must be serializable ", "source: " + source);
}
// Don't serialize a null object, simply return the default for that object
/*if (Object.ReferenceEquals(source, null))
{
return default(GameObject);
}*/
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (GameObject)formatter.Deserialize(stream);
}
}
}
I get the following error:
ArgumentException: The type must be serializable Parameter name: source: SP0 (UnityEngine.GameObject) ObjectCopier.Clone[GameObject] (UnityEngine.GameObject source) (at Assets/Scripts/ScenarioManager.cs:121)
The function posted above is called here:
void SaveScenario(){
foreach(GameObject obj in sleManager.listOfSourcePoints){
tempObj = ObjectCopier.Clone(obj);
listOfScenarioSourcePoints.Add(tempObj);
Debug.Log("Saved Scenario Source List Point");
}
foreach(GameObject obj in sleManager.listOfDestPoints){
tempObj = ObjectCopier.Clone(obj);
listOfScenarioDestPoints.Add(tempObj);
Debug.Log("Saved Scenario Dest List Point");
}
}
void LoadScenario(){
sleManager.listOfSourcePoints.Clear();
sleManager.listOfDestPoints.Clear ();
foreach(GameObject obj in listOfScenarioSourcePoints){
tempObj = ObjectCopier.Clone(obj);
sleManager.listOfSourcePoints.Add(tempObj);
Debug.Log("Loaded Scenario Source List Point");
}
foreach(GameObject obj in listOfScenarioDestPoints){
tempObj = ObjectCopier.Clone(obj);
sleManager.listOfDestPoints.Add(tempObj);
Debug.Log("Loaded Scenario Dest List Point");
}
}
Now, the original list is created here:
if (child.name == "DestinationPoints")
{
parentDestinationPoints = child.gameObject;
foreach (Transform grandChildDP in parentDestinationPoints.transform)
{
//Debug.Log("Added DP object named: " + grandChildDP.name);
tempObj = grandChildDP.gameObject;
listOfDestPoints.Add(tempObj);
tempObj.AddComponent<DestinationControl>();
tempObj.transform.renderer.material.color = Color.white;
}
}
// Hide all SourcePoints in the scene
if (child.name == "SourcePoints")
{
parentSourcePoints = child.gameObject;
foreach (Transform grandChildSP in parentSourcePoints.transform)
{
tempObj = grandChildSP.gameObject;
listOfSourcePoints.Add(tempObj);
tempObj.transform.renderer.enabled = false;
}
}
This "tempObj" has the [SerializeField] property so I must be missing something here. Any help would be greatly appreciated.
EDIT: Forgot to mention, this app is in Unity3D.