"ArgumentException: The object you want to instantiate is null" Unity 和我不知道为什么



这突然停止工作,当尝试实例化弹丸时,告诉我弹丸为空。即使我为它声明了一个值。调试告诉我 Start(( 正在运行。不能提供更多的背景。

这里的问题不是"这个错误是什么意思",而是"为什么它是空的?我从代达罗斯那里得到了很好的回复,他告诉我远离字符串查找。我会尝试一下,并告诉你们是否有效。

EDIT://我的老师在文本中添加了一些我忘记删除的代码(他找不到我为什么得到 null(,但是它现在被删除了,这是不正确的代码,不起作用。标签没有拼写错误,我已经检查了大小写等。

void Start()
{
targPlayer = GameObject.FindGameObjectWithTag("Player").transform;
projectile = GameObject.Find("Projectile");
Debug.Log("was run");
}
void Update()
{
fire -= Time.deltaTime;
dmg -= Time.deltaTime;
if (fire <= 0)
{
if (Vector2.Distance(transform.position, targPlayer.position) <= detectionRange)
{
// This is where the error happens
Instantiate(projectile, transform.position, Quaternion.identity);
}
fire = fireRate;
}
if (Vector2.Distance(targPlayer.position, transform.position) <= detectionRange && Vector2.Distance(targPlayer.position, transform.position) >= stopRange)
{
transform.position = Vector2.MoveTowards(transform.position, targPlayer.position, movSpeed * Time.deltaTime);
}
}

这里有许多可能的解决方案,所以我将介绍一些想到的解决方案。

首先,使用字符串查找是我认为大多数开发人员客观上会称之为糟糕的一件事。撇开大小写和文化问题进行比较,打错字非常容易,对于您或其他团队成员来说,以后更改该对象的名称而不记得这些查找依赖于它,并且在非平凡的情况下使用时,存在严重的性能问题。对于 Unity 尤其如此,对于几乎所有的查找调用,它只会遍历层次结构,直到找到匹配的对象。

如果您的实例化调用失败,则必须发生类似上述情况。

您可能希望在某个时候查看对象池,但让我们继续进行实例化调用。

要绕过字符串查找,您可以将弹丸设置为变量。

public Transform projectile;

这将允许您在检查器中分配它。可能不允许其他脚本访问此变量,因此对于奖励积分,您可以使用 SerializeField 属性来序列化私有变量,并在检查器中分配它。

[SerializeField] private Transform projectile;

然后,您将可以立即访问弹丸,而无需任何查找开销,也不必担心中断查找。

随着你的进步,你的设计理念肯定会发生很大变化,我认为你不应该将任何这类数据与逻辑类联系起来(以防万一有人提到这一点(,但我想说这是朝着正确方向迈出的好一步,从改变你的查找结构开始。

相关内容

  • 没有找到相关文章

最新更新