Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

AssetDatabase.LoadAssetAtPath returns Null in Batchmode

Discussion in 'Windows' started by f0ff886f, Jul 11, 2019.

  1. f0ff886f

    f0ff886f

    Joined:
    Nov 1, 2015
    Posts:
    155
    I'm trying to read an asset, a ScriptableObject defined by:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "BuildScenes", menuName = "Editor Build Scenes", order = 100)]
    4. public class EditorBuildScenes : ScriptableObject
    5. {
    6.     public string[] Scenes;
    7. }
    in a Batchmode script which is called from EditorApplication.update, like this:

    EditorBuildScenes list = AssetDatabase.LoadAssetAtPath<EditorBuildScenes>("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?
     
  2. lasercannon

    lasercannon

    Joined:
    Nov 29, 2012
    Posts:
    70
    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. :(
     
  3. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    3,892
    Be careful with
    AssetDatabase.FindAssets
    , it gets out of sync if you rename a script:
    https://issuetracker.unity3d.com/is...amed-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.
     
  4. f0ff886f

    f0ff886f

    Joined:
    Nov 1, 2015
    Posts:
    155
    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.
     
  5. lasercannon

    lasercannon

    Joined:
    Nov 29, 2012
    Posts:
    70
    @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. :)
     
  6. f0ff886f

    f0ff886f

    Joined:
    Nov 1, 2015
    Posts:
    155
    Holy S***... 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 :) 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!
     
  7. lasercannon

    lasercannon

    Joined:
    Nov 29, 2012
    Posts:
    70
    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!