Why does OnEndDrag override OnDrop with only SetPosition and SetParent?

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

public class Drag : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler

{
    public Image localItemImage;
    public CanvasGroup localItemCanvasGroup;
    public InventorySlotDrop inventorySlotDrop;
    public Transform currentItemSlot;

    private void Start()

    {
        localItemImage = GetComponent<Image>();
        localItemCanvasGroup = GetComponent<CanvasGroup>();
        inventorySlotDrop = GetComponentInParent<InventorySlotDrop>();
        currentItemSlot = inventorySlotDrop.transform;
     
    }

    public void OnBeginDrag(PointerEventData eventData)

    {
        inventorySlotDrop.isInventorySlotFull = false;
    }

    public void OnDrag(PointerEventData eventData)

    {
        transform.position = Input.mousePosition;
        transform.SetParent(transform.root);
        localItemImage.color = Color.red;
        localItemCanvasGroup.blocksRaycasts = false;
    }

    public void OnEndDrag(PointerEventData eventData)

    {
        GetComponent<Image>().color = Color.white;
        transform.SetParent(currentItemSlot);
        transform.position = currentItemSlot.position;
        inventorySlotDrop.isInventorySlotFull = true;
        localItemCanvasGroup.blocksRaycasts = true;
        Debug.Log("Item returned to original slot");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class InventorySlotDrop : MonoBehaviour, IDropHandler

{
    public bool isInventorySlotFull = false;
    public GameObject droppedItem;

    private void Start()

    {
        if (transform.childCount > 0)

        {
            isInventorySlotFull = true;
        }
    }

    public void OnDrop(PointerEventData eventData)

    {
        droppedItem = eventData.pointerDrag;
        isInventorySlotFull = true;
        droppedItem.GetComponent<Image>().color = Color.white;
        droppedItem.GetComponent<CanvasGroup>().blocksRaycasts = true;
        droppedItem.transform.SetParent(transform);
        droppedItem.transform.position = transform.position;
        Debug.Log("Inventory Slot Found");
    }
}

A bit baffled by this one, even on tutorials I’ve seen EndDrag should just return to the original slot whenever the item hasn’t been dragged to a slot rather than constantly.

Found the answer! Was neglecting to do proper parent checks on the EndDrag.

Go to 9:45 for the explanation.

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

public class Drag : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler

{
    public Image localItemImage;
    public CanvasGroup localItemCanvasGroup;
    public InventorySlotDrop inventorySlotDrop;
    public Transform currentItemSlot;

    private void Start()

    {
        localItemImage = GetComponent<Image>();
        localItemCanvasGroup = GetComponent<CanvasGroup>();
        inventorySlotDrop = GetComponentInParent<InventorySlotDrop>();
        currentItemSlot = inventorySlotDrop.transform;
      
    }

    public void OnBeginDrag(PointerEventData eventData)

    {
        inventorySlotDrop.isInventorySlotFull = false;
    }

    public void OnDrag(PointerEventData eventData)

    {
        transform.position = Input.mousePosition;
        localItemImage.color = Color.red;
        localItemCanvasGroup.blocksRaycasts = false;
    }

    public void OnEndDrag(PointerEventData eventData)

    {
      
        if (transform.parent == currentItemSlot)

        {
            GetComponent<Image>().color = Color.white;
            transform.SetParent(currentItemSlot);
            transform.position = currentItemSlot.position;
            inventorySlotDrop.isInventorySlotFull = true;
            localItemCanvasGroup.blocksRaycasts = true;
            Debug.Log("Item returned to original slot");
        }
    }
}
1 Like
droppedItem.GetComponent<Drag>().currentItemSlot = transform;

Extra note for those wondering, I needed to update the current slot in the InventorySlotDrop class.

Oh and this is totally random but how acceptable is it to compare the same variables with each other if they get changed later in the execution order?

        if (currentItemSlot == currentItemSlot)

        {
            GetComponent<Image>().color = Color.white;
            transform.SetParent(currentItemSlot);
            transform.position = currentItemSlot.position;
            currentItemSlot.GetComponent<InventorySlotDrop>().isInventorySlotFull = true;
            localItemCanvasGroup.blocksRaycasts = true;
        }

I did this because in order to deal with the sorting order issues I have the item change it’s parent while being dragged and realised rather than do what the guy does in the video where he does a kind of blind parent check you can simply check to see if the slot is the same without breaking anything and Unity complains a bit about this even though I’m having the currentItemSlot change when the item is dropped. Seems to work fine unless there’s a specific operand I’ve completely ignored which does a check to see if it’s the same properly.

Just to help contribute to having some up to date inventory code because I noticed that there are some really out of date posts on this topic I’m throwing in some of the pickup code I’m using as well, just wrote it up tonight.

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

public class RaycastInteraction : MonoBehaviour
{

    public GameObject inventoryCanvas;
    public InventorySlotList inventorySlotList;
    public Image item1;


    private void Start()

    {
        inventoryCanvas = GameObject.FindGameObjectWithTag("InventoryCanvas");
        inventorySlotList = inventoryCanvas.GetComponent<InventorySlotList>();
    }

    void Update()
    {
        RaycastHit hit;

        if (Physics.Raycast(transform.position, transform.forward, out hit, Mathf.Infinity))

        {
            if (hit.transform.gameObject.tag == ("Item1"))

            {
                if (Input.GetKeyDown(KeyCode.E))

                {
                    Destroy(hit.transform.gameObject);
                
                    foreach (InventorySlotDrop inventorySlotDrop in inventorySlotList.inventorySlots)

                    {
                        if (inventorySlotDrop.isInventorySlotFull == false)

                        {
                            Image localItem1 = Instantiate(item1, inventorySlotDrop.gameObject.transform.position, Quaternion.identity);
                            inventorySlotDrop.isInventorySlotFull = true;
                            localItem1.transform.SetParent(inventorySlotDrop.transform);
                            return;
                        }
                    }
                }
            }
        }
    }
}