【问题标题】:Updating image UI with unity统一更新图像 UI
【发布时间】:2019-04-26 11:56:30
【问题描述】:

我试图制作一个程序来更新玩家每回合的心数(满心、半心和空心)。当我这样做时,我将该预制件的一个游戏对象实例化为一个变量,然后将它统一分配给我的 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 更改时仅更新一次生命值条)。
  • 你能告诉我们HP增加/减少的代码吗?
  • 1.你不应该在Update 中使用Find! 2.你不应该多次使用Find...如果某些东西只使用一次,存储结果并在以后重用引用! 3. 你不应该一直在Update 中销毁和重新实例化东西,这是非常非常密集的性能并且浪费资源。只实例化一次...

标签: list unity3d methods gameobject


【解决方案1】:

问题在于,一旦 HP 低于零,每次后续更新都会进入第一个 if 语句并尝试一遍又一遍地删除“Hearts”和“Inventory”对象。您可以通过添加一个名为 isDead 的 bool 并将语句更改为 if (HP &lt;= 0 &amp;&amp; !isDead) 然后在块内设置 isDead = true 来解决此问题。这将防止它输入两次。

不过,坦率地说,您解决问题的方式完全是倒退的。正如其他人指出的那样,每帧删除和实例化对象效率非常低,并且 Transform.Find 也很慢。你根本不需要摧毁任何东西 - 你可以只拥有一个心的列表,并在 HP 变化时启用/禁用适当的数量。您可以在列表末尾有一个半心并在适当时启用/禁用它 - 如果您使用的是 Horizo​​ntalLayoutGroup,它仍然会正确对齐。您可能希望这样做,以便您只能使用属性或函数(例如ModifyHealth(float amount))更改 HP,并将更新红心显示的逻辑放在那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-08
    • 2017-12-18
    • 2017-06-20
    • 2020-02-18
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多