Search Unity

Question Resources.LoadAll shows error "InvalidCastException" and "Null Exception" while type casting.

Discussion in 'Scripting' started by TCYeh, Nov 24, 2022.

  1. TCYeh

    TCYeh

    Joined:
    Jul 25, 2022
    Posts:
    55
    I'm trying to load my scriptable object (LocaleFilesData) from the Resources folder.
    Here is the code:

    Code (CSharp):
    1. UnityEngine.Object[] test1 = Resources.LoadAll("Localization", typeof(LocaleFilesData));
    2. Debug.Log($"Resources {test1.Length} {test1[0].GetType()}");
    3.  
    4. LocaleFilesData[] test2 = (LocaleFilesData[])Resources.LoadAll("Localization", typeof(LocaleFilesData));
    5. Debug.Log($"Resources {test2.Length} {test2[0].GetType()}");
    6.  
    7. LocaleFilesData[] test3 = Resources.LoadAll("Localization", typeof(LocaleFilesData)) as LocaleFilesData[];
    8. Debug.Log($"Resources {test3.Length} {test3[0].GetType()}");
    Test1 runs properly.
    Test2 shows an error: "InvalidCastException: Specified cast is not valid."
    Test3 shows another error: "NullReferenceException: Object reference not set to an instance of an object."

    If I first save the Object[] and type casting separately like below, it can also run properly.
    Code (CSharp):
    1. UnityEngine.Object[] test1 = Resources.LoadAll("Localization", typeof(LocaleFilesData));
    2. LocaleFilesData data = (LocaleFilesData)test1[0]; // data != null
    Could anyone tell me why?
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    241
    You need a cast for every object in the array.

    Code (CSharp):
    1. // use generic
    2. LocaleFilesData[] allLocalFiles = Resources.LoadAll<LocaleFilesData>("Localization");
    3.  
    4. // array converter
    5. LocaleFilesData[] allLocalFiles = Array.ConvertAll(Resources.LoadAll("Localization", typeof(LocaleFilesData)), (i) => (LocaleFilesData)i);
    6.  
    7. // or linq cast
    8. LocaleFilesData[] allLocalFiles = Resources.LoadAll("Localization", typeof(LocaleFilesData)).Cast<LocaleFilesData>().ToArray();
     
  3. TCYeh

    TCYeh

    Joined:
    Jul 25, 2022
    Posts:
    55
    @samana1407 Thank you so much for your reply! It works!! Thank you!!!

    However, I actually use a similar statement to implement Singleton Scriptable Object for different projects.
    So far, everything is good, except for the one I posted in this thread.
    Is this due to my luck? Or it's any difference between the two statements (since it is generic?)?

    The code is as below:
    Code (CSharp):
    1. public class SingletonScriptableObject<T> : ScriptableObject where T : ScriptableObject
    2. {
    3.     private T instance;
    4.     public T Instance
    5.     {
    6.         get
    7.         {
    8.             if (instance == null)
    9.             {
    10.                 T[] targets = Resources.LoadAll("", typeof(T)) as T[];
    11.  
    12.                 if (targets == null || targets.Length <= 0)
    13.                 {
    14.                     Debug.LogError($"Singleton Scriptable Object not found: {typeof(T).Name}");
    15.                 }
    16.                 else if (targets.Length > 1)
    17.                 {
    18.                     Debug.LogError($"Multiple Scriptable Objects found: {typeof(T).Name}");
    19.                 }
    20.                 else
    21.                 {
    22.                     instance = (T)targets[0];
    23.                 }
    24.             }
    25.             return instance;
    26.         }
    27.     }
    28.  
    29. }
    Sorry for keep bothering you:( Thank you again for your reply!