【问题标题】:Creating a drag and drop system with a trash can to remove object使用垃圾桶创建拖放系统以删除对象
【发布时间】:2015-09-21 10:31:16
【问题描述】:

我在创建允许将游戏对象拖放到屏幕的垃圾区域从而破坏游戏对象的脚本时遇到问题。我在 onDrop 函数中哪里出错了?基本上我想说的是,当一个游戏对象被扔到垃圾桶上时,它就变成了垃圾桶的一个孩子,一旦它成为一个孩子,它就会被摧毁。这个逻辑有意义吗?

using System.Collections;
using UnityEngine.EventSystems;

namespace MyNamespace
{
    public class DropZone : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler 
    {
        public void OnPointerEnter(PointerEventData eventData)
        {
            if(eventData.pointerDrag == null)
                return;

            DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();

            if(dragHandling != null)
            {
                dragHandling.placeholderParent = this.transform;        // change parent based on drop zone
            } 
        }

    public void OnPointerExit(PointerEventData eventData)
    {
        if(eventData.pointerDrag == null)
            return;

        DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();
        if(dragHandling != null && dragHandling.placeholderParent == this.transform)
        {
            dragHandling.placeholderParent = dragHandling.parentToReturnTo;     // change parent based on drop zone
        } 
    }

    public void OnDrop(PointerEventData eventData)
    {
        Debug.Log(eventData.pointerDrag.name + " was dropped on " + gameObject.name);

        DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();

        if(dragHandling != null)
        {
            dragHandling.parentToReturnTo = this.transform;     // change parent based on drop zone
        }  

        if (this.transform.parent.gameObject == dragHandling.trashCan) 
        {
            Destroy(this);
        }
    }
}

这是我用来获取变量的脚本:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
    public Transform placeholderParent = null;
    public Transform parentToReturnTo = null;

    GameObject placeholder = null;

    public GameObject trashCan;
    public Transform trashCanTrans;
    public GameObject partsPanel;
    public Transform partsPanelTrans;
    public GameObject buildBoard;
    public GameObject dragLayer;

    void Awake ()
    {
        dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
        buildBoard = GameObject.FindGameObjectWithTag("Board");
        partsPanel = GameObject.FindGameObjectWithTag("Parts");
        trashCan = GameObject.FindGameObjectWithTag("Trash");

        partsPanelTrans = partsPanel.transform;
        // trashCanTrans = trashCan.transform;
    }

    #region IPointerClickHandler implementation

    public void OnPointerClick (PointerEventData eventData)
    {
        if(this.transform.parent.gameObject == buildBoard)
        {
            this.transform.SetAsLastSibling();
        }

    }

    #endregion

    #region IBeginDragHandler implementation

    public void OnBeginDrag (PointerEventData eventData)
    {
        // this.transform.SetAsLastSibling();

        // create placeholder gap and hold correct position in layout
        placeholder = new GameObject();
        placeholder.transform.SetParent(this.transform.parent);
        placeholder.transform.SetSiblingIndex(this.transform.GetSiblingIndex());

        LayoutElement le = placeholder.AddComponent<LayoutElement>();               // add layout element

        le.preferredWidth = this.GetComponent<LayoutElement>().preferredWidth;      
        le.preferredHeight = this.GetComponent<LayoutElement>().preferredHeight;
        le.flexibleWidth = 0;
        le.flexibleHeight = 0;

        parentToReturnTo = this.transform.parent;                   // store current parent location
        placeholderParent = parentToReturnTo;                       // set placeholder gameobject transform

        GetComponent<CanvasGroup>().blocksRaycasts = false;         // turn off image raycasting when dragging image in order to see what's behind the image            
    }

    #endregion

    #region IDragHandler implementation

    public void OnDrag (PointerEventData eventData)
    {
        this.transform.position = eventData.position;               // set object coordinates to mouse coordinates
        this.transform.SetParent(dragLayer.transform);              // pop object to draglayer to move between dropzones
    }

    #endregion

    #region IEndDragHandler implementation

    public void OnEndDrag (PointerEventData eventData)
    {
        this.transform.SetParent(parentToReturnTo);                                 // Snaps object back to orginal parent if dropped outside of a dropzone
        this.transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex());    // Returns card back to placeholder location

        GetComponent<CanvasGroup>().blocksRaycasts = true;                          // turn on Raycast blocking

        Destroy(placeholder);                                                       // kill the placeholder if object hits a drop zone or returns to parts panel
    }

    #endregion
}

好的,所以我做了一些更改,现在当我将游戏对象拖到垃圾箱上时,它会被破坏,但垃圾箱也是如此。我一直试图让它工作,但仍然没有运气。这是我现在所拥有的,但它仍然无法正常工作。

public void OnDrop(PointerEventData eventData) { Debug.Log(eventData.pointerDrag.name + " 被丢弃在 " + gameObject.name);

    DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();

    if(dragHandling != null)
    {
        dragHandling.parentToReturnTo = this.transform;     // change parent based on drop zone

        if (this.transform.gameObject == dragHandling.trashCan) 
        {
            Debug.Log("You've dragged something into the trash!");

            Destroy(this.transform.gameObject);
        }
    }  
}

【问题讨论】:

  • 如果前面的所有变量都有正确的期望值,我会说它是 Destroy() 函数,是否所有前面的变量都具有您期望它们具有的值?
  • 我想是的...这是我引用的脚本变量。刚刚将另一个脚本添加到我原来的帖子中。

标签: c# unity3d drag-and-drop


【解决方案1】:

如果垃圾可以与游戏对象一起销毁,请不要使该对象成为垃圾箱的子对象。这里可能发生的情况是,destroy() 函数还想销毁对象的父对象,以保持数据的一致性。

【讨论】:

  • 这样的东西在代码中会是什么样子?如果 GameObject 掉落到其他 GameObject 上,则销毁它。
  • 其实还挺混乱的,别放弃!我明天去。
【解决方案2】:

老实说,我认为您不应该将“this”放入destroy函数中,请参阅直接提问的人:http://answers.unity3d.com/questions/19223/is-destroygameobject-the-same-as-destroythis.html

您试图破坏放置区而不是破坏游戏对象。只销毁游戏对象,一切都应该没问题。

【讨论】:

  • 有道理,谢谢。如何识别我试图在销毁函数中杀死的游戏对象? Destroy(gameObject) 似乎不起作用。
  • 好吧,我不确定在那种情况下,很难说,但很快,我会说这是你试图摧毁的 this.transform.parent.gameObject。呵呵,如果它有效,别忘了接受答案,它可能会帮助其他人
  • 嗨 Antoine,我刚刚在原始帖子中重新发布了该更改的最新情况。
  • 好的,现在在销毁游戏对象的同时,也销毁了垃圾桶,这是新问题吗?
  • 是的。我似乎无法弄清楚为什么。
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多