Hi All,
I know this issue has come up before, but I can’t find a working solution. I’ve read about [System.Serializable] and EditorUtility.SetDirty (which is obsolete) but nothing seems to be working.
So, the problem I’m having is that when I change some values in the prefabs, Unity doesn’t store the changes.
Here’s screen recording of the issue.
Component code
using UnityEngine;
public class ObjectProperties : MonoBehaviour
{
public string i_baseMaterialName;
public Material e_baseMaterial;
}
Menu item code, that changes the value on the component
using UnityEngine;
using UnityEditor;
public class TopMenu
{
[MenuItem("Tools/Update From Library")]
public static void UpdateFromLibrary()
{
foreach (ObjectProperties partProp in GameObject.FindObjectsOfType<ObjectProperties>())
{
partProp.e_baseMaterial = AssetDatabase.LoadAssetAtPath("Assets/" + partProp.i_baseMaterialName + ".mat", typeof(Material)) as Material;
}
}
}
How can I make it store the values?
Here’s the full project, in case that’s more helpful.
Thanks,
Nick
Looks like your not dirtying the scene (which usually is shown by an asterix * after the “PC, Max & Linux Standalone” part of the top of the window). Without that, Unity doesn’t know your scene has been modified, and may not save any changes.
Try calling this after the foreach loop:
EditorSceneManager.MarkAllScenesDirty()
Many thanks for the reply. I’ve tried that and it doesn’t work. It does mark the scene dirty and you do get a prompt to save, but the property/field is not made bold letters, so Unity ignores the change for this field.
I just managed to make it work with Undo.RecordObject (which apparently replaced EditorUtility.SetDirty 5.3+), but I’ll probably going to change a few hundreds of properties, so I don’t know if it’s the best approach, creating and undo for each field.
I think you would need to ‘apply’ your prefab from code before saving scene. You can use following:
PrefabUtility.ReplacePrefab(instance, PrefabUtility.GetPrefabParent(instance), ReplacePrefabOptions.ConnectToPrefab);
If you don’t want your data in prefab to be replaced you probably should use PrefabUtility.DisconnectPrefabInstance().
Otherwise your data will be replaced using values that are saved in prefab.
Thanks Mathew.
I tried both suggestions. First one, works only for the last prefab in the loop. Disconnecting the prefab, seems to work better for me.
Both options though were losing the changes as soon as I was opening another scene, so I had to use
EditorSceneManager.MarkAllScenesDirty()
as bobisgod234 suggested.
Not sure if disconnecting the prefab is a best way forward, but it should be OK in this case, so thanks both of you. I’ll do some more testing later today.