Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question In-Scene Prefab Properties not Updating when Modifying Asset via Custom Script

Discussion in 'Prefabs' started by MitchCroft, Dec 29, 2020.

  1. MitchCroft


    Apr 20, 2018
    Hi forum users, I’m hoping someone here might be able to give me some direction on a problem I’ve been having. I have a custom editor script running (Custom property drawer, if it matters) where I’m modifying the actual objects that are referenced by a SerializedProperty.

    After the inspector field has been modified, the value is extracted and applied to my properties and I’m using the ISerializationCallbackReceiver interface to convert the live data to and from serializable versions of the data. I’ve got everything working for multiple instances, undo/redo application and the like (So far as I’ve seen anyway) but I’m having a small problem when it comes to prefabs.

    I’m using the below code section to handle the assigning of data and recording it on the undo stack:
    Code (CSharp):
    1. // Record the changes to the target objects that are about to have their data modified
    2. Undo.RecordObjects(property.serializedObject.targetObjects, "SerialData Modified");
    4. // Apply the new data to the specified objects
    5. object toApply = storage[0].GetValue();
    6. for (int i = 0; i < data.Length; ++i) {
    7.     // If the data can't be assigned, warn the user and hope they can figure it out
    8.     if (!data[i].SetValue(toApply, data[i].DataType))
    9.         Debug.LogErrorFormat("Failed to apply the data value '{0}' to the object of type '{1}'", toApply, data[i].DataType);
    11.     else {
    12.         // Apply the data changes to the serial storage for record
    13.         data[i].OnBeforeSerialize();    // <- Takes the object value and type and converts them to string values for properties marked with [SerializeField]
    15.         // Record any prefab changes that are needed for updates
    16.         PrefabUtility.RecordPrefabInstancePropertyModifications(property.serializedObject.targetObjects[i]);
    17.     }
    18. }
    When I modify a prefab instance within the scene it behaves as expected, marking the field as overridden for the instance and I can apply it back to the prefab asset if I want. However if I modify the field on the asset it doesn’t (immediately) update on the instances within the loaded scenes. They maintain their previous value and it’s not marked as an override. However if I reload the scene or trigger undo/redo actions via the editor the value updates as expected.

    I can’t profess any particular expertise into how the Unity prefab system works in regards to this but my guess was that the in-scene instances are not being updated when the asset is? I’ve looked for a function that I can call to refresh the values of the prefabs but can’t seem to find anything in PrefabUtility. Is there something that I’m missing or a method that you know of that can be used to get the scene instances to update as one would expect from a regular value?

    Any help would be greatly appreciated, many thanks in advance