What does Object.DestroyImmediate(asset, true) do exactly?

The documentation wording is rather vague.

My assumption is that it would destroy the in-memory representation of an asset and free that memory.

I’ve seen speculations on the forums that it would physically delete the asset from the disk, but that seems highly unlikely, from the API design standpoint.

My use case: in the editor script (e.g., a custom MenuItem command), I’d like to load an asset using AssetDatabase.LoadAssetAtPath(“Assets/SomeAsset.prefab”), perform certain operations on it, and then unload it completely to release the memory it occupies. There’s a lot such assets to be processed, so releasing memory after we’re done with them is crucial.

Is Object.DestroyImmediate(asset, true) the right choice for this task, and if not - what’s the best way to unload assets in the editor script?

The middle part of AaronB’s answer is mostly correct. As the manual says, destroy has a delay before it does anything. Try this:

Destroy(g);
g.transform.position=Vector3.zero; // no error
if(ggg==null) Debug.Log("null"); // does not print

DestroyImmediate(g);
g.transform.position=Vector3.zero; // error - the gameObject you are...

Also, google “Unity destroyImmediate” and you’ll find this same Q with more discussion.

Not exactly, as shown in Unity’s Section on Optimization in the docs, Unity will periodically remove anything from Memory that doesn’t have any active object referencing it.


So from my understanding, the difference between Destroy and DestroyImmediate is that Unity will normally destroy the object, wait till the end of the frame update, then remove any references to the object in the scene.
DestroyImmediate, on the other hand, will remove all references to the object immediately, not waiting for the end of the frame. As displayed in the documentation, it’s not recommended to use at runtime, although there are occasions where it can be needed if you have to have an object destroyed before running further code.


So in your case, it probably wouldn’t make much difference, so it’s probably better to just go with Destroy, since DestroyImmediate can mess with the timings of other functions if overused.

To clarify, I’m interested specifically in Object.DestroyImmediate(object, bool) overload.

The difference between Object.Destroy() and Object.DestroyImmediate() is pretty clear from the documentation, and I can’t use Object.Destroy() anyway, because it’s an editor script.

About Object.DestroyImmediate(asset, true)


The overload with 2 arguments would allowing destroy asset object from disk. Which is not you want. If you were to call DestroyImmediate(asset)on object returned from AssetDatabase.LoadAssetAtPath you would get error in editor saying that “destroying asset is prevented, use 2nd overload instead”.

.

And that’s what 2nd overload do.

.

Then what about correct way to modify prefab content while releasing it properly? See next topic below.


The correct way to modify prefab in editor script


The object returned from AssetDatabase.LoadAssetAtPath is surprisingly, not really a “source” prefab, it is library version of the prefab (the one that unity “imported” from source prefab on the disk)

.

So modifying it would require a roundabout to mark it dirty, then tell unity to save it, then have unity “flush” it back to source version in disk.

.

The very direct and correct way, with proper cleaning, is to use function from PrefabUtility. Read the indepth discussion here: FORUM LINK

PrefabUtility.LoadPrefabContents
PrefabUtility.SaveAsPrefabAsset
PrefabUtility.UnloadPrefabContents

Or if you are already using 2020, unity has a IDisposable scope for you. (see example in API doc)

TIPS:

While editing lots of prefabs, it would reasonable to wrap it around StartAssetEditing and StopAssetEditing so that unity stops AUTO import things while we modifying.

AssetDatabase.StartAssetEditing( );
// Modifying code
AssetDatabase.StopAssetEditing( );

After editing, it would be very reasonable to call

AssetDatabase.Refresh( );