首页 > 解决方案 > Unity 文本事件在编辑器中触发,但在构建中不触发

问题描述

我在 Unity 中开发的 C# 游戏遇到问题。虽然在编辑器中触发了带有动画的文本通知,但在我构建和运行时却没有。

我检查了输出日志并得到了这个。

NullReferenceException: Object reference not set to an instance of an object
  at NarrativeLocation+<InitializePanel>c__Iterator0.MoveNext () [0x00000] 
  in <filename unknown>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, 
  IntPtr returnValueAddress) [0x00000] in <filename unknown>:0 
UnityEngine.MonoBehaviour:StartCoroutine_Auto_Internal(IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
NarrativeLocation:Update()

NarrativeLocation.Update 的代码

void Update()
    {
        if (!popupIsPlaying && GameState.popupQueue.Count != 0)
        {
            int temp = GameState.popupQueue.Dequeue();
            StartCoroutine(InitializePanel(temp));
        }

        int num = 1;

        while(inZone)
        {
            if (this.gameObject.tag == "NarrativeEvent" + num)
            {
                if (Input.GetKeyDown(KeyCode.E))
                {
                    Destroy(GameObject.FindGameObjectWithTag("Notification"));
                    Destroy(GameObject.FindGameObjectWithTag("NarrativeEvent" + num));

                    Constants.GameState.popupQueue.Enqueue(num);
                }

                return;
            }
            num++;
        }
    }

InitializePanel 的代码

IEnumerator InitializePanel(int num)
{
    popupIsPlaying = true;

    panel = GameObject.Find("Panel").GetComponent<PanelConfig>();
    currentEvent = JSONAssembly.RunJSONFactoryForScene(1);

    StartCoroutine(IntroAnimation());

    panel.characterIsTalking = true;
    panel.Configure(currentEvent.dialogues[num - 1]);

    yield return new WaitForSeconds(6f);

    StartCoroutine(ExitAnimation());

    Debug.Log("Event " + num + " destroyed");

    popupIsPlaying = false;

}

public IEnumerator IntroAnimation()
{
    panelAnimator.SetBool("IntroAnimationIn", true);
    yield break;
}

public IEnumerator ExitAnimation()
{
    panelAnimator.SetBool("IntroAnimationIn", false);
    yield break;

}

当我运行游戏时,面板弹出没有文字。退出动画似乎也没有被调用。

JSON 程序集类。

namespace JSONFactory {
class JSONAssembly {

    private static Dictionary<int, string> _resourceList = new Dictionary<int, string>
    {
        {1, "/Resources/GameScript.json"}
    };

    public static NarrativeEvent RunJSONFactoryForScene(int sceneNumber)
    {
        string resourcePath = PathForScene(sceneNumber);

        if (isValidJSON(resourcePath) == true)
        {
            string jsonString = File.ReadAllText(Application.dataPath + resourcePath);
            NarrativeEvent narrativeEvent = JsonMapper.ToObject<NarrativeEvent>(jsonString);

            return narrativeEvent;
        }
        else
        {
            throw new Exception("JSON is not valid");
        }
    }

    private static string PathForScene(int sceneNumber)
    {
        string resourcePathResult;

        if (_resourceList.TryGetValue(sceneNumber, out resourcePathResult))
        {
            return _resourceList[sceneNumber];
        }
        else
        {
            throw new Exception("Scene not in resource list");
        }
    }

    private static bool isValidJSON(string path)
    {
        return (Path.GetExtension(path) == ".json") ? true : false;
    }
}

}

标签: c#unity3d

解决方案


虽然在编辑器中触发了带有动画的文本通知,但在我构建和运行时却没有。

我可以发现您的代码无法在构建中运行的几个可能原因。我可能错过了更多,但在下面看到它们:

1 . 您尝试从哪里加载 json 文件:

{1, "/Resources/GameScript.json"}

一个。从 Resources 文件夹中读取时,路径中不包含“Resources”。该路径是相对于资源文件夹的。

。不要在路径中包含 .txt、.jpeg、.mp3 等文件扩展名。

要解决这两个问题,请替换

{1, "/Resources/GameScript.json"}

{1, "GameScript"}

2 . 您当前阅读文件的方式:

string jsonString = File.ReadAllText(Application.dataPath + resourcePath);

您当前正在使用 读取文件File.ReadAllText。这将在编辑器中起作用,但在构建中不起作用,因为这不是读取 Resources 文件夹中文件的方式。

Resources 文件夹中的文件是使用Resources API读取的。

要解决此问题,请替换

string jsonString = File.ReadAllText(Application.dataPath + resourcePath);

TextAsset txtAsset = Resources.Load<TextAsset>(resourcePath);
string jsonString = txtAsset.text;

确保 json 文件放置在项目中名为“Resources”的文件夹中,并且必须拼写正确。


稍后可能会遇到其他问题:

无限循环:

代码没有退出的while(inZone)方法,如果您遇到这种情况,您可能会导致程序冻结,因为inZone在该循环中没有代码可以使 false 。您必须找到一种方法来重新编写该代码。


推荐阅读