尝试与由raycast命中的对象上的组件进行交互,获取NullReferenceException

时间:2017-01-04 16:38:05

标签: c# unity3d

我的角色与盒子互动时遇到问题。我有一个GameObject Player附加了一个脚本来与游戏中的盒子进行交互,脚本是:

using UnityEngine;
using System.Collections;

public class PlayerBox : MonoBehaviour {

    public bool active = true;
    public KeyCode key = KeyCode.E;

    float distance = 2F;
    RaycastHit obj;
    BoxManager box;

    void Start () {
        box = GetComponent<BoxManager>();
    }

    void Update () {
        if (active && Input.GetKeyDown (key) && Physics.Raycast (this.transform.position, this.transform.forward, out obj, distance)) {
            if (obj.collider.gameObject.tag == "Box") {
                box.Open();
                Debug.Log("aperto " + box);
            }
        }

    }
}

在场景中有一个带有脚本的GameObject Box来管理行为:

using UnityEngine;
using System.Collections;

public class BoxManager : MonoBehaviour {

    public void Open() {
        Debug.Log ("Dentro");
    }
}

最后一个脚本应该打印日志,但是当我与它进行交互时,我得到了

  

NullReferenceException:未将对象引用设置为对象的实例   PlayerBox.Update()(在Assets / ETSMB / Script / Use / PlayerBox.cs:23)

如何正确地将box设置为对象的实例?

2 个答案:

答案 0 :(得分:1)

这里的问题是,当您在BoxManager方法中为box分配值时,您正在查找Start()组件的错误位置:

void Start () {
    box = GetComponent<BoxManager>();
}

GetComponent<BoxManager>()将在当前脚本的 GameObject(本例中为BoxManager的GameObject)上搜索组件PlayerBox。但是,根据您的措辞,它听起来像BoxManagerPlayerBox在两个不同的游戏对象上,因此您无法以这种方式找到组件。尝试这样做只会给box一个值null,这是调用box.Open()时NullReferenceException背后的原因。

您需要做的是从BoxManager返回的对象中检索Physics.Raycast() - 所以删除Start()方法中的内容,然后重写{{1}的内容方法:

Update()

希望这有帮助!如果您有任何问题,请告诉我。

答案 1 :(得分:1)

问题是:

void Start () {
    box = GetComponent<BoxManager>();
}

正在寻找PlayerBox上的BoxManager组件,而不是场景中的BoxManager游戏对象。因此,如果PlayerBox游戏对象上没有BoxManager脚本,则框将为空。因此,您的错误消息。

有很多种方法可以在场景中找到对象(参见:FindObjectsOfType),但最简单的例子就是将BoxManager框公开:

public BoxManager box;

void Start () {
    //box = GetComponent<BoxManager>();
}

然后,在Unity编辑器中,将BoxManager对象从场景层次结构拖放到PlayerBox对象检查器的box变量上。

现在一切都已连线,你不应该再得到一个空指针异常。