Search Unity

Bug Resources.FindObjectsOfTypeAll<T> Does not work for imported files from packages.

Discussion in 'Editor & General Support' started by mikeNspired, Jun 6, 2020.

  1. mikeNspired

    mikeNspired

    Joined:
    Jan 13, 2016
    Posts:
    82
    Code (CSharp):
    1.  public class SettingsFile: ScriptableObject
    2.     {
    3.         private static SettingsFile _instance;
    4.  
    5.         public static SettingsFile Instance
    6.         {
    7.             get
    8.             {
    9.                 if (_instance != null) return _instance;
    10.              
    11.                 _instance = Resources.FindObjectsOfTypeAll<SettingsFile>().FirstOrDefault();
    12.            
    13.                 if (_instance != null) return _instance;
    14.             }
    15.         }
    16.  
    If the file is imported from a unity package. This always returns null unless I move the imported file out of the folder to any place in the project. After moving the file anywhere, it finds the instance. Does anyone know of a way around this problem?
     
    io-games likes this.
  2. - Do not use static accessor on a ScriptableObject. Drag the object into a slot where you want to use it.
    - if you really need to then here is how you can do it safely (I don't recommend it):

    - if you want to check in Editor that one of these are already exists:
    https://docs.unity3d.com/ScriptReference/AssetDatabase.FindAssets.html with the t: search you can check.

    But if you want to boot up your static Instance variable, then this way:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.         private void OnEnable()
    3.         {
    4.             EditorApplication.playModeStateChanged += OnPlayStateChange;
    5.         }
    6.  
    7.         private void OnDisable()
    8.         {
    9.             EditorApplication.playModeStateChanged -= OnPlayStateChange;
    10.         }
    11.  
    12.         private void OnPlayStateChange(PlayModeStateChange state)
    13.         {
    14.             if(state == PlayModeStateChange.EnteredPlayMode)
    15.             {
    16.                 OnBegin();
    17.             }
    18.         }
    19. #else
    20.         private void OnEnable()
    21.         {
    22.             OnBegin();
    23.         }
    24. #endif
    25.         private void OnBegin()
    26.         {
    27.             Instance = this;
    28.         }
    29.  
    This is working both in the Editor and in the build in theory, unless I didn't mistype something, because it was from the top of my head.
     
  3. mikeNspired

    mikeNspired

    Joined:
    Jan 13, 2016
    Posts:
    82
    Have you seen the Unity Unite talk?
    "Overthrowing the MonoBehaviour tyranny in a glorious ScriptableObject revolution".

    This is almost exactly the code unity posted.
    Its also how steamVR does it but they load it from the Resources folder.

    This is a settings file for In editor use only, so I'll check out the AssetDatabase.findassets
     
  4. mikeNspired

    mikeNspired

    Joined:
    Jan 13, 2016
    Posts:
    82
    I didn't realize Resources was a special folder that could be used in any folder like Editor.
    I just did what steamVR did, and threw it into a Resources folder, that way I can keep my asset entirely contained in one folder.
     
  5. If it's editor only, that makes it even easier. Just use the OnEnable. It runs when you create/load the ScriptableObject. It doesn't run when you go in play mode.
    If this is editor only, it is probably a good idea to protect the entire file with #if UNITY_EDITOR in order to not to build into the runtime.

    I saw every ScriptableObject thing, I was play with the a lot. That's why I came to the conclusion to not to allow static accessor to any of them.