Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

Reference to prefab changing to clone self-reference

Discussion in 'Scripting' started by rsx, Aug 13, 2010.

  1. rsx

    rsx

    Joined:
    Nov 4, 2009
    Posts:
    87
    Hi,

    I have a script on a prefab which displays a GUI button. When the button is clicked it instanciates a prefab. The prefab to instantiate is a drag dropped reference on a transform parameter in the script.

    This works.

    However... If I want an instance (clone) of the prefab to instanciate another clone of its prefab (meaning the reference in the prefab's script is referencing itself), I run in to a problem. When I drag the original prefab in to the scene, everything looks fine, but the when I use the UI to make an instance/clone, and look at the new clone in the inspector, the reference is no longer to the prefab, it is a self-reference to the clone in the scene.

    This is a pretty simple setup, but kind of hard to explain. I hope I am making sense.

    My goal is to have this game object make copies of itself using the GUI Button.

    My GUI code is simple. It does not set this reference anywhere in the code. Something is triggering the change, but I don't know where to start my search. Hopefully someone here can help. In the mean-time, I'll start stripping back my code to see if I can uncover it.

    Cheers,
     
  2. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    ?

    If you showed your code, we could have helped, but simply telling us this don't help you at all, you're still alone against your problem.
     
  3. rsx

    rsx

    Joined:
    Nov 4, 2009
    Posts:
    87
    I was hoping someone might have seen something like this before and have an idea where I might look. I have a lot of code to trip back and it is bed time here.

    It is strange the code works fine with one object but not another. My main lone is a simply:

    Transform instance = (Transform)Instantiate(prefab);

    Where 'prefab' is the reference right from the inspector. After I make the instance, I do a bunch of manipulation on the transform, but nothing else really.

    I'm sure I can isolate it if it is in my code, but last time something weird happened like this, it turned out to be a Unity bug that cost me 6 hours, so I did some high-level repro and decided to post here. I promise to go deeper in to my code tomorrow.

    Thanks for the reply.
     
  4. rsx

    rsx

    Joined:
    Nov 4, 2009
    Posts:
    87
    OK, I have a repro.

    1. Create a new scene.

    2. Create a sphere, make it a prefab, and add the prefab to the scene.

    3. Add the following script to the sphere prefab.

    4. Drag the sphere prefab onto the script's "prefab" attribute in the inspector.

    5. Play the game and click the button over the sphere to create another sphere.

    6. Look at the new sphere's script's "prefab" reference and it will NOT be referencing the prefab, instead it will reference the instance that created it.


    Code (csharp):
    1. using UnityEngine;
    2.  
    3.  
    4. public class TestInstanceButton : MonoBehaviour
    5. {
    6.     public Transform prefab;
    7.  
    8.  
    9.     protected void OnGUI()
    10.     {
    11.         float height = 30;
    12.         float width = 70;
    13.  
    14.         // Create a new rect
    15.         Rect rect = new Rect();
    16.         rect.height = height;
    17.         rect.width = width;
    18.  
    19.         // Put the rect over the transform
    20.         Vector3 pos = UI.cam.WorldToScreenPoint(transform.position);
    21.         pos.y = Screen.height - pos.y;
    22.  
    23.         // Multiply by half so the rect is centered
    24.         rect.x = pos.x - (width * 0.5f);
    25.         rect.y = pos.y - (height * 0.5f);
    26.        
    27.         // Create the GUI
    28.         GUILayout.BeginArea(rect);
    29.  
    30.         if (GUILayout.Button("test", GUILayout.Height(height)))
    31.         {
    32.             Transform instance = (Transform)Instantiate(this.prefab);
    33.  
    34.             if (!instance)
    35.             {
    36.                 Debug.LogError("Unable to create instance.");
    37.                 return;
    38.             }
    39.  
    40.             // Move the instance over to the side a little so we can see it
    41.             Vector3 new_pos = new Vector3();
    42.             new_pos.x = transform.position.x + 3;
    43.             new_pos.y = transform.position.y;
    44.             new_pos.z = transform.position.z;
    45.             instance.position = new_pos;
    46.         }
    47.  
    48.         GUILayout.EndArea();
    49.     }
    50.  
    51. }

    No where in the code do I change the reference, so it is definitely Unity doing it.

    If I need a workaround, Does anyone know a way to get to a prefab from an instance/clone of it?
     
  5. cj.currie

    cj.currie

    Joined:
    Nov 27, 2008
    Posts:
    292
    I have this same issue, and I really want to get it fixed. For me, it's a slightly different situation, though.

    I have a script that goes on an Item object, and when the player collides with it the Item is added to the Inventory and the object is destroyed. The Item also had a variable, myPrefab, that pointed to the prefab that it is a copy of. This reference is copied into a holder var before the object is destroyed. Tests on the holder var confirm this.

    However, at run time, the variable points not at the prefab in the Project folder, but to the actua in-game GameObject. This makes sense because at run time they are essentially clones of each other, and instantiating one over the other makes no difference, but if I store the variable myPrefab in another script and try to instantiate it later, the changed reference means I'm trying to instantiate an object that was destroyed - which is against the rules.

    Basically,
    1.) Object 1 stores a reference to its own prefab.
    2.) At run time that reference changes from the prefab in the Project folder to the in-scene instance of the object.
    2.) Object 2 copies that reference and destroys object 1.
    3.) When Object 2 tries to instantiate using that reference, it gets a NullReferenceException because the object no longer exists.

    I have a theory that if I can somehow break the prefab connection before Unity does step 2.), that would fix this.
     
  6. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    Pretty crazy.

    If you don't set anything in the "prefab" Transform value of the prefab...

    And you set the prefab in the "Prefab" Transform value of the sphere in the scene...

    It works as intended.

    Putting the Transform prefab in the "prefab" Transform value of the prefab (its own Transform) results in the current situation (cubes are instantiated from the previous instance).

    I think the use of a third object is required. This object has a reference to the initial gameObject, and whenever a instance is wanted, the prefab checks for the gameobject reference, his "prefab" variable (which should not chance over time).
     
  7. nvarcha

    nvarcha

    Joined:
    Sep 27, 2008
    Posts:
    191
    Make sure you're selecting a Prefab from the Project and not from the Scene.

    Hope this helps.
     
  8. rsx

    rsx

    Joined:
    Nov 4, 2009
    Posts:
    87
    @nvarcha Yeap.

    @cjcurrie The reference is good if the gameobject is placed in the scene then the game is started. It only seems to happen if the gameobject is instanced during the game play.

    My problem is that this game object has a starting state in the prefab, and once added to the scene, will change. Making a copy of the copy, with the changed state, really messes things up.

    @AkilaeTribe I can't use that work-around that because these objects are placed by a user. However, you might have given me a workaround I can use, it just seems a bit insane...


    Work-around? (still need to try this tomorrow):
    I already have a "Globals" game object I use for other stuff, this is in the scene before the game starts and I suppose I could place a script on there that holds references to the prefab. Any script that needs to make instances of these references could stor a reference to "Globals" on Awake() then instance with that reference instead of the local script drag-and-drop reference.

    If this works, I would likely go one step further and make a globally-accessible static dictionary (singleton), so I don't have to do anything in Awake(). The dictionary would be created on startup and used globally.




    A Comment to the Unity Team:
    I'd like to say this is not the expected result from a user point of view. This creates a black-hole of debugging time. I can easily store a reference to an instance from a script, I don't need some elaborate reference passing to try and solve this. Especially when I don't need it.

    I expect a prefab to always instance a fresh copy, not a copy of a copy. Would you expect a C# class to create an instance of the last instance? Or a new instance? The Prefab holds an initiated state, and THAT is what I want to instance in to my game.

    I love Unity, but this kind of thing really eats away my day. I hope you will either explain why this is a wanted feature, in clear terms, to me and in the docs; or fix it.

    I mean this to be constructive.


    Cheers,
     
  9. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    I think it works like this because the variable refers to a component that is a part of the game object itself.

    The reasoning must be the following :

    - If the component pointed is on another gameObject, there is nothing special, it will always show "that" component.
    - If the component pointed is on the same game object, then, it will understand it is his component and refers to itself.

    Another example is Microsoft Office Excel. When you make a table, with three columns, the third columb being the sum of the two first columns, you write :
    A1 + B1 = C1

    Excel is clever, if you copy paste this line deeper in the table, it changes the numbers. So, Ax + Bx = Cx. It is relative position.

    There is an option in Excel, that is not present in Unity, blocking value.

    So, writing in Excel, for example, $A$1 + B1 = C1, and copying pasting it will result in the general formula : A1 (always) + Bx = Cx.

    But let's go back to the subject. If what I wrote is true, then, you really need a foreign object, to avoid the relative position. :?
     
  10. cj.currie

    cj.currie

    Joined:
    Nov 27, 2008
    Posts:
    292
    A simple "break prefab reference at startup" or "don't make the assumption that I meant your own object" method would solve this.
     
  11. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    820
    If you want to instantiate the prefab itself, place it in the Resources folder and do a:

    Instantiate(Resources.Load("PrefabName")) as GameObject;

    Once you drag a prefab into the game world, it's an instance of that prefab - anything you do down the line will be done to that instance. It sounds like you are attempting to use prefabs in a way that they are not designed to be used.

    To do something similar to what you want, here is what I would do:

    1) Make a script on all of my prefabs I wish to instantiate this way with some value unique to that prefab (I'd probably just use a string equal to the prefab name).

    2) Move all the prefabs to the resources folder, or a sub-folder

    3) Make my script which does the instantiation do something like:

    Instantiate(Resources.Load("Prefabs/" + myClass.PrefabName)) as GameObject; (where PrefabName is a public/getter string equal to the name of the prefab object in the resources/Prefabs folder).
     
  12. cj.currie

    cj.currie

    Joined:
    Nov 27, 2008
    Posts:
    292
    I was aware of Resources.Load, but I didn't want to muck with a resources folder :p
     
  13. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    The problem with having to find a work around is that this should not need a work around.

    There is no reason that an object cannot store it's own prefab as a variable to later be instantiated.

    In fact, this does work. Upon running this with some debug settings, it successfully passes the prefab name that it's supposed to instantiate to be stored. Problem is, as mentioned in the topic, is it stores it as the clone and not as the prefab itself, so when called on, the prefab in clone form does not exist, and thus fails.

    IMHO, this is clearly a bug, as it ONLY happens when the instance refers to itself.

    the most "optimized" fix for it, at least now, is to create 2 prefabs of the same object. object1 references object2, and object2 references object1.

    I would definitely submit this to support as a bug, with example of code.

    Regards,
    Rob
     
  14. cj.currie

    cj.currie

    Joined:
    Nov 27, 2008
    Posts:
    292
    Submitted. UT, please fix this asap!
     
  15. rsx

    rsx

    Joined:
    Nov 4, 2009
    Posts:
    87
    Exactly my thought. If it did this in all situations it would be a feature, but it only happens in this specific situation, so it has to be a bug IMO. Inconsistency is bad.

    I thought Unity guys where on these forums. I'll look for an official place to post this as a bug.

    Nice idea using a duplicate. Not great, but the resources folder scares me for some reasons, lol. I just hate workarounds that increase the chances for human error. I'm still thinking a global script to hold prefabs is the way to go, then we keep one prefab, with only one state possible, and I can print error messages to protect my code.

    Thanks for talking through this guys.
     
  16. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    34
    It's not a bug in my eyes. It's kind of a feature that cause some problems in this special case. A prefab is a very special construct. You can create very complex prefabs with a lot of nested gameobjects and scripts. For example: if you have a script with a public var of type Collider, you can assign the collider of eg. a nested gameobject to that variable. The clue is when the prefab is instanciated all local references you've set inside the prefab will be adjusted to match the new clone. Consider this: you've created a house with a door and a trigger that opens that door. You would have set a reference in the script on your trigger to the door GameObject. When cloning the prefab of the house (or even the house itself) those internal references will be adjusted during Instanciate().

    In most cases it's a good feature and saves a lot of time to init all references at Start(), only when you try to make a self replicating prefab you run into that problem. Maybe you can copy the prefab reference into a static variable at Awake() (only if not set yet) and use that for replication. But i will only work when assigning the prefab to an instance in the scene and you do NOT apply the changes. If you press apply the references get immediately adjusted. That means the true reference to the prefab is not set inside the prefab it's on that one single instance in the scene.

    I think the best way/workaround would be some kind of singleton prefab manager. Maybe Unity will add another bool to Instanciate() to specify whether you want to adjust references or not. But i think that's not that trivial because even the transform child relationship of the cloned objects have to be adjusted. Otherwise there would be a child with two parents or the original will loose the child to the clone.
     
  17. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    (This thread is actually a few months old...)

    Maybe there's a good reason for it to work this way, but it certainly cost me some debugging time the first time I ran into it. What I do now whenever I need 'recursive instantiating' is create two identical prefabs and link them to each other. It's not ideal (since you have to keep the prefabs in sync), but it works.
     
  18. gameboyyo

    gameboyyo

    Joined:
    Jul 16, 2011
    Posts:
    20
    What an horrible issue. Just stumbled upon it. Stupidly absurd. Working around it requires an equally contorted and retarded approach to this which should be a non-problem.
     
  19. vladk

    vladk

    Joined:
    Jul 10, 2008
    Posts:
    131
    My workaround for this one is that I make a host-object that instantiates a prefab in the position the original gameObject requires it to be. Quite painful tho. A fix required!

    And no, there is no "good reason for it to work this way". It's a freaking bug for Christ sake!
     
  20. Ad1981

    Ad1981

    Joined:
    Dec 14, 2011
    Posts:
    1
    I had similar problem with buildings which can be destroyed, and repaired (replaced by fresh instantiation of prefab). The easiest way, which i found to resolve this was to create in first frame after start copy of object and deactivate it. Then in moment, when i normally would call instantiate, i'm just activating previously created one.
     
  21. idmadj

    idmadj

    Joined:
    Jan 17, 2012
    Posts:
    1
    This looks like a design compromise the Unity team had to make. It's helpful in some cases, not in others.

    Instead of going one way or the other to "fix" this issue, why not create a new attribute? Something like "@ExplicitReference" or whatever. Leave the default behavior as it is, and if we want the field to always point to a prefab in our asset folder (instead of the one on the scene), we'd just add this attribute.

    This would also prevent older code from breaking.
     
  22. GBCFraser

    GBCFraser

    Joined:
    Apr 11, 2013
    Posts:
    89
    I hate to bump an old post, but its better than starting a new one... has anyone found a solution to this issue besides the ones mentioned? I just ran into this issue, any planned updates by unity to fix this?
     
  23. Glorion13

    Glorion13

    Joined:
    Nov 19, 2012
    Posts:
    7
    The quick dirty solution is the one mentioned about creating 2 objects, each pointing to the other. Another solution would be to have a 2nd, different object, which points to the prefab. Then the original prefab can point to where that 2nd different object points.

    Example:
    You have a 'Building' prefab, which can build new 'Building' objects and you have it pointing to itself, creating the Clone issue.
    You create a 2nd object, called 'ListOfBuildings' and you have it reference the 'Building' prefab. Then, the 'Building' prefab, instead of referencing itself, will reference the 'Building' prefab from 'ListOfBuildings'.

    I hope this makes sense.
     
  24. CiberX15

    CiberX15

    Joined:
    Jul 31, 2013
    Posts:
    8
    I don't feel bad about dragging this back to light. It is causing massive problems for me and apparently many others and needs to be complained about properly so that the devs at least keep trying to fix it. : P

    Like this perhaps?!

     
  25. bombapps

    bombapps

    Joined:
    Jul 11, 2013
    Posts:
    5
    Yeah I've gotta say this is a huge pain.

    I want to copy the original reference to the prefab because it saves me having to reset all the changes over the lifetime of the currently active one, but as soon as destroy the active object, presto, all the scripts are deactivated. None of the suggested workarounds are very practical and make it very messy to maintain if you are dealing with more then just a few prefabs.
     
  26. fivearchers

    fivearchers

    Joined:
    Apr 17, 2009
    Posts:
    716
    Ugh just hit this wall also. Kind of a stupid bug. I'm going to try the two object method I think (though I may end up with resources load).
     
  27. bombapps

    bombapps

    Joined:
    Jul 11, 2013
    Posts:
    5
    Yeah the two object method works, though it is cumbersome. I ended up using a combination of two objects in some cases and in others I used a small script to enable all children components in Awake(), which works fine if you know all the types of the components you need to enable (in my cause just MonoBehaviour). Won't work in all scenarios of course.
     
  28. Devil_Inside

    Devil_Inside

    Joined:
    Nov 19, 2012
    Posts:
    904
    Oh God! A 3 years old bug still not fixed.
    Spent the last 2 hours trying to understand what I'm doing wrong.
     
    lPVDl likes this.
  29. cayouMontreal

    cayouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    213
    Same issue here, an object can't keep a reference to its own prefab...
    Any news about that?

    Or is there a way to get the prefab referenced by using a "magic" method?
     
  30. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,794
    The behavior is by design, it's not a bug.

    The solution is usually to have the thing that did the instantiating (and therefore has a reference to the 'original' prefab) fix up the instantiated object. i.e:

    Code (csharp):
    1.  
    2. MyObj instantiatedObj = (MyObj) Instantiate(prefab);
    3. instantiatedObj.sourcePrefab = prefab;
    4.  
     
  31. basti

    basti

    Joined:
    Jan 5, 2012
    Posts:
    6
    could you please elaborate further? If i pass the reference to the original prefab over to the freshly instantiated copy it does not work for me.

    Code (csharp):
    1. public class SelfInstantiate : MonoBehaviour
    2. {
    3.     public SelfInstantiate myPrefab;
    4.    
    5.     public int testVal1;
    6.     public int testVal2;
    7.    
    8.     void Update ()
    9.     {
    10.         if(Input.GetKeyUp(KeyCode.Space))
    11.         {
    12.             SelfInstantiate si = (SelfInstantiate)Instantiate (myPrefab, Vector3.zero, Quaternion.identity);
    13.             si.myPrefab = myPrefab;
    14.         }
    15.     }
    16. }
     
  32. noio

    noio

    Joined:
    Dec 17, 2013
    Posts:
    54
    Is there a reason you are assigning to `sourcePrefab` ? Why not just set `instantiatedObj.prefab = prefab;` like basti is doing?
     
  33. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,794
    They're just different variable names.
     
  34. noio

    noio

    Joined:
    Dec 17, 2013
    Posts:
    54
    You are not setting the same field on the instantiated object (sourcePrefab) that you get from the current object (prefab)

    instantiatedObj.sourcePrefab = this.prefab

    Did you mean

    instantiatedObj.sourcePrefab = this.sourcePrefab ?

    Whereas basti is setting/getting the same variable, and reporting a failure.
     
  35. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,794
    My code snippet isn't designed to be used inside an instance of MyObj; it's designed to be used inside the instance of the thing creating MyObj (say, MyObjFactory). So there's no reason why the field names would necessarily be the same.

    I'm not sure why basti's code isn't working. Needs to be more specific than 'it does not work for me' if we're going to diagnose it.
     
  36. noio

    noio

    Joined:
    Dec 17, 2013
    Posts:
    54
    Ah okay, that confused me :)...

    Just staying a little more on topic. We used the workaround of creating a Singleton with references to all the prefabs, so we

    Code (CSharp):
    1. (Tree) Instantiate(  PrefabHolder.Instance.TreePrefab )
     
  37. Suttonian

    Suttonian

    Joined:
    Apr 24, 2013
    Posts:
    3
    How to reproduce:
    1. Create a new script (C#)
    2. Add a variable: public GameObject myPrefab;
    3. Create an empty GameObject in the scene
    4. Attach the new script
    5. Drag the game object into the project window to create a new prefab
    6. Now, drag the newly created prefab in the project view to the myPrefab variable in the scene view
    7. If you click the 'myPrefab' value at this point (in the scene), you'll see that it highlights the prefab in the project view (correct)
    8. Click Apply on the GameObject
    9. If you click the 'myPrefab' value at this point (in the scene), you'll see that it highlights the gameobject itself in the scene view (unexpected). This means that the script cannot create new instances of the prefab, only clone itself.

    Is that really intentional? Although you can posit a self-instantiating gameobject isn't good design, it still seems like a bug (or is there a good reason it behaves like this?).

    This happened in 4.6.2 on Windows and Mac.

    Also superpig - hey! I used see you frequently in #gamedev many years ago (I was stevenmarky).
     
  38. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,470
    Not sure if this helps, but you can use PrefabUtility.GetPrefabParent(yourPrefabInstance);

    This will get the real prefab, from your assets... instead of the prefab instance you've dropped on the scene.

    EDIT: Actually doesn't work once you make a build.
     
    Last edited: Jul 14, 2015
  39. lPVDl

    lPVDl

    Joined:
    Aug 10, 2014
    Posts:
    2
    Asked about it in Unity questions but not see it posted, looks like devs don't like such questions about self linked prefabs. Thanks community for a method of two objects :)
     
  40. simplicitydown

    simplicitydown

    Joined:
    Dec 11, 2015
    Posts:
    6
    this thread needs re-reviving... There's still no fix for this and it is now five years or so later from the first person posting about this. I'm having the exact same problem, and I'm going to try the two object method now, but it seems weird.
     
    dogzerx2 likes this.
  41. noio

    noio

    Joined:
    Dec 17, 2013
    Posts:
    54
    If you instantiate a game-object with a child, references (on the new object) to the child will point to the child of the new object. I.e. References are updated relatively to the new object. So a "self-reference" is updated to be a "self-reference" on the new object too. This is the thinking behind the mechanic.
     
  42. gspeager

    gspeager

    Joined:
    Jan 11, 2016
    Posts:
    23
  43. ThePilgrim

    ThePilgrim

    Joined:
    Apr 25, 2013
    Posts:
    2
    I solved this problem and avoided double prefabs by creating a singleton in which I dragged in the prefab references to all of the prefabs contained my script in which I needed a self-reference.

    On the self-referencing script, in the place of a reference to its own prefab, I instead added a string field called uniqueIdentifier. Each different prefab needs to have a unique value for this field. This can be defaulted to the name of the prefab if need be.

    Since the singleton has a reference to each of the prefabs, and the prefabs contain the script with the unique identifier, the singleton go through each of it's prefab references, get the component, and read that uniqueIdentifier string. With this, it can build a dictionary which links the string identifiers to the desired prefab.

    Now, when the scripts need to reference their own prefab, they can ask the singleton what prefab is associated with their uniqueIdentifier.

    Example code:
    Code (CSharp):
    1. public class SelfReferencePrefabManager : MonoBehaviour
    2. {
    3.  
    4.     public GameObject[] prefabs;
    5.     private Dictionary<string, GameObject> identifierToPrefabDictionary = new Dictionary<string, GameObject>();
    6.     public static SelfReferencePrefabManager instance;
    7.  
    8.     void Awake ()
    9.     {
    10.         instance = this;
    11.     }
    12.  
    13.     void Start ()
    14.     {
    15.         // Build dictionary
    16.         foreach (GameObject prefab in prefabs)
    17.         {
    18.             // get the script with the identifier string
    19.             SelfReferencingComponent selfReferenceComponent = prefab.GetComponent<SelfReferencingComponent>();
    20.             if (selfReferenceComponent != null)
    21.             {
    22.                 identifierToPrefabDictionary.Add(selfReferenceComponent.uniqueIdentifier, prefab);
    23.             }
    24.         }
    25.     }
    26.  
    27.     // Get the prefab by the string identifier. Returns null if it is not in the dicitonary.
    28.     public GameObject GetPrefabByIdentifier (string uniqueIdentifier)
    29.     {
    30.         GameObject prefab;
    31.         identifierToPrefabDictionary.TryGetValue(uniqueIdentifier, out prefab);
    32.         return prefab;
    33.     }
    34.  
    35. }
    36.  
    37. public class SelfReferencingComponent : MonoBehaviour
    38. {
    39.     public string uniqueIdentifier;
    40.  
    41.     public GameObject myOwnPrefab
    42.     {
    43.         get
    44.         {
    45.             return SelfReferencePrefabManager.instance.GetPrefabByIdentifier(uniqueIdentifier);
    46.         }
    47.     }
    48.  
    49.     void Start ()
    50.     {
    51.         // fail early in case we forgot to add the singleton to the scene
    52.         UnityEngine.Assertions.Assert.IsNotNull(SelfReferencePrefabManager.instance);
    53.     }
    54.  
    55. }
     
  44. ZDurst

    ZDurst

    Joined:
    May 1, 2014
    Posts:
    1
    If anyone is still running into something similar (I did), this is a pretty easy solution:
    i.e., if instantiating a new object on destroy:
    Code (CSharp):
    1.     void OnDestroy() {
    2.         YourScriptName yourScriptVariable = (Instantiate (prefabVariableName, new Vector3(x, y, z),Quaternion.identity)).gameObject.GetComponent<YourScriptName>();
    3.         yourScriptVariable.prefabVariableName = prefabVariableName;
    4.     }
    Where prefabVariableName is a variable referencing the original prefab you want to continue to use
    YourScriptName is the name of the script you are in with the above variable and doing the instantiating
    yourScriptVariable is a new variable created for holding the new prefab. You could shorten this into one line, but I like to think this is slightly easier to understand.

    We're instantiating the new copy and grabbing the script and putting it into a variable. We then access the prefab variable in the copy's script to point it at the one we were originally using, rather than at itself.
     
  45. maxizrin

    maxizrin

    Joined:
    Apr 13, 2015
    Posts:
    6
    Hit this bug when trying to grow mushrooms.
    Each mushroom holds the main mushroom prefab... or so I thought, but they spawned with the age of the first mushroom.

    Very strange, as I vaguely recall this working correctly on older versions (4.6 I think).

    I tried encapsulating the prefab in an array, this didn't work either.
     
  46. alxcancado

    alxcancado

    Joined:
    Aug 17, 2013
    Posts:
    5
    Same here. I just want a unique Game object based on my prefab, not a clone reference.