4
\$\begingroup\$

I'm working with AssetDatabase.CreateAsset and all over the internet (not so much in the official documentation) I see

AssetDatabase.CreateAsset(blah, blahPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();

Why?

SaveAssets says it Writes all unsaved asset changes to disk so I assume that there's a situation in which you can have changes to your assets in memory, but not on disk. Is this the case when you create an asset with CreateAsset? I tried ending the Unity process right after creating a file but it looks like it writes to disk immediately, but I've only tried in-editor on Windows. Maybe it behaves differently in runtime or on different platforms.

Refresh says it will import any assets that have changed their content modification data or have been added-removed to the project folder. The editor UI gets updated when I call CreateAsset even if I don't Refresh, so is this for updates from other sources, or what?

I'm trying to understand the process and not do things just because everyone does it like that.

\$\endgroup\$
1
  • \$\begingroup\$ I'm not familiar with AssetDatabases, but the general rule is, if the documentation doesn't support something, you are not supposed to use it that way. Obviously there are exceptions, but then its up to you. \$\endgroup\$ – TomTsagk Aug 31 '18 at 15:14
3
\$\begingroup\$

Unity lacks clarity in its documentation on when to use different AssetDatabase methods. That's why a lot of people call all the available methods after an asset change just to be sure.

Robert C. Martin provides a good piece of advice in his "Clean Code" book: When you are not sure how API works, write unit tests for it. Not only will you learn how to use it, but when there are new releases, just running those tests again will detect if there are changes you should know of.

That's what I did, and you can run those tests on your machine too: https://gist.github.com/SolidAlloy/3027f88e69b63700b9ae530360cfd0eb

Here is what I discovered:

  • CreateAsset() and ImportAsset() add the file to AssetDatabase automatically, so you don't have to call any other methods.
  • AssetDatabase.Refresh() is only needed when a file was added through System.IO (like File.WriteAllText()). Without it, you will not be able to get the asset GUID or load a Unity.Object from the asset.
  • AssetDatabase.SaveAssets() is only needed when you made changes to a Unity.Object instance (e.g. ScriptableObject), marked the object as dirty, and want to see the changes written to disk. Unity Editor writes all the changes to disk upon exit, so the use of SaveAssets() is very limited. It is only helpful when you changed a scriptable object and want to open the .asset file in a text editor and see the changes there without closing the editor.

I also discovered a weird bug/feature that may cause a lot of headaches if you are not aware of it:
If you create an asset and then remove it, AssetDatabase will store the deleted asset GUID and path until the Editor closes. No method can remove the GUID from the database.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Great answer! Thanks for sharing all these details and the tests to back it up! \$\endgroup\$ – DMGregory Jan 20 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.