Search Unity

Question How do I monitor a scriptable object for inspector changes?

Discussion in 'UI Toolkit' started by Xelnath, Jul 8, 2022.

  1. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I have a custom editor in UIElements, which allows you to select scriptable objects and edit them in the inspector.

    How do I get a callback when that object is marked dirty / saved so that I can refresh the custom editor as well?
     
  2. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    The closest I've been able to get is this. However, there is no easy way to get from instanceId to the game object.

    Code (CSharp):
    1.  
    2. ObjectChangeEvents.changesPublished += (ref ObjectChangeEventStream stream) =>
    3. {
    4.     Log.Info($"{stream.length}");
    5.     for (int i = 0; i < stream.length; ++i)
    6.     {
    7.         var eventKind = stream.GetEventType(i);
    8.         if (eventKind == ObjectChangeKind.ChangeAssetObjectProperties)
    9.         {
    10.             stream.GetChangeAssetObjectPropertiesEvent(i, out ChangeAssetObjectPropertiesEventArgs data);
    11.  
    12.             // I would have preferred to filter by class type, but...
    13.             if (data.instanceId == ActiveTimeline.GetInstanceID())
    14.             {
    15.                 RefreshUI();
    16.             }
    17.  
    18.             if (AssetDatabase.GetAssetPath(data.instanceId) == AssetDatabase.GetAssetPath(ActiveTimeline))
    19.             {
    20.                 RefreshUI();
    21.             }
    22.  
    23.         }
    24.     }
    25. };
     
  3. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    Hi, have you looked into the Serialized Property bindings system ?
    It handles updating standard fields automatically but also allows you to get callbacks for property changes.

    Hope this helps.
     
  4. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I looked at it, but it was a bit convoluted for what I needed. A visual editor that doesn't map 1:1 with certain elements, so really I just need to know when the asset involved has changed for force a screen refresh.

    For example, each of these bars maps to a scriptable object:
    upload_2022-7-8_13-10-4.png
    There is no direct editing of any values here, so binding makes no sense.

    However, dragging the bars around changes the values inside the scriptable object, so if the user edits those fields inside a scriptable object, I need to refresh the UI to keep them in sync. (e.g if you manually change the duration, I want the screen to update immediately)

    I don't immediately see an example to have a 'generalized' registration for the object changing via binding.

    an example here of the backing objects:
     
  5. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
  6. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    There is a method for observing an entire SerializedObject, which can be created to represent a ScriptabeObject (example).
     
    Mnemotic likes this.
  7. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Now that sounds right on the money! Thank you