【问题标题】:Neither null nor type check detecting destroyed object/component?既不是空也不是类型检查检测被破坏的对象/组件?
【发布时间】:2020-02-06 19:33:49
【问题描述】:

我有一个问题,我找到了解决方法,但不明白为什么 Unity 没有按我预期的方式工作,或者我做错了什么。基本上,我在脚本中引用了一个被破坏对象的渲染器组件(在它被破坏很久之后),空检查和类型检查都没有让我知道它被破坏了。

我有一个临时修改某些对象的着色器的脚本,以便我可以对它们应用效果;效果完成后,它会将材质/着色器恢复原状。

碰巧我在开始其中一个效果的同一帧中更换了角色的武器,因此脚本结束时引用了被破坏对象(旧武器)的渲染器。许多帧之后,当效果要完成时,它自然会出错。

我首先尝试了类型检查以查看引用是否仍然指向渲染器 - 不走运。 Unity 的文档说空检查应该有效,但仍然无效。

if (pair.Key != null && pair.Key is Renderer renderer) { renderer.materials = pair.Value; }

我明白了:

MissingReferenceException: The object of type 'SkinnedMeshRenderer' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

activeInHierarchy 同样不起作用。

在我销毁对象的代码中添加 DestroyImmediate 可以正常工作;效果开始时对象不存在,因此永远不会进行引用。但是,这只解决了这个问题,而不是其他此类情况。

谁能告诉我如何正确检查对已损坏对象或组件的引用,或者我在检查时是否做错了什么?我应该引用 gameObject 而不是渲染器组件或类似的东西吗?

编辑: 由于评论者要求它,这里是效果的完整代码的要点。破坏发生在此之外,因为它完全不相关。 https://gist.github.com/jackphelps/f507d949a84c53457f570c5009bcb6d4

解决了——有点? 我更改了字典以存储渲染器的游戏对象而不是渲染器,并且正如预期的那样,简单的空检查用于检测被破坏的对象。我喜欢知道为什么它在渲染器上不起作用,以及是否有适当的方法来检查!

【问题讨论】:

  • 销毁对象时是否要从字典中删除键?
  • 如果您注意到屏幕截图不在列表中,但我的代码显示字典:我的参考存储在字典中;因为 unity 不会序列化它们,所以我添加了跟踪与字典键/值对相同的引用的列表,所以我可以看到发生了什么。
  • 为什么要使用字典来更改 renderer.materials?您可以直接从密钥中引用它。无需将其临时存储为值。
  • @ErikOverflow 我不是——物品破坏与效果完全无关,效果只是捡起物品,因为破坏发生在同一帧的早些时候。所以我需要一种方法来确保在效果的最后一位运行时字典仍然有效。
  • 我正在更改材料,存储的参考是原始材料。我需要不同的临时效果。

标签: c# unity3d


【解决方案1】:

我能找到解决此问题的最佳方法是存储对渲染器游戏对象的引用,而不是对渲染器组件本身的引用。在这种情况下,脚本末尾的简单空检查可以正常工作,正如预期的那样。

我不接受这个答案,因为它仍然没有告诉我在移除游戏对象时如何检查组件是否存在¯(°_o)/¯

【讨论】:

  • 这可能是因为销毁发生在帧的末尾。如果您销毁渲染器的游戏对象,渲染器直到帧结束才知道它已被销毁。 gameObject 引用将返回 null,但渲染器将继续引用该组件,直到销毁完成。 DestroyImmediate 起作用的原因是它会立即清理所有脏引用。
  • @ErikOverflow 你不明白——正如我所说,效果在创建参考后很多帧结束(并且使用了对渲染器的参考)。即使它所引用的渲染器在其开始和结束之间的任何时间点被破坏,我也试图使效果安全。您可以通过简单地引用游戏对象的渲染器组件来重现这一点,然后在稍后销毁游戏对象,然后在之后的某个时间尝试验证渲染器是否存在。
  • 我最初说过 destroyimmediate 确实适用于这种情况,我理解为什么——从一开始就没有引用——但这并不能处理对象可能存在的其他情况在效果运行时被摧毁。幸运的是,这里的解决方案可以。
猜你喜欢
  • 2012-11-10
  • 2011-11-05
  • 2013-12-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多