从OnTriggerEnter类获取变量到另一个类

时间:2019-05-04 21:04:21

标签: c# unity3d

我有一个非常简单的问题,我不明白自己在想什么。 我收到错误消息:

NullReferenceException:对象引用未设置为对象的实例 test.Update()(位于Assets / Scripts / test.cs:13)

因此,我有一类“ DissableInput”,其中有一个简单的触发器,只要它被另一个对象触发,它就会更改。每当它更改时,它都会返回true / false。

另一个类名为“ test”,根据触发器输入,当它为真/假时,基本上应该将其打印出来。

//测试类

public bool touchedCollision;

// Update is called once per frame
void Update()
{
    if (this.GetComponent<DissableInput>().touchedCollision)
    {
        Debug.Log("IN COLL");
    }
    if(!this.GetComponent<DissableInput>().touchedCollision)
    {
        Debug.Log("NOT IN COLL");
    }
}

// DisableInput类

public bool touchedCollision;

void OnTriggerEnter (Collider other)
{
    Debug.Log("In Triger");
    touchedCollision = true;
}

public void OnTriggerExit(Collider other)
{
    Debug.Log("Out Triger");
    touchedCollision = false;
}

我期望true / false会进入测试类,但会给出NullReferenceException错误。

2 个答案:

答案 0 :(得分:0)

这部分this.GetComponent<DisableInput>().touchedCollision将尝试在与其连接的同一gameObject中获取指定类型的组件,在本例中为“ DisableInput”类。如果希望在另一个gameObject中使用DisableInputClass脚本,则需要以其他方式进行引用。

使用公共变量看起来像

// TestClass

public DisableInput disableInput;

// Update is called once per frame
void Update()
{
    if (disableInput.touchedCollision)
    {
        Debug.Log("IN COLL");
    }
    else //you don`t need to specify the condition again, you can do it with and else
    {
        Debug.Log("NOT IN COLL");
    }
}

您可以查看GetComponent here的工作原理

也可以使用FindObjectOfType<DisableInput>() // TestClass

  private DisableInput disableInput;

void Awake(){
  disableInput = FindObjectOfType<DisableInput>(); 
// you only need to get the 
//class refence one time, no need for it to be in the update, 
//it gains a lot of performance
}

    // Update is called once per frame
    void Update()
    {
        if (disableInput.touchedCollision)
        {
            Debug.Log("IN COLL");
        }
        else //you don`t need to specify the condition again, you can do it with and else
        {
            Debug.Log("NOT IN COLL");
        }
    }

有关FindObjectOfType here的更多信息,但是要使用它,您必须了解 它将返回他发现的第一个附加了DisableInput的对象。如果您有多个带有DisableInput的gameObjects,则无法确定它将获得哪一个。

答案 1 :(得分:0)

您的脚本位于不同的对象上,因此this.GetComponent不起作用

您想知道ObjA何时触摸ObjB,因此在ObjA上有一个脚本想知道,而在ObjB上有一个脚本在两次触摸时运行。但是,this.GetComponent只能看到附加到相同对象的脚本。因此,您不能从ObjA运行此代码(因为它不知道,而且也不知道ObjB! )

我将对您的脚本进行两​​个小更改:

//测试类

public bool touchedCollision; //you already had this, but weren't using it

// Update is called once per frame
void Update()
{
    if (touchedCollision)
    {
        Debug.Log("IN COLL");
    }
    if(!touchedCollision) //can be changed to just `else`
    {
        Debug.Log("NOT IN COLL");
    }
}

// DisableInput类

//removed touchedCollision from here

void OnTriggerEnter (Collider other)
{
    Debug.Log("In Triger");
    other.GetComponent<TestClass>().touchedCollision = true;
}

public void OnTriggerExit(Collider other)
{
    Debug.Log("Out Triger");
    other.GetComponent<TestClass>().touchedCollision = false;
}

之所以可行,是因为它假定:

  • 您要禁用输入的每个卷有一个以上的DisableInput实例
  • 可能有多个TestClass(或您要称呼的实例)实例(例如,多人游戏或AI控制的对象)。
  • DisableInput类查找引起物理事件的对象的TestClass 并更改其值。

附录:

您应检查是否为空。这是最简单的方法(荣耀归于C#6!)

other.GetComponent<TestClass>()?.touchedCollision = ...

使用null conditional operator