- Home /
Drag and Drop Problem
Hi i have some problems with the drag and drop functionality for UI elements. In the picture below i show you the overview of the inventory and marked all the elements i used and what you can see in the hierarchy!
If i take one Item (EquipImage) and drag it from the "EquipmentItemsParent" away and i release the mouse, the item snaps correctly back to its origin position in the correct slot. But if i take one item and want to drop it in one of the slots (Head, Jacket, Shoes, etc) in the "Characterpanel" the item or the image of the item is not in the center of the slot, but -50 to the left on the x axis. Shown in the picture below.
The next bug is if i want to drag and drop the item back to the inventory slots on the left ("EquipmentItemsParent") the drag an drop is working and it snaps back to the center of the slot but while i drag the item from the right to the left, the item disappear behinf the "StaticItemsParent" and the "EquipmentItemsParent" Panel. How can i solve these things? The code of this i show you in the following post. Thank you!
Answer by Legend_Bacon · Jan 16, 2018 at 05:32 PM
Hello there,
I am at work and can't give you a proper answer right now, but this should be a start:
Bug #1: Several possibilities here.
Sometimes the UI doesn't refresh immediately. Try hitting Ctrl + R when it does that bug, or resize the game window. Does it fix itself?
If not, try setting the ANCHOR POSITION to zero instead of doing
this.transform.localPosition = Vector3.zero;
.
Bug #2: This one is due to the object being a child of "HeadSlot". The Canvas in Unity draws object from top to bottom, so what happens is:
"HeadSlot" and its children get drawn
"StaticItemsParent" gets drawn on top of it
Etc.
Basically, because of the new parenting your object now has in the hierarchy, it gets drawn before some other UI elements, and therefore is hidden by those drawn on top. To fix this, parent your object to your Canvas (either reference the Canvas directly or use transform.root
) on OnBeginDrag(). and then parent it to the proper parent on OnEndDrag().
Judging by your variable names, you might have already seen it. But if not, THIS is a very good resource for drag & drop features.
Hope that helps!
Cheers,
~LegendBacon
Hi thank you for the help!
I checked the anchor position after your reply in the inspector and saw that they were not centered. So i set the ancor points in the middle of the slots. After the fix the drag and drop works correctly and it fits in the correct position.
The other bug is also fixed now.
this.transform.SetParent (transform.root); worked perfectly! Thank you for the help!
Besides that i have two more questions about drag and drop or equipping an item.
If i drag and drop an item from the inventory to another slot in the inventory where also an item is, the dropped item will be placed on top of the other item. So there is no swap. How can i do that, that the dropped item will be placed ins$$anonymous$$d of the other item and the replaced item get to the mouse position?! Do i need to store the SlotItem in a temporary variable and the drag and drop item also in a variable?
And how is the workflow for equipping items? How do i cange i.e. stats if i have equipped one item? How do i effect some values? Do i need to write this code on the item itself? Or in the EquipmentSlot? What is the best way to archieve this? $$anonymous$$y item system is based on ScriptableObjects.
Anyway thank you for your help it worked perfectly! :)
Answer by strudi1986 · Jan 14, 2018 at 12:13 PM
Draggable Script:
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public Transform parentToReturnTo = null;
public void OnBeginDrag (PointerEventData eventData)
{
parentToReturnTo = this.transform.parent;
this.transform.SetParent (this.transform.parent);
GetComponent<CanvasGroup> ().blocksRaycasts = false;
}
public void OnDrag (PointerEventData eventData)
{
//this.transform.position = eventData.position;
transform.position = eventData.position;
}
public void OnEndDrag (PointerEventData eventData)
{
this.transform.SetParent (parentToReturnTo);
GetComponent<CanvasGroup> ().blocksRaycasts = true;
this.transform.localPosition = Vector3.zero;
}
}
ItemDropZone Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ItemDropZone : MonoBehaviour, IDropHandler {
public void OnDrop (PointerEventData eventData)
{
Draggable d = eventData.pointerDrag.GetComponent<Draggable> ();
if(d != null )
{
d.parentToReturnTo = this.transform;
}
}
}
The Items (EquipImage) have the Draggable Script attached and the Slots the Dropzone Script! Thx for help!
@Legend_Bacon maybe you have a clue/hint? :) Thx