【问题标题】:Object reference not set to an instance of an object, it worked yesterday, opened today and errors are thrown对象引用未设置为对象的实例,它昨天工作,今天打开并抛出错误
【发布时间】:2019-04-12 15:49:59
【问题描述】:

基本上,我正在 Unity 中使用 Vuforia 创建一个增强现实项目。我对 C# 很陌生,所以我知道代码可能不是那么理想,但它确实有效。我昨天和今天保存并退出,当我再次打开它进行测试并开发更多内容时,突然抛出错误:

NullReferenceException: Object reference not set to an instance of 
an object
marsHVB_script.Start () (at Assets/marsHVB_script.cs:11)

我有两个单独的脚本,一个是主脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;

public class main : MonoBehaviour
{
    public static GameObject helpObj;
    public static GameObject NVB;
    public static GameObject BVB;
    public static GameObject helpMsg;
    public static GameObject nText1;
    public static GameObject nText2;
    public static GameObject nText3;
    public static GameObject nText4;
    public static int stage = 1;
    // Start is called before the first frame update
    void Start()
    {
        helpObj = GameObject.Find("marsHVB");
        helpMsg = GameObject.Find("marsHelp");
        nText1 = GameObject.Find("nText1");
        nText2 = GameObject.Find("nText2");
        nText3 = GameObject.Find("nText3");
        nText4 = GameObject.Find("nText4");
        nText2.SetActive(false);
        nText3.SetActive(false);
        nText4.SetActive(false);
        helpMsg.SetActive(false);

    }

    public static void IncrStage()
    {
        stage++;
        Debug.Log("Stage Increased to " + stage);
    }
    public static void DecrStage()
    {
        stage--;
        Debug.Log("Stage Decreased to " + stage);
    }
    public static int GetStage()
    {
        Debug.Log("Stage Got " + stage);
        return stage;
    }
    // Update is called once per frame
    void Update()
    {

    }
}

在下面显示的代码中,我创建了应该可以从其他脚本访问的公共静态变量。我找到了它们,然后我把它们关掉了。

然后,还有第二个控制虚拟按钮的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;

public class marsHVB_script : MonoBehaviour, IVirtualButtonEventHandler
{

    void Start()
    {
        main.helpObj.GetComponent<VirtualButtonBehaviour>().RegisterEventHandler(this);
    }

    void IVirtualButtonEventHandler.OnButtonPressed(VirtualButtonBehaviour vb)
    {
        switch (main.GetStage())
        {
            case 1:
                main.nText1.SetActive(false);
                main.helpMsg.SetActive(true);
                break;
            case 2:
                main.nText2.SetActive(false);
                main.helpMsg.SetActive(true);
                break;
            case 3:
                main.nText3.SetActive(false);
                main.helpMsg.SetActive(true);
                break;
            case 4:
                main.nText4.SetActive(false);
                main.helpMsg.SetActive(true);
                break;
        }

        Debug.Log("Help Pressed");
    }

    void IVirtualButtonEventHandler.OnButtonReleased(VirtualButtonBehaviour vb)
    {

        switch (main.GetStage())
        {
            case 1:
                main.helpMsg.SetActive(false);
                main.nText1.SetActive(true);
                break;
            case 2:
                main.helpMsg.SetActive(false);
                main.nText2.SetActive(true);
                break;
            case 3:
                main.helpMsg.SetActive(false);
                main.nText3.SetActive(true);
                break;
            case 4:
                main.helpMsg.SetActive(false);
                main.nText4.SetActive(true);
                break;
        }
        Debug.Log("Help Removed");
    }

    // Update is called once per frame
    void Update()
    {

    }
}

第二个脚本对虚拟按钮的按下和释放做出反应。 第 11 行抛出了错误,这是 main.helpObj.GetComponent 函数,昨天有效,今天无效。

请帮我解决这是什么原因,因为我现在被困在这里。

【问题讨论】:

  • @JSteward 怎么可能在关闭和打开项目后变为空?
  • 多个脚本中Start()的调用顺序未定义。 main.Start() 昨天首先运行但 marsHVB_script.Start() 今天首先运行是完全合法的。如果marsHVB_script.Start()main.Start() 之前运行,你能明白为什么helpObj 会为空吗?
  • 如果将main 中的Start() 更改为Awake() 会发生什么?
  • @JeffE 改变了,它起作用了!谢谢。

标签: c# unity3d augmented-reality vuforia


【解决方案1】:

您不应该使用Start void 来初始化代码中的变量。 Awake 通常用于此目的,因为 Awake 总是在 Start 之前调用。

如果您将main 类中的Start() 更改为Awake(),则可以确保始终在marsHVB_script class 尝试访问它之前分配helpObj

【讨论】:

  • 将 Start() 更改为 Awake() 有效,但由于未知原因(我没有碰其他任何东西)统一相机开始严重滞后。就像每秒5帧或smth。它可以以某种方式关联吗?或者是我的代码太重而无法运行吗?
  • 不应与此相关联。尝试全屏运行游戏,看看它是否仍然滞后。有时,当您在编辑器中选择某些 GameObjects(如 UI 对象)时,游戏可能会出现延迟。
【解决方案2】:

您可以使用 Reset() 函数并将您编写的所有代码放在 Start 函数中。它将允许您在不玩游戏的情况下设置参考。

void Reset()
{
    helpObj = GameObject.Find("marsHVB");
    helpMsg = GameObject.Find("marsHelp");
    nText1 = GameObject.Find("nText1");
    nText2 = GameObject.Find("nText2");
    nText3 = GameObject.Find("nText3");
    nText4 = GameObject.Find("nText4");
    nText2.SetActive(false);
    nText3.SetActive(false);
    nText4.SetActive(false);
    helpMsg.SetActive(false);

}

写这个,回到编辑器。单击脚本组件上的齿轮图标,然后单击“重置”。它将设置所有引用,然后您可以安全地删除该 Start 函数。

【讨论】:

    猜你喜欢
    • 2011-10-31
    • 1970-01-01
    • 2014-12-20
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    相关资源
    最近更新 更多