Cloning a GameObject List

Greetings,

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(){
		
		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.

Automatic deep copy is hard todo, because some resources can’t be easily cloned. The best you can do is build a copy constructor and manually copy the things, instancing new objects and making the attributions.

Unity have this [1] and I think you can use it for cloning unity game objects, but you need to copy manually any other attribute you create.

[1] Unity - Scripting API: Object.Instantiate

I think I was overcomplicating things, ended up saving the values (game objects position) I needed in a XML file (had to do it at some point anyway).
Thanks for all help though.