【问题标题】:Unity: GetComponent results in nullreferenceUnity:GetComponent导致空引用
【发布时间】:2017-09-19 08:41:53
【问题描述】:

我有一个包含嵌套预制件的场景。 嵌套预制件包含多个桶预制件(下图)

这些桶形预制件具有组件:变换、动画、网格过滤器和网格渲染器

问题是我无法通过代码找到网格过滤器和网格渲染器。在 Unity 播放器中一切正常!但是当我为 pc 构建时,我在 `gobj.getComponent 上得到了一个空引用,但只在具有“桶”标签的对象上,(油工作正常并且具有相同的组件):

private void EvaluateAll() //gets called from awake
{
    EvaluateDissolve();
    EvaluateFish();
    EvaluateFloor();
    EvaluateFogCol();
    EvaluateFogDens();
    EvaluatePlants();
    EvaluateRocks();
}

private void EvaluateDissolve()
{
        foreach (GameObject gobj in GameObject.FindGameObjectsWithTag("oil"))
        {
            gobj.GetComponent<Renderer>().sharedMaterial.SetFloat("_SliceAmount",m_dissolveFactor + 0.2f);
        }

        foreach (GameObject gobj in GameObject.FindGameObjectsWithTag("barrel"))
        {
            gobj.GetComponent<Renderer().sharedMaterial.SetFloat("_SliceAmount",m_dissolveFactor);
        }
}

我尝试记录桶对象的所有组件,它只记录动画和变换组件,由于某种原因没有记录网格渲染器和网格过滤器(此代码从唤醒函数调用):

foreach (GameObject gobj in GameObject.FindGameObjectsWithTag("barrel"))
{
            Debug.Log("is object active? " + gobj.activeInHierarchy.ToString());
            Debug.Log("barrel scene: " + gobj.scene.name.ToString());
            Debug.Log("asking components of barrel, is barrel null?" + (gobj == null).ToString());

            Component[] components = gobj.GetComponents(typeof(Component));
            foreach (Component comp in components)
            {
                Debug.Log(comp.GetType().ToString());
            }
            gobj.GetComponent<Renderer>().sharedMaterial.SetFloat("_SliceAmount",m_dissolveFactor);
 }

【问题讨论】:

  • "我在桶上得到一个空引用。getComponent" .....你的代码中没有i get a nullreference on barrel.getComponent&lt;Renderer&gt;。由于我们无权访问您的场景对象,因此最好指出错误发生的确切位置。
  • 我添加了一些信息来指出错误发生的确切位置
  • 还不知道。我将就如何轻松找出导致此问题的原因提供建议。如果您确定问题出在此处:gobj.GetComponent&lt;Renderer() 然后在屏幕中间添加一个简单的Text 组件。根据它是否为空来修改此文本。如果gobj.GetComponent&lt;Renderer() 为空,则打印它,然后使用break 跳出循环。你也可以用yourUIText.text = gobj.name;将GameObject的名称添加到Text组件中,如果你有任何发现请回复我
  • 我确定渲染器组件是空的,因为它没有打印在我的日志中,我记录了所有内容并使用名为报告器的工具在构建中检查这些内容。我还明确检查了 getComponent() == null 并打印了一个日志告诉我它的 null
  • 好的,现在打印我上面所说的为空的游戏对象的名称,并告诉我它是什么。

标签: c# unity3d


【解决方案1】:

GetComponent 永远不会返回 null,除非组件未附加到该 Object 或组件被销毁。

您的GameObject.FindGameObjectsWithTag("oil")GameObject.FindGameObjectsWithTag("barrel") 正在寻找一个分别带有“oil”或“barrel”标签的游戏​​对象。

在此之后,GetComponent&lt;Renderer() 在循环中用于访问由FindGameObjectsWithTag 返回的每个Renderer。根据你的说法,它有时会返回 null 并且返回 null 的循环指向一个名为 "Fish1" 的游戏对象。

问题是您错误地将 Fish1 的标签更改为“油”或“桶”。 FindGameObjectsWithTag 然后会拿起它并尝试检查它的 Renderer 是否为空。

"Fish1" 标记更改为未标记,这样GameObject.FindGameObjectsWithTag("oil")GameObject.FindGameObjectsWithTag("barrel") 就不会找到它。

现在,如果您真的想让 "Fish1" 带有“油”或“桶”标签,那么您必须确保在其上附加了 MeshRender

注意

编辑器中有一个搜索栏,用它来搜索场景中的“Fish1” GameObjects并更改标签。

另外,请确保您没有使用“oil”或“barrel”标签实例化任何名为““Fish1” 的游戏对象。这非常重要。这不是魔术。GameObject.FindGameObjectsWithTag 正在返回因为它存在于场景中。

【讨论】:

  • 我的鱼没有桶标签我发誓,wtf
  • 我重置了标签,即使它不是桶状的,它解决了我的问题
  • 也许这是编辑器中的缓存/保存问题,但我相信您更改了粘贴中的标签并将其改回,但 Unity 没有识别出该更改。更不用说“Fish1”在我看来就像一个预制件,因为它是蓝色的,所以我相信你没有应用对它所做的更改。
  • 无论如何,非常感谢,我浪费了很多时间来寻找问题
  • 只要你学到了一些新的东西,比如打印对象名称和标签,就不会浪费时间。我保证您将能够解决大多数其他 null 问题。不客气!
猜你喜欢
  • 2016-12-26
  • 2016-03-24
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
相关资源
最近更新 更多