How can I overwrite .asset using AssetDatabase.CreateAsset?

I have a TestObject class derived from ScriptableObject and an EditorWindow to edit and save it.
When I edit the TestObject using the EditorWindow and save it using AssetDatabase.CreateAsset, it works well for the first time.

But if I edit and save again with the window open, it fails with an error message,

Couldn’t add object to asset file
because the MonoBehaviour ‘TestObject’
is already an asset at
‘Assets/TestObject.asset’!

How can I save my TestObject for the second time?
The code is below:

using UnityEngine;
using System.Collections;
using UnityEditor;

public class TestWindow : EditorWindow {

	private TestObject m_test_obj;

	[MenuItem("MyMenu/ShowWindow")]
	public static void Open()
	{
		GetWindow<TestWindow>();
	}

	public void OnEnable()
	{
		m_test_obj = CreateInstance<TestObject>();
	}

	public void OnGUI()
	{
        // TestObject has one int variable named 'bar'.
		m_test_obj.bar = EditorGUILayout.IntField("test variable", m_test_obj.bar);

		if (GUILayout.Button("save"))
		{
			AssetDatabase.CreateAsset(m_test_obj, "Assets/TestObject.asset");
		}
	}
}

I’ve been wondering around this problem too and I found the following solution. Here’s how it should look with your code

if (GUILayout.Button("save"))
         {
 if (!AssetDatabase.Contains(m_test_obj))
             AssetDatabase.CreateAsset(m_test_obj, "Assets/TestObject.asset");
         }

It checks if assetDatabase has that object. If there’s no object, it creates an asset, otherwise it overwrites existing one, in case you edit the through your editor.

This is interesting, because the scripting reference specifically states that it will overwrite existing assets… :smiley:

Similar to how terraKote suggested, you could either try AssetDatabase.SaveAssets() or delete the asset before saving it. Something like this:

if (GUILayout.Button("Save")) {
    // Approach with SaveAssets
    if (AssetDatabase.Contains(m_test_obj)) { AssetDatabase.SaveAssets(); }
    else { AssetDatabase.CreateAsset(m_test_obj, "Assets/TestObject.asset"); }

    // Approach with DeleteAsset
    if (AssetDatabase.Contains(m_test_obj)) { AssetDatabase.DeleteAsset("Assets/TestObject.asset"); }
    AssetDatabase.CreateAsset(m_test_obj, "Assets/TestObject.asset");
}

EDIT:
The manual says that EditorApplication.SaveAssets()will be deprecated in a future release, so you should not rely on it, but AssetDatabase.SaveAssets() is NOT the same as EditorApplication.SaveAssets(), so it should be fine (thanks for @CyRaid for pointing this out).

Hi ! I have same problem.

 void SaveMachineData()
    {

      
        foreach(GameObject obj in Selection.gameObjects) {
           
           string dataPath = "Assets/RepairSystem/manager/resources/machinesData/data/";
            dataPath += "rolnicze/" + obj.name + ".asset";


            if (AssetDatabase.Contains(MachinesDesignerWindow.RolniczeInfo)) { AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log(obj.name); }
            else
            {
               
                AssetDatabase.CreateAsset(MachinesDesignerWindow.RolniczeInfo, dataPath);
            }
          
        



        if (Selection.Contains(obj))
            {

                if (!obj.GetComponent<Rolnicze>())
                        obj.AddComponent(typeof(Rolnicze));
                    obj.AddComponent(typeof(BoxCollider));
                    obj.GetComponent<Rolnicze>().rolData = MachinesDesignerWindow.RolniczeInfo;
           
            }

            

        }
    
    }
}

There’s any option for create asset for every selected GameObject? When i create asset with selected BOX its ok asset is created. But if i select another gameObject like Sphare only copy my box.asset instead of create the new one for Sphare. Can you help me guys?:slight_smile: