Search Unity

How to customise the clone/copy/instantiate function?

Discussion in 'Scripting' started by dishmop, Nov 21, 2014.

  1. dishmop

    dishmop

    Joined:
    Sep 5, 2014
    Posts:
    5
    Summary
    The default cloning method which is called when I call Instantiate(obj) is not working as I need it to for my script. Does this Instantiate() call, call a member function on obj to do the copying? If so, can I write my own custom version?

    If not, how does it work?

    Details
    Here is a simplified description of my problem:

    I have a GameObject called sampleGO. This has a script attached called SampleSc - which looks something like this:

    class SampleSc : MonoBehaviour{
    public GameObject meshPrefab;

    GameObject displayedMesh;

    void Awake(){
    displayMesh = Instantiate(meshPrefab) as GameObject;
    displayMesh.transform.parent = transform;
    }
    };

    Now, suppose elsewhere in my program I attempt to clone my sampleGO. E.g.
    GameObject newGO = Instantiate(sampleGO);

    Then I get a problem, because while in the original, the child of the sampleGO and the displayMesh in SampleSc point to the same object - in my cloned version, they point to two new objects (i.e. both displayedMesh AND the transform's child have been cloned - even through originally they were a single object).

    While I am sure I could work around this by (e.g. not having the displayedMesh variable in the class), I would like to be able to write a custom clone/copy/whatever function to override the default behaviour (there are other reasons why the default behaviour is not good for me too - which I have not gone into here).

    Please help!

    Diarmid
     
  2. Deleted User

    Deleted User

    Guest

    Here's how I did it: (Note: I free-typed this.)

    public void Create(GameObject prefab, Vector3 position, any other custom data you want to pass)
    {
    GameObject go = Instantiate(prefab, position);
    Any functions needed to change go;
    }
     
  3. Stoven

    Stoven

    Joined:
    Jul 28, 2014
    Posts:
    171
    It's actually a bit difficult to understand the problem considering how you've worded it. Maybe I'm just tired, I don't know.

    Looking at the script, I guess I can understand the problem. My guess is that each time you call Instantiate on your sampleGO you're populating an additional displayMesh child even though that's not the behavior that you want?
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Move your Instantiate code into Start and have another method that sets displayMesh. Then check if displayMesh is null before doing the Instantiate.

    Code (csharp):
    1.  
    2. void SetDisplayMesh(GameObject displayMesh)
    3. {
    4.     this.displayMesh = displayMesh;
    5. }
    6.  
    7. void Start()
    8. {
    9.     if (displayMesh == null)
    10.     {
    11.         displayMesh = Instantiate(...);
    12.     }
    13. }
    14.  
    Code (csharp):
    1.  
    2. GameObject clone = Instantiate(original.gameObject);
    3. clone.GetComponent<SampleSc>().SetDisplayMesh(original.displayMesh);
    4.