AssetDatabase.LoadAssetAtPath returns Null in Batchmode

I’m trying to read an asset, a ScriptableObject defined by:

using UnityEngine;

[CreateAssetMenu(fileName = "BuildScenes", menuName = "Editor Build Scenes", order = 100)]
public class EditorBuildScenes : ScriptableObject
{
    public string[] Scenes;
}

in a Batchmode script which is called from EditorApplication.update, like this:

EditorBuildScenes list = AssetDatabase.LoadAssetAtPath(“Assets/Scenes/DemoBuildDefs/Demo.asset”);

And every time, no matter what, list is null.

If I call AssetDatabase.AssetPathToGUID(“Assets/Scenes/DemoBuildDefs/Demo.asset”), I do indeed get the proper GUID back.

And if I convert that back to a path with GUIDToAssetPath, it still works.

Heck, if I do a LoadAllAssetsAtPath(“Assets/Scenes/DemoBuildDefs/Demo.asset”), I’ll get an array of size one, but I cannot cast that back to an EditorBuildScenes (the cast returns null).

If I look at the serialized .asset YAML, I see it is a m_EditorClassIdentifier: Assembly-CSharp::EditorBuildScenes, so it looks like it should work.

Does anyone have any idea why this simply will not work?

We’re having the same issue right now. I’m having a little bit more luck with AssetDatabase.FindAssets, but it’s still inconsistent. My last two days have just been debugging this. :frowning:

Be careful with AssetDatabase.FindAssets, it gets out of sync if you rename a script:
https://issuetracker.unity3d.com/issues/assetdatabase-is-not-updated-after-saving-renamed-script-name-which-is-referenced-in-asset

… and then does not find the type anymore until you reimport all those assets. I find it more reliable to use AssetDatabase.GetAllAssetPaths and do the “find” myself.

I gave up. I literally hard-coded my lists of scenes to include in a build in the Build Script. It was 2am and I needed to get things done.

I don’t understand why in Batchmode the asset will not cast to its type, but in the actual Editor the same code works fine.

@f0ff886f So this may not help in your specific case, but it seems that calling some of these functions from a static constructor caused our issues. I took them out of the static constructor and instead called them explicitly, and everything seems to be working fine now!

I seem to remember Unity sometimes getting confused when calling Unity functions from static or sometimes even non-static constructors, thinking that they’re called on a different thread. I hope this helps!

@Peter77 Thanks for the tip! And yeah, I’ve definitely had issues with that in the past. I think FindAssets will work for us, but good to know there’s a workaround if we need it. :slight_smile:

1 Like

Holy shit… so wait, are you saying in the static constructor you instantiate another class and inside that class do your processing?

That’d be a fun workaround :slight_smile: For me hardcoding stuff directly into the source is fine, but in the future I may come back and try to fix this the right way. Thank you for the information!

Not exactly; I just moved the contents of the static constructor to an ‘Init()’ function that is called at the beginning of every function in that class (only if it hasn’t already been run, of course).

Oddly enough, that same code works when that static constructor is called via InitializeOnLoad, but not after the scripts are recompiled and that class was referred to again.

No problem!

1 Like