Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by ben_slinger · Apr 08, 2015 at 01:13 PM · unity 5uidragdrag-and-drop

OnDrop called on wrong GameObject

I am implementing a drag and drop inventory interface - I have a UI Panel with an Inventory script on it, which instantiates an appropriate number of InventorySlot prefabs on Start(). The prefabs consist of a UI Image with an InventorySlot script and a InventoryDropHandler attached, and a child UI Image with a InventoryDragHandler attached. The idea is that the child image has the item icon on it, can be dragged to other slots and the parent InventorySlot object will handle the drop.

I've been using this tutorial as a basis: https://www.youtube.com/watch?v=c47QYgsJrWc≈p=desktop - the only thing I'm doing slightly differently is that I'm not changing the parent of the child item icon object to the new InventorySlot, instead I am assigning the internal GameObject which represents my actual item to the new slot, setting the child icon based on that, and resetting the original item icon back to it's previous state.

My problem is that after moving from one slot to the other (which works as expected), if I try to move back to the original slot (or any other slot that has held an item), the OnDrop function gets called on whichever InventorySlot the item is currently in, rather than the destination. I can't see anyway this is happening so I'm baffled.

Any help would be much appreciated - here are the appropriate scripts:

Inventory.cs (on the parent panel)

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class Inventory : MonoBehaviour {
 
     public int slotSize = 32;
     public int offset = 5;
     public List<InventorySlot> slots = new List<InventorySlot>();
     public GameObject slotPrefab;
 
     public static GameObject draggingItem;
     public static bool isDragging = false;
 
     // Use this for initialization
     void Start () {
         // create an appropriate number of slots for the size of the panel
         RectTransform panelRect = GetComponent<RectTransform> ();
         int columns = (int)Mathf.Floor (panelRect.rect.width / (slotSize + offset));
         int rows = (int)Mathf.Floor (panelRect.rect.height / (slotSize + offset));
 
         for (int x = 0; x < columns; x++) {
             for (int y = 0; y < rows; y++)
             {
                 GameObject newSlot = Instantiate(slotPrefab);
                 newSlot.transform.SetParent(this.transform);
                 slots.Add (newSlot.GetComponent<InventorySlot>());
             }
         }
     }
 
     public void AddItemToInventory(GameObject item)
     {
         if (item.GetComponent<InventoryItem> () != null) {
             foreach (InventorySlot slot in slots)
             {
                 if (slot.itemInSlot == null)
                 {
                     slot.PutItemInSlot(item);
                     break;
                 }
             }
         }
     }
 }

InventorySlot.cs (on the parent Image in the prefab)

 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 using UnityEngine.EventSystems;
 
 public class InventorySlot : MonoBehaviour  {
 
     public GameObject itemInSlot;
     protected Image itemIcon;
 
     // Use this for initialization
     void Start () {
         itemIcon = this.transform.Find ("ItemIcon").GetComponent<Image> ();
     }
     
     public void ResetImagePosition()
     {
         transform.Find ("ItemIcon").position = Vector3.zero;
         transform.Find ("ItemIcon").gameObject.GetComponent<CanvasGroup> ().blocksRaycasts = true;
     }
 
     public void PutItemInSlot(GameObject obj)
     {
         InventoryItem item = obj.GetComponent<InventoryItem> ();
         if (!item) {
             return;
         }
         obj.SetActive (false);
         itemInSlot = obj;
         itemIcon.gameObject.SetActive (true);
         itemIcon.sprite = item.icon;
         if (item.currentSlot != null) {
             item.currentSlot.RemoveItemFromSlot();
         }
         item.currentSlot = this;
     }
 
     public void RemoveItemFromSlot()
     {
         itemInSlot = null;
         itemIcon.gameObject.SetActive (false);
         itemIcon.sprite = null;
     }
 }

InventoryDragHandler.cs (on the child Image in the prefab)

 using UnityEngine;
 using System.Collections;
 using UnityEngine.EventSystems;
 
 public class InventoryDragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
 
     protected Vector3 startPosition;
 
     #region IBeginDragHandler implementation
     public void OnBeginDrag (PointerEventData eventData)
     {
         Inventory.draggingItem = GetComponentInParent<InventorySlot> ().itemInSlot;
         Inventory.isDragging = true;
         GetComponent<CanvasGroup> ().blocksRaycasts = false;
         startPosition = transform.position;
     }
     #endregion
     
     #region IDragHandler implementation
     public void OnDrag (PointerEventData eventData)
     {
         transform.position = Input.mousePosition;
     }
     #endregion
 
     #region IEndDragHandler implementation
 
     public void OnEndDrag (PointerEventData eventData)
     {
         transform.position = startPosition;
         Inventory.isDragging = false;
         Inventory.draggingItem = null;
     }
 
     #endregion
 }

InventoryDragHandler.cs (on the parent Image in the prefab)

 using UnityEngine;
 using System.Collections;
 using UnityEngine.EventSystems;
 
 public class InventoryDropHandler : MonoBehaviour, IDropHandler {
 
 
     public InventorySlot slot;
     void Start()
     {
         slot = GetComponent<InventorySlot> ();
         //Debug.Log ("Started drop handler", slot);
     }
 
     #region IDropHandler implementation
 
     public void OnDrop (PointerEventData eventData)
     {
         Debug.Log ("Dropped", slot);
         if (slot.itemInSlot == null) {
             Inventory.draggingItem.GetComponent<InventoryItem>().currentSlot.ResetImagePosition();
             slot.PutItemInSlot(Inventory.draggingItem);
         }
     }
 
     #endregion
 
 
 }

InventoryItem.cs (this goes on any GameObject I want to be able to place in an inventory

 using UnityEngine;
 using System.Collections;
 
 public class InventoryItem : MonoBehaviour {
 
     public Sprite icon;
 
     public InventorySlot currentSlot;
 
 }

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image WolfsDragoon · Aug 30, 2018 at 12:50 AM 1
Share

Pay close attention to hierarchy with debug.log to see what is firing where. Parent/Child relations seem to have.. interesting effects with the Event System. I just got done figuring out the parent's OnPointerEnter was firing off even when thepointer hovered a child that was offset from it.

Good luck, event system bugs are the hardest I've had to find so far and the documentation is garbage.

Cheers.

avatar image bslinger WolfsDragoon · Aug 30, 2018 at 01:00 AM 0
Share

I've long since dropped this project and have moved to UE4 for my hobby projects, but thanks for the comment! Brought back good memories of working on this :) Good luck with your project!

(Also just noticed this isn't the same Unity account I wrote the question with, hah)

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by text23d · Oct 26, 2017 at 02:39 PM

I also used same tutorial and had same problem. Then I started experimenting with Canvas/Canvas component. I changed "render mode" to three ooptions, and concluded that "screen space - overlay" works best. also, see that there is "PIXEL PERFECT" chaeckbox? I just checked it and it seems like this Drag-and-drop Inventory is now working perfectly. COOL!!!! ;-)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Dragable UI Around the Player Using a Radius 1 Answer

Possible to drag items across tabs onto the same frame? 1 Answer

C# UI list item drag onto 2d sprite in world space? 1 Answer

How to move UI image between panels 0 Answers

Cannot drag text object into inspector 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges