我试图制作一个程序来更新玩家每回合的心脏数量(全心,半心和空心)。当我这样做时,我将该预制件的游戏对象实例化为变量,然后将其分配到我的UI面板中。但是(我不确定,但我认为)之前更新中使用的变量在下一个循环中被销毁后仍然被引用,从而给出了错误:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
这是更新循环:
void Update()
{
if (HP <= 0)
{
anim.SetBool("Death", true);
Destroy(GameObject.Find("Hearts"));
Destroy(GameObject.Find("Inventory"));
text.alignment = TextAnchor.LowerCenter;
text.text = "\n YOU DIED";
text.fontSize = 150;
text.color = new Color(255, 0, 0);
} else {
foreach (Transform child in GameObject.Find("Hearts").transform)
{
Destroy(child.gameObject);
}
for (var i = 0; i<(int)HP; i++)
{
GameObject Heart = Instantiate(heart, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
Heart.transform.SetParent(GameObject.Find("Hearts").transform);
}
if (HP - (float)((int)HP) == 0.5F) {
GameObject HalfHeart = Instantiate(halfheart, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
HalfHeart.transform.SetParent(GameObject.Find("Hearts").transform);
}
for (var i =0; i<Mathf.Floor(MaxHP-HP); i++)
{
GameObject EmptyHeart = Instantiate(emptyheart, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
EmptyHeart.transform.SetParent(GameObject.Find("Hearts").transform);
}
}
有没有办法在不制作变量的情况下实例化预制件?或者将变量引用设为临时的方法,以便它只持续一次更新?提前谢谢你的帮助!
问题是,一旦HP低于零,每次后续更新都将进入第一个if语句并尝试一遍又一遍地删除“Hearts”和“Inventory”对象。您可以通过添加名为isDead
的bool并将语句更改为if (HP <= 0 && !isDead)
然后在块内设置isDead = true
来解决此问题。这将阻止它两次输入。
坦率地说,你解决问题的方式完全是倒退的。正如其他人所指出的那样,每帧删除和实例化对象的效率非常低,而且Transform.Find也很慢。你根本不需要销毁任何东西 - 你可以只选择一个心脏列表,并在惠普改变时启用/禁用适当的数量。您可以在列表的末尾添加一个半心脏,并在适当的时候启用/禁用它 - 如果您使用的是HorizontalLayoutGroup,它仍将正确对齐。您可能想要这样做,以便您只能使用属性或函数(类似于ModifyHealth(float amount)
)更改HP,并将更新心脏显示的逻辑放在那里。