Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Bug Сhanges to the values in the inspector cause the object reference to be lost

Discussion in '2020.1 Beta' started by HedgehogNSK, Mar 25, 2020.

  1. HedgehogNSK


    Jun 3, 2017
    When I change some values of class field attached to prefab in the inspector, Unity for some reason destroys instance of prefab (or just script) and instantiate new with changed values.

    Noteworthy, in the inspector it looks like flash-reload when you change value not in Prefab Mode and nothing happens when you make changes in Prefab Mode.

    The funniest thing is that after changing value, destructor calls 2 times: first time for old values, second time for new values?
    Is that normal behaviour?

    More details under the spoiler:
    I found that when I were trying to create instance guid control system, where guid is a field of class and there is method in class that checks for another instances with equal guids. This method calls from OnValidate method. So every new class instance is adding by it self to static list. And when instance found another instance with equal guid value it recalculates. But someone changes value in inspector you'll get to OnValidate method several times.

    So I have static list of references to my class instances.
    At first time when I check in OnValidate method if list contains reference to the current instance List.Contains method returns "true" and everything is fine.

    But then algorithm goes to the OnValidate method againd. At second time I see that the object of current name is already in the list, but List.Contains method concludes that it's not and then adds this object to the list.

    After that I get to the OnValidate third time and for this moment both instance references have been changed to nulls. There are 1 or 2 more entrances in OnValidate method.

    Code example and gif:
    Code (CSharp):
    2. public abstract class RuntimeSet<T> : ScriptableObject, IEnumerable<T>
    3.     {
    4.         [SerializeField]protected List<T> items = new List<T>();
    5.         public IEnumerable<T> Items => items;
    6.         public void Add(T obj)
    7.         {
    8.             if (!items.Contains(obj))
    9.                 items.Add(obj);
    10.         }
    11.         public void Add(IEnumerable<T> objects)
    12.         {
    13.             items = items.Union(objects).ToList();
    14.         }
    15. ...
    16. }
    Code (CSharp):
    3. public class Clipart : MonoBehaviour, IClipartView, IGood, ISerializationCallbackReceiver
    4.     {
    5.         //[HideInInspector]
    6.         [SerializeField] string guidString;
    7.         [SerializeField] RuntimeSet<Clipart> runtimeCliparts = null;
    8. ...
    9. public void OnValidate()
    10.         {
    11.             runtimeCliparts?.Add(this);
    12.         }
    13. ...
    14. }

    Sorry for my english. It's hard to write so long message.:)
  2. brunocoimbra


    Sep 2, 2015
    Did I misunderstood, or are you trying to add a scene object reference to a scriptable object? Because this is not supported AFAIK.
  3. HedgehogNSK


    Jun 3, 2017
    Nope. As you can see at start of the gif I'm trying to add prefab reference from assets folder to scriptable object. This is just for clarity, to show that object reference is missing after changing values in inspector. In real project there are static list with same issue. But gif recorded from debugger is less clear.
    Last edited: Mar 26, 2020