【问题标题】:How to delete dynamically loaded gameobjects from a List in Untiy?如何从 Unity 的列表中删除动态加载的游戏对象?
【发布时间】:2019-05-29 04:42:09
【问题描述】:

我有一个动态加载其内容的列表。列表的元素是正在转换为游戏对象的按钮。对于用户列表中的每个对象,都会创建一个新元素。现在我希望能够在按下按钮时与按钮本身一起删除元素,其中每个元素都有自己的动态创建的删除按钮。我尝试使用 OnMouseDown 事件放置一个盒子对撞机,但从未调用过 onMouseDown。

public void ShowLectures()
{
    foreach (var course in selectedCourses)
    {
        AddMoreButton();
    }
}

public void AddMoreButton()
{
    GameObject button = (GameObject)Instantiate(prefabButton);
    button.transform.SetParent(panel.transform, false);
    button.layer = 5;
    button.SetActive(true);
}

public void OnMouseDown()
{
    Destroy(gameObject);
}

【问题讨论】:

  • 是UI元素吗?按钮等
  • 是的,这些都是 ui 元素

标签: c# unity3d


【解决方案1】:

首先,OnMouseDown 不会在创建的 Button 上调用,而是在您的脚本所附加到的 GameObject 上调用。

然后

Destroy(gameObject);

同样的方式会破坏你的脚本所附加的游戏对象,而不是实例化的button游戏对象。


既然您评论说您正在使用 UI.Button 组件,不如在 Button 被实例化时将其添加到 onClick 事件中作为回调:

public void AddMoreButton()
{
    GameObject button = (GameObject)Instantiate(prefabButton);
    button.transform.SetParent(panel.transform, false);
    button.layer = 5;
    button.SetActive(true);

    // get the Button on the button object or any child
    var buttonInstance = button.GetComponentInChildren<Button>();

    // add a callback to destroy the button gameObject
    // () => {} is a lambda expression
    buttonInstance.onClick.AddCallback(()=>{ Destroy(button); });
}

一点提示:如果Button 已经在同一个游戏对象上,您应该将预制类型本身更改为Button,例如

public Button prefabButton;

而不是简单地使用

public void AddMoreButton()
{
    Button button = Instantiate(prefabButton, panel.transform);
    button.gameObject.layer = 5;
    button.gameObject.SetActive(true);

    // add a callback to destroy the button gameObject
    // () => {} is a lambda expression
    button.onClick.AddListener(()=>{ Destroy(button.gameObject); });
}

【讨论】:

    【解决方案2】:

    我可能会创建一个 Button 并将一个事件绑定到它,而不是使用 OnMouseDown 创建一个游戏对象:

     var closeButton = /* Dynamically create button */
     closeButton.GetComponent<Button>().onClick.AddListener(HandleCloseClick);
    
     void HandleCloseClick() {
    
         Destroy(gameObject);
     }
    

    但是,您可以使用已经实现的架构 - 您只需实现 IPointerClickHandler

    Here's an answer describing how to implement & use the interface

    查看docs,了解如何使用每个事件(鼠标向下、向上、进入、退出)的说明

    【讨论】:

    • 请注意,这仍然Destroy(gameObject) ... gameObject(脚本附加到的游戏对象)不是您要销毁的对象,而是实例化的button游戏对象;)跨度>
    • 哦? where each Element has its own dynamically created delete button。我认为这是 OP 想要销毁的对象。标题也提到了一个列表,但它在问题中不存在,但那只是最坏情况下 Destroy 之前的一行。
    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多