有效的 AssetBundle 在任何 API 调用中抛出空引用异常 (NRE)
Valid AssetBundle Throws Null Reference Exception (NRE) With Any API Call
这个问题不是关于什么是空引用,这个问题是关于为什么一个有效的 AssetBundle 在 API 我无法单步执行
我一直在将我的项目从使用 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 会导致空引用异常。
我什至无法单步执行代码来查看什么是 null。 AssetBundle 本身不是 null,但是任何调用都会导致这个。
关于如何进一步调试这个问题或问题可能是什么的任何建议?
在
AssetBundle _scriptableObjectsBundle = ...
您否决(隐藏)您已经存在的同名字段变量 _scriptableObjectsBundle
... 所以这个外部字段 _scriptableObjectsBundle
仍然是 null
!而您实际分配的那个只存在于
if(_scriptableObjectsBundle == null)
块→只需删除这个额外的 AssetBundle
_scriptableObjectsBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/scriptableobjects");
这个问题不是关于什么是空引用,这个问题是关于为什么一个有效的 AssetBundle 在 API 我无法单步执行
我一直在将我的项目从使用 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 会导致空引用异常。
我什至无法单步执行代码来查看什么是 null。 AssetBundle 本身不是 null,但是任何调用都会导致这个。
关于如何进一步调试这个问题或问题可能是什么的任何建议?
在
AssetBundle _scriptableObjectsBundle = ...
您否决(隐藏)您已经存在的同名字段变量 _scriptableObjectsBundle
... 所以这个外部字段 _scriptableObjectsBundle
仍然是 null
!而您实际分配的那个只存在于
if(_scriptableObjectsBundle == null)
块→只需删除这个额外的 AssetBundle
_scriptableObjectsBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/scriptableobjects");