首页 > 解决方案 > 有效的 AssetBundle 通过任何 API 调用引发空引用异常 (NRE)

问题描述

这个问题不是关于什么是空引用,这个问题是关于为什么有效的 AssetBundle 在我无法单步执行的 API 中抛出 NRE

我一直在将我的项目从使用 Resource 文件夹转换为 AssetBundles。我已在“scriptableobjects”资产包中标记了我的可编写脚本的对象,并将该包加载并存储在“Assets/AssetBundles”文件夹中。

这是我构建资产的代码:

public class AssetBundleManager
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string assetBundleDirectory = "Assets/AssetBundles";
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }

        //https://docs.unity3d.com/Manual/AssetBundles-Building.html
        BuildPipeline.BuildAssetBundles(assetBundleDirectory,
                                        BuildAssetBundleOptions.UncompressedAssetBundle,
                                        BuildTarget.StandaloneWindows);
    }
}

在查看下面的代码之前,这里证明了 AssetBundle 在使用时不为空:

在此处输入图像描述

构建资产后,我将实际加载这些资产及其资源:

public class X_AssetBundleManager : MonoBehaviour
{
    private static Maps _maps;
    private static AssetBundle _scriptableObjectsBundle;

    public static T LoadScriptableObject<T>(string assetName) where T : ScriptableObject
    {
        if (_scriptableObjectsBundle == null)
        {
            AssetBundle _scriptableObjectsBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/scriptableobjects");
            if (_scriptableObjectsBundle == null)
            {
                Debug.Log("Failed to load 'scriptableobjects' AssetBundle!");
                return null;
            }
        }

        if (_scriptableObjectsBundle.Contains(assetName)) // NRE HERE
        {
            Debug.Log("DOES CONTAIN");
        }
        else
        {
            Debug.Log("DOES NOT CONTAIN");
        }

        try
        {
            // NRE HERE
            var all = _scriptableObjectsBundle.LoadAllAssets();
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }

        T obj = _scriptableObjectsBundle.LoadAsset<T>(assetName); // NRE HERE
        if (obj == null)
        {
            Debug.LogError("Failed to load " + assetName + "  in scriptableobjects");
        }
        return obj;
    }
}

_scriptableObjects变量不为空。它是一个有效的对象。但是,在其上调用 ANY api 会导致空引用异常。

我什至无法通过代码查看什么是空的。AssetBundle 本身不为空,但任何调用都会导致此问题。

有关如何进一步调试此问题或问题可能是什么的任何建议?

标签: c#unity3dasset-pipelineassetsassetbundle

解决方案


AssetBundle _scriptableObjectsBundle = ...

你否决(隐藏)你已经存在的同名字段变量_scriptableObjectsBundle......所以这个外部字段_scriptableObjectsBundle仍然存在null!而你实际分配的那个只存在于

if(_scriptableObjectsBundle == null) 

块 → 只需删除这个额外的 AssetBundle

_scriptableObjectsBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/scriptableobjects");

推荐阅读