尝试在MonoGame中加载SpriteFont时发生NullReferenceException

时间:2018-09-16 15:28:02

标签: c# winforms xna game-engine monogame

好的,我正在为一个问题而苦苦挣扎,而且还不知道该怎么做。我一直在构建自己可以使用的游戏框架/引擎,它由游戏引擎本身和一个单独的WinForms编辑器应用程序(使用MonoGame.Forms)组成,该应用程序引用了我可以用来生成数据文件的引擎dll。由引擎使用(场景文件,实体类型,材料等)。该编辑器应用程序与游戏完全独立,并运行自己的Game子类。当用户从游戏中选择项目文件夹和场景文件时,编辑器将尝试从该文件夹中加载所需的任何资产。

到目前为止,我一直在通过FromStream方法加载纹理和声音来回避内容管道。现在的问题是我要包含文本,因此我必须使用内容管道,因为我还没有找到任何从流中加载精灵字体的方法。而且我似乎无法在编辑器中加载spritefont。当我运行游戏项目时,所有项目都可以正常工作,并且字体会加载并绘制到屏幕上。当我尝试在编辑器中打开该项目时,加载由NullReferenceException引起的spritefont时发生崩溃。

这是我用来加载资产的代码:

public Resource GetResource<Resource>(string resourceFile, string bundle, bool reload = false) where Resource : Cv_Resource, new()
{
    var resource = new Resource();
    resource.File = resourceFile;

    var isOwnedByResManager = resource.VIsManuallyManaged();
    Cv_ResourceData resData;
    if (/** file has been loaded already**/)
    {
        /** return asset in memory **/
    }
    else
    {
        Cv_ResourceBundle resBundle;

        if (!m_ResourceBundles.TryGetValue(bundle, out resBundle))
        {
            /** could not find resource bundle (a subclass of ContentManager) in the list **/
        }

        if (isOwnedByResManager)
        {
            /** do stuff with files that don't use the content pipeline **/
        }
        else
        {
            /** calls VLoad of the specific resource type, which loads the resource **/
            if (!resource.VLoad(resourceFile, null, out size, resBundle))
            {
                /** error loading resource **/
            }
        }
    }

    return resource;
}

这是Font资源的VLoad方法:

public bool VLoad(string resourceFile, Stream resourceStream, out int size, Cv_ResourceBundle bundle)
{
    try {
        var resource = Path.GetFileNameWithoutExtension(resourceFile);
        /** EXCEPTION IN THIS NEXT LINE **/
        var font = bundle.Load<SpriteFont>(resource); /** bundle is a subclass of ContentManager so this just loads the content as you would do normally in MonoGame **/

        var resData = new Cv_SpriteFontData();
        resData.Font = font;
        ResourceData = resData;

         /** Do some other stuff here **/

       return true;
    }
    catch (Exception e)
    {
        /** handle the error **/
    }
}

在编辑器中,当我打开项目文件夹并将其RootDirectory设置为该文件夹中的子目录(在本例中为名为Assets的目录)时,我将实例化资源束。当在与Assets文件夹相同的目录上运行游戏引擎时,此方法效果很好,但是由于编辑器是单独运行的,因此加载sprite字体似乎有困难。在Assets文件夹中,我同时拥有内容项目生成的xnb和spritefont文件,这些文件似乎没有问题,因为它们已正确加载到游戏中。

这是我尝试在其中加载文本的场景时遇到的错误:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Xna.Framework.Content.Texture2DReader.Read(ContentReader reader, Texture2D existingInstance)
   at Microsoft.Xna.Framework.Content.ContentTypeReader`1.Read(ContentReader input, Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.InnerReadObject[T](T existingInstance)
   at Microsoft.Xna.Framework.Content.SpriteFontReader.Read(ContentReader input, SpriteFont existingInstance)
   at Microsoft.Xna.Framework.Content.ContentTypeReader`1.Read(ContentReader input, Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.InnerReadObject[T](T existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T]()
   at Microsoft.Xna.Framework.Content.ContentReader.ReadAsset[T]()
   at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[T](String assetName, Action`1 recordDisposableObject)
   at Microsoft.Xna.Framework.Content.ContentManager.Load[T](String assetName)
   at Caravel.Core.Resource.Cv_SpriteFontResource.VLoad(String resourceFile, Stream resourceStream, Int32& size, Cv_ResourceBundle bundle)
    Function: VLoad

在调用Load之前,我已经检查了资产的名称和RootDirectory,它们似乎是正确的。所以我不知道该怎么办。内容管理器是否无法在运行应用程序的目录之外加载文件?还是我在这里想念一些愚蠢的东西?对于在游戏中以及在编辑器中加载场景时,如何使spritefonts正确加载,您有什么建议?

如果使用的话,我正在使用MonoGame 3.5。

编辑:这是发生异常时局部变量的屏幕截图。

Debugger info

感谢您阅读这段文字。

0 个答案:

没有答案