Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Editing prefab causes references to it to become null until the object referencing it is reloaded

Discussion in 'Prefabs' started by Prodigga, Oct 12, 2018.

  1. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    611
    Hi there

    I have been unable to reproduce this issue in a clean project with the 'exact same' setup.

    In our project we have a monobehaviour, that monobehaviour references a scriptable object, and that scriptable object has a reference to a prefab.

    On our monobehaviour, we have some editor functionality to instantiate that prefab at the position of the monobehaviour. This all works fine...

    However, if I edit the prefab in any way (Turn Shadows off on the meshrenderer, turn on/off a component, anything), the reference to that prefab on the scriptable object becomes 'null' but ONLY as seen by my scripts. If I breakpoint my insantiation code, it will see that prefab reference as 'null'. But if I view the scriptableobject in the inspector, it is NOT null. It has a valid reference to the prefab. Despite 'viewing' the scriptableobject in the inspector and confirming that the reference is not null, my code still thinks it is. Any attempts made by the Monobehaviour to access myScriptableObject.PrefabReference will return null.

    I can fix this problem in one of a few ways...

    • I can clear the reference on the scriptableobject, and drag and drop the prefab back into the reference slot. This corrects the problem.
    • I can reload/recompile assemblies. This fixes the problem.
    Once I 'fix' the problem using any of the 2 options, if I edit the prefab again, it'll break again. It isn't a permanent fix.

    The follow doesn't work:
    • Right clicking and reimporting the scriptable object. This doesn't fix the problem.
    • Saving and reloading the scene. The monobehaviour in the scene still sees the prefab reference on the scriptable object as null. This doesn't fix the problem.
    • Remove the scriptable object reference on the monobehaviour and drag and dropping the scriptable object back into field on the monobehaviour. This doesn't fix the problem.
    • Our prefabs were upgraded from 2018.2.. so to ensure the prefab itself wasn't the problem I created a new prefab from scratch, and set that prefab as the referenced prefab in the scriptable asset. When I make changes to the prefab, I get the same issue. This doesn't fix the problem.
    • Our scriptable objects were upgraded from 2018.2..to to ensure the scriptable object itself wasn't the problem I created a new scriptable object from scratch and set that scriptableobject as the referenced scriptableobject on the monobehaviour. This doesn't fix the problem.
    • Using both the scriptable object created from scratch, and making it reference the prefab that was also created from scratch doesn't fix the problem either. So it doesn't seem like there is an issue with the assets themselves.
    When I breakpoint my code, and inspect the reference, it still shows me valid values. Note how the object is null in the second image, but we can still see my test variables 'ShouldBe5' and 'ShouldSayTest' reporting correct values. Also interesting to note is that the CachedPtr has become 0x0, though that doesn't mean anything to me..

    'This' is the scriptable object.
    'SpanPrefab' is the reference to the prefab.

    Before Editing 'SpanPrefab' Prefab:

    ss1.PNG
    After editing 'SpanPrefab' Prefab:

    ss2.PNG
     
  2. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,180
    Thanks for bringing this to our attention. Any chance you could make the original project accessible to us and submit what you wrote here as a bug report?
     
  3. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    365
    Are your references by any chance in a List/Array/Collections?
     
  4. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    611
    No unfortunately. It's just a direct reference to script on another prefab. As you can see in the image above, there is a script called ShapeFenceGenerator which has a reference to a FencePost prefab and a FenceSpan prefab. If I edit either of these, that prefab reference suddenly becomes null.

    @LeonhardP I can give you access to our repository if you would like to pull it down and try for yourself. We do not want to publish our project via the bugtracker, since it is a bit of a black box, we don't know who is going to have access and it'll be up there in the bugtracker forever.
     
  5. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,180
    Could you please submit a bug report and reply with the issue ID? Then you can give the person handling your case access to your repository.
     
  6. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    3
    Has this issue been submitted? It's super easy to reproduce.
     
  7. snair692

    snair692

    Joined:
    Feb 2, 2016
    Posts:
    28
    Wondering this myself I came here because I have this same thing happening.

    In my case I had a prefab on the scene that stored a list of other prefabs. When I edited the prefab from the project folder window, the prefab on the scene would get a null reference on the list and I'd have to slide the prefab back onto it.

    This kept happening, until finally I "unpacked" the prefab that was holding the list script. Now this no longer is happening. I didn't really need that to be a "prefab" anyways but it does seem like it would be easy to re-produce.

    I should say though my project migrated over from previous version of Unity. Also while not intuitive I am able to select prefabs and tell them to all update/override at once, but they don't all seem to update/override at the same time.

    I kind of like the new system, but prefab references suddenly going null is a bit... scary=p
     
  8. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    611
    Yep we still have one stuburn prefab reference on one specific script that continues to go null. We just manually fix it whenever it happens. I can't reproduce it and we do not want to upload and give an unknown Unity dev/qa person access to our entire game, so we just put up with it for now. I've tried exporting the specific scripts and the specific prefabs in question into another project to see if it happens there but no luck. Can't reproduce.
     
  9. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    22
    We're also getting this issue. This is really very fundemental, and can be reproduced with just two scripts.

    One default Monobehaviour
    One with a serialized field and a context menu to Debug.Log the field.

    Add the 2nd script component to an object in the scene. Drag in a prefab reference to your serialized field (of type script 1). Log it - It won't be null.

    2) Edit the prefab, and save it.

    3) Log it - Now it's null.

    We've submitted a detailed bug report including a repro project. We'll need to delay releasing our next big asset until this is resolved :(
     
    gavagai likes this.
  10. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,432
    Thanks you, appreciated!

    If you post the case number here (when you have it) we can make sure to have a look soon next week.
     
    gavagai likes this.
  11. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    22
    Sure thing :)

    (Case 1116476) Prefab References are LOST when modifying prefab

    I've also checked in the absolute latest official release and it's still occurring. Cheers!
     
  12. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    365
    @DigitalSalmon

    This is really weird. If you change the reference type in Spawner to GameObject or Transform it works fine. It is only when the type is a Monobehaviour the issue is reproducable.

    I'll have a look, but consider using GameObject as a work around for now
     
    nongbenzgames likes this.
  13. nongbenzgames

    nongbenzgames

    Joined:
    Oct 8, 2018
    Posts:
    1
    I too have references in other scripts going missing when updating prefabs. Components randomly get new FileIDs for some reason according to my Git. This has happened since the beginning of new prefab workflows to the latest 2019 alpha13. Not sure if it's due to a faulty upgrade process but this has been project breaking for months and needs attention.
     
    trenthm and Prodigga like this.
  14. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    22
    If it helps - AssetDatabase.ForceReserializeAssets seems to help, as does marking things as dirty then saving the asset database. Useful in small cases, but not sustainable obviously!

    Our project is a clean 2018.3 we've only been using for a few weeks so it's not the upgrade process :)
     
  15. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    365
    Thanks, this will help in the investigation of the issue.

    Can you post your updated script here or PM to me?
     
  16. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    22
    Ahh afraid the use of those scripts was in a live project and has since been stripped out.

    Broadly speaking, it looked like this

    Code (CSharp):
    1.  
    2. PrefabStage.prefabSaved += PrefabStage_PrefabSaved;
    3.  
    4.     public static void PrefabStage_PrefabSaved(GameObject gameObject) {
    5.             string[] allAssetPaths = AssetDatabase.GetAllAssetPaths();
    6.             IEnumerable<string> paths = allAssetPaths.Where(p => p.EndsWith(".prefab")).Where(p => AssetDatabase.LoadAssetAtPath<Module>(p) != null);
    7.             paths = paths.Concat(allAssetPaths.Where(p => p.EndsWith(".prefab")).Where(p => AssetDatabase.LoadAssetAtPath<Blueprint.Blueprint>(p) != null));
    8.             paths = paths.Concat(allAssetPaths.Where(p => p.EndsWith(".asset")).Where(p => AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(Theme)));
    9.            
    10.             foreach (string path in paths) {
    11.                 Object loadedAsset = AssetDatabase.LoadMainAssetAtPath(path);
    12.                 EditorUtility.SetDirty(loadedAsset);
    13.             }
    14.            
    15.             AssetDatabase.SaveAssets();
    16.         }
    17.  
    Or instead of a dirty/save, we had previously had some success with ForceReserializeAssets, though I believe that was used in an AssetPostprocessor, or the OnWillSaveAssets in an AssetModificationProcessor.

    Sorry I can't be more specific - We tried many things, and hadn't clocked what was actually happening until we'd gone through a few 'fixes'.
     
  17. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    365
    Ok, I get it, after saving the prefab, you mark it dirty and save it again and you reference works correctly. Meaning I missed something in the prefab system to ensure MonoBehaviour references stays valid.

    Thanks.
     
  18. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    22