Unity文本事件在编辑器中触发,但在构建中不触发

时间:2018-10-29 18:08:04

标签: c# unity3d

我在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;
    }
}

}

2 个答案:

答案 0 :(得分:2)

  

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

我可以找到一些可能的原因,为什么您的代码无法在构建中工作。我可能想念的还有更多,但请在下面查看它们:

1 。您尝试从以下位置加载json文件的地方:

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

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

B 。请勿在路径中包含文件扩展名,例如.txt,.jpeg,.mp3。

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

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

使用

{1, "GameScript"}

2 。您当前如何读取文件:

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

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

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

要解决此问题,请替换

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

使用

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

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


其他问题可能会在以后出现:

无限循环:

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

答案 1 :(得分:0)

在内部版本中,不能在运行时使用File.ReadAllText使用资源路径加载文件。在构建过程中,Resources /目录中的文件将打包成专有的打包资产格式,并且无法通过这种方式在路径中进行检索。

如果要以这种方式加载文件,则必须使用Resources api。

但是,以这种方式在运行时读取位于Application.streamingAssetsPath(又名/Assets/StreamingAssets CAN 中的文件。该文件夹中的文件将保留原样。可以通过

访问它们
System.IO.Path.Combine(
  Application.streamingAssetsPath, "/Path/To/file.json");

// assuming path is:
//   /Assets/StreamingAssets/Path/To/file.json

资源可能更接近您想要的资源。

或者,Unity将json文件(或与此相关的任何其他文本文件)导入为TextAssets。您可以像其他任何类型的资产一样在检查器中引用这些TextAsset文件。

public class MyMono : MonoBehaviour
{  
    public TextAsset json;

    void Start() {
        Debug.Log(json.text);
    }