Search Unity

Issues with UI object dragging

Discussion in 'Scripting' started by PaperMouseGames, Jun 26, 2019.

  1. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Hi there! So I'm pretty new to game development and I've started working on my RPG's inventory UI but I'm having an issue:

    Currently I'm clicking on and dragging my ItemSlots/EquipmentSlots (which are prefabs that populate my inventory UI) by having each ItemSlot/EquipmentSlot have the
    ClickableObject 
    script attached, which I'm proving at the bottom.

    I'm trying to get a dragged object (i.e. an ItemSlot or EquipmentSlot) to be able to detect what it's dragged into. So for example, be able to drag an item from my inventory into another inventory and then execute some code.

    I tried adding a tag to my inventory panel and checking to see if the tag matched in the
    ClickableObject 
    script but I can't seem to do this because the Inventory Panel is in the Inventory Canvas and so it seems to only check the Canvas' tag.

    I hope what I'm saying is clear, anyway, I'm wondering if there is any way around this without having to make multiple canvases for my inventory UI.

    Again, the intended behavior is to be able click and drag on an object that has an ItemSlot or EquipmentSlot component, then when the mouse button is released, depending on what object the ItemSlot/EquipmentSlot is over, do something.

    Thanks so much in advance, and here's my
    ClickableObject 
    script:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3. using UnityEngine.UI;
    4.  
    5. public class ClickableObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
    6. {
    7.     InventoryManager inventoryManager;
    8.     Item item;
    9.     EquipmentSlotType slotType;
    10.     GameObject dragObject;
    11.  
    12.     Vector3 initialPosition = Vector3.zero;
    13.     Vector3 position = Vector3.zero;
    14.     float timeCount = 0.0f;
    15.     Color baseColor = new Color(1, 1, 1, 1);
    16.  
    17.     private void Awake()
    18.     {
    19.         inventoryManager = FindObjectOfType<InventoryManager>();
    20.     }
    21.    
    22.     public void OnPointerClick(PointerEventData eventData)
    23.     {      
    24.         if (eventData.button == PointerEventData.InputButton.Left)
    25.         {
    26.            
    27.             inventoryManager.CloseItemMenus();
    28.             if (eventData.pointerPress.gameObject.GetComponent<ItemSlot>() != null)
    29.             {                          
    30.                 item = eventData.pointerPress.gameObject.GetComponent<ItemSlot>().Item;              
    31.                
    32.                 inventoryManager.SelectItem(item);
    33.  
    34.                 if (eventData.clickCount == 2)
    35.                 {
    36.                     inventoryManager.AddItemFromContainer();
    37.                 }
    38.             }
    39.         }
    40.         else if (eventData.button == PointerEventData.InputButton.Right)
    41.         {                          
    42.            
    43.             if (eventData.pointerPress.gameObject.GetComponent<ItemSlot>() != null)
    44.             {
    45.                            
    46.                 item = eventData.pointerPress.gameObject.GetComponent<ItemSlot>().Item;
    47.                 inventoryManager.ItemMenu(eventData.pressPosition, item);
    48.             }
    49.             else if (eventData.pointerPress.gameObject.GetComponent<EquipmentSlot>() != null)
    50.             {
    51.                 slotType = eventData.pointerPress.gameObject.GetComponent<EquipmentSlot>().SlotType;
    52.                 inventoryManager.UnequipItemMenu(eventData.pressPosition, slotType);
    53.             }
    54.         }
    55.     }
    56.     public void OnBeginDrag(PointerEventData eventData)
    57.     {
    58.         if (eventData.pointerPress.gameObject.GetComponent<ItemSlot>() != null || eventData.pointerPress.gameObject.GetComponent<EquipmentSlot>() != null)
    59.         {
    60.             dragObject = eventData.pointerPress.gameObject;
    61.             dragObject.GetComponent<CanvasGroup>().blocksRaycasts = false;
    62.             initialPosition = transform.position;
    63.             position = transform.position;
    64.         }
    65.  
    66.  
    67.     }
    68.     public void OnDrag(PointerEventData eventData)
    69.     {
    70.         if (eventData.pointerPress.gameObject.GetComponent<ItemSlot>() != null || eventData.pointerPress.gameObject.GetComponent<EquipmentSlot>() != null)
    71.         {
    72.             if (eventData.dragging)
    73.             {
    74.                 timeCount += Time.deltaTime;
    75.                 if (timeCount > 0.25f)
    76.                 {
    77.                     timeCount = 0.0f;
    78.                 }
    79.                 transform.position = eventData.position;
    80.             }
    81.         }
    82.        
    83.     }
    84.     public void OnEndDrag(PointerEventData eventData)
    85.     {      
    86.        
    87.         if (eventData.pointerEnter != null)
    88.         {
    89.             Debug.Log(eventData.pointerEnter.gameObject.tag);
    90.             if (eventData.pointerEnter.gameObject.tag == "Player Inventory")
    91.             {
    92.                 transform.position = position;
    93.             }
    94.             else
    95.             {
    96.                 transform.position = initialPosition;
    97.             }
    98.         }
    99.         else
    100.         {
    101.             transform.position = initialPosition;
    102.         }
    103.  
    104.         if (dragObject != null)
    105.         {
    106.             dragObject.GetComponent<CanvasGroup>().blocksRaycasts = true;
    107.             dragObject = null;
    108.         }
    109.        
    110.     }
    111.     public void OnPointerEnter(PointerEventData eventData)
    112.     {
    113.         if (gameObject.GetComponent<ItemSlot>() != null)
    114.         {
    115.             Item ttItem = gameObject.GetComponent<ItemSlot>().Item;
    116.             inventoryManager.TooltipDisplay(ttItem);
    117.         }
    118.         else if (gameObject.GetComponent<EquipmentSlot>() != null)
    119.         {
    120.             EquipmentSlotType ttSlotType = gameObject.GetComponent<EquipmentSlot>().SlotType;
    121.             inventoryManager.EquipmentTooltipCheck(ttSlotType);
    122.         }
    123.         else
    124.         {
    125.             inventoryManager.CloseTooltipDisplay();
    126.         }      
    127.     }
    128.     public void OnPointerExit(PointerEventData eventData)
    129.     {
    130.         inventoryManager.CloseTooltipDisplay();
    131.     }
    132. }
    133.  
     
  2. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
  3. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    Just wanted to add something:
    You don't really need a tag, if you have a main class shared by all the things that can be dropped into the slot, you can just use polymorphism. Hear me out: Say that you have a main class "Slot", and you have two classes inheriting from it CommonSlot and EquipmentSlot. OnDrop, you store whatever was dropped as Slot miSlot (a variable named miSlot of a Slot class). Since both CommonSlot and EquipmentSlot belong to Slot, they both can be equally stored in that variable. Then inside your function you say if (miSlot is CommonSlot){DoSomething();} else if (miSlot is EquipimentSlot){doSomethingElse();}
    And if you ever need to use them as their child classes, you just downcast them like this:
    EquipmentSlot miEquipmentSlot = miSlot as EquipmentSlot;
     
    Last edited: Jun 26, 2019
  4. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Thanks for the reply! Not sure I fully understand what you're suggesting though. Are you saying I could only use this if I'm dropping an object onto a slot with a script that has OnDrop?

    Right now I'm basically trying to drop these objects onto a Panel, not a specific slot within that Panel, and then I want the InventoryManager to see that the item was dropped on that Panel and say, add it to the inventory.

    Sorry if I'm just not getting your answer.
     
  5. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    I'm not saying you can only do it this way, I'm just saying you can do it this way if you want.
    You'd only need to put a script on the panel, and add an OnDrop event to the script. If something is dropped into the panel, the function will do whatever you want with the dropped item. Add it to the inventory or whatever you want.
    I don't know if I'm missing any part of the question, but whatever you don't get just ask.
     
    Last edited: Jun 27, 2019
    PaperMouseGames likes this.
  6. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    You'd attach something like this to your panel:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.UI;
    5.  
    6.  
    7. public class MyPanel : IDropHandler
    8. {
    9.  
    10.     public void OnDrop(PointerEventData eventData)
    11.     {
    12.         Debug.Log("an item was dropped");
    13.         ClickableObject droppedItem = eventData.pointerDrag.GetComponent<ClickableObject>();
    14.  
    15.         //Do whatever you want with it.
    16.     }
    17. }
     
    Last edited: Jun 27, 2019
    PaperMouseGames likes this.
  7. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    I see, thank you! I'll give this a try. I thought for some reason you were implying this would only work for certain types of items. Thanks for clarifying for me, I'm still very much a beginner and lots of stuff goes over my head haha.
     
  8. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    UPDATE: This is working great! I had trouble getting the dragged object to the foreground of the UI elements on the canvas but then switched it so the dragged object wasn't actually moving and instead it was a new foreground object that was being activated that did all the moving.

    Anyway, the point is IDropHandler and OnDrop worked beautifully, so thanks so much for bringing them to my attention!
     
  9. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    Glad to help!