- Home /
Deep clone a gameobject
I tried searching around for this, but I wasn't able to find an answer.
I have a gameobject with a custom component attached (C# script). This script has several variables that have been set previously (Lists, booleans, etc). I need to make a clone of it.
Now, when I Instantiate a new object from this one, I have noticed that none of the variables from the original are copied over; the component is in a fresh state in the new one.
Is there a way to perform a deep clone of a gameobject? A clone where the state of every attached component is identical to the original, including members?
EDIT:
Here is some example code to demonstrate the issue (the original code is far too verbose)
public class FooBar : Monobehaviour {
private HashSet<uint> hashSet;
public void Awake() {
hashSet = new HashSet<uint();
}
public void SomeMethod() {
hashSet.Add(12345);
}
}
// code in some other class
gameObjectWithFooBarComponent.SomeMethod();
GameObject go = Instantiate(gameObjectWithFooBarComponent);
If I set a breakpoint in the code in the Awake() method, hashSet is null before assigning it a new hashSet. I want it to have a single element "12345", which is what the object I cloned from has.
Could you post any source code? Or at least detail how and where you are calling Instantiate. As noorudheen has stated if you read the documentation(http://docs.unity3d.com/ScriptReference/Object.Instantiate.html) it "should" make a complete copy of whatever GameObject you pass in.
Edit: Just thought, are you setting any of these variables in the Start, Awake etc functions in any of the $$anonymous$$onoBehaviors attached to the object in question?
Yes I am, but I inserted a breakpoint in the code to check the value before Awake() gets to override the value.
I have updated the question with some example code.
I would step back and try it out with simpler code. It could be an issue with having the variables private. It could be a weird interaction that Awake has with Instantiate. It could be something to do with complex values (List of Lists). It could be none of those and some other issue all together. If all else fails you can always deep copy over the data manually.
Answer by noorudheen · Aug 11, 2015 at 04:59 PM
are the variables set at runtime? In the editor you have to assign gameobject itself rather than a prefab to the instantiating script.. this will copy the current variable values at runtime.
The gameobject that is being cloned will have been instantiated previously during gameplay, and have all sorts of state information set.
This is a gameobject that is not in an initial prefab state, but has had lots done to it already during the course of gameplay.
If it helps, the attached component procedurally creates a mesh for the gameobject, and contains spline information. the clone also needs this information (and not simply the $$anonymous$$eshFilter.mesh). It has meta-data that was used to create the mesh, and the clone also needs this.
Bottom line is that I need an EXACT copy, not just a new gameobejct that has all the same components; and it has to happen at runtime.
if you assign a "gameobject" to the gameobject variable, not a "prefab" of the required gameobject, all the values at the time of cloning will be copied to the clone. In your case, if you had Instantiated a prefab already and added datas to it and you need the clone with those data, just clone the clone not the initial gameobject.
hopes this helps.
Answer by ThePunisher · Aug 11, 2015 at 07:25 PM
Awake gets called on an object as it is instantiated.
You're calling SomeMethod on the original object modifying its data then proceeding to instantiate a copy of it. Then the newly instantiated copy is calling Awake and re-initializing the list, losing your values in the process.
Try this:
public class FooBar : Monobehaviour {
public HashSet<uint> hashSet = new HashSet<uint();
public void SomeMethod() {
hashSet.Add(12345);
}
}
Update: Actually, aside from what I mentioned above, Unity will not copy over private or protected members when you create a new copy. It will only copy public members, which makes total sense. You might need to rethink what you are doing vs what you are trying to accomplish.
I know Awake will do that, I was testing this with breakpoints before the re-assignment.
That being said, I think I have tracked the problem down to party private members, and also to Unity not being able to serialize a List of custom class (in my case: List), regardless of the fact it is public.
I suppose I will just need to work around it.
It is able to serialize a custom class provided you add the [Serializable] attribute to the top of the class.
[Serializable]
public class FooBar : $$anonymous$$onobehaviour {
public HashSet<uint> hashSet = new HashSet<uint();
public void Some$$anonymous$$ethod() {
hashSet.Add(12345);
}
}
Did you even read my answer?
That is a massive generalization. Unity can serialize any custom class fieldtype. This however does little good if none of the data in that class can get serialized and depending on the types of data structures your hoping to get serialized this is where you will run into trouble. If the problem with Instantiate is a serialization one I recommend checking out Unity's blog post on it. http://blogs.unity3d.com/2014/06/24/serialization-in-unity/ You also might consider looking into Scriptable Objects, typically videos or posts which cover them have to cover Unity's serialization system.
@JoshuaStrunk umm.... what? Yes it can. I think what you meant to say was that it will only serialize members that meet certain criteria.
@ThePunisher Ah your right it was semantic difference. You can in theory serialize any custom class you want. That does not mean it will be very useful afterwards. I have edited my original comment to reflect the correction.
Your answer
Follow this Question
Related Questions
Moving a transform behaves odd 0 Answers
How can I assign a clone with a script to a variable? without drag & drop 1 Answer
my object instantiates to much 1 Answer
Instantiating a random dropped consumable item from many cloned objects 1 Answer
How can I make a game object follow an instantiated game object? 1 Answer