Already mentionned here Double click instead of dragging but the topic is closed. ^^
It is a pretty common QoL feature to clicky swap an item by double clicking on it, instead of always drag and drop it.
Here how I impleted it.
First we need to add a method in EquipementSlotUI
public EquipLocation GetEquipLocation()
{
return equipLocation;
}
After that we need to go to DragItem and change the method DropItemIntoContainer from private to protected. The class is in GameDevTV.Core.UI.Dragging .
And with that, the preparations are complete, we can begin to modify InventoryDragItem inside GameDevTV.UI.Inventories
using System.Collections.Generic;
using GameDevTV.Core.UI.Dragging;
using GameDevTV.Inventories;
using UnityEngine;
using UnityEngine.EventSystems;
namespace GameDevTV.UI.Inventories
{
/// <summary>
/// To be placed on icons representing the item in a slot. Allows the item
/// to be dragged into other slots.
/// </summary>
public class InventoryDragItem : DragItem<InventoryItem>, IPointerClickHandler
{
private const float DOUBLE_CLICK_TIME = 0.3f;
private float lastClickTime;
public void OnPointerClick(PointerEventData eventData)
{
float timeSinceLastClick = Time.time - lastClickTime;
// Double click ! We wil try to swap between the equipement and inventory.
if (timeSinceLastClick <= DOUBLE_CLICK_TIME)
{
EquipableItem removedSourceItem = source.GetItem() as EquipableItem;
// If not equipable, don't bother.
if (removedSourceItem == null) return;
IDragContainer<InventoryItem> destination = null;
if (source is InventorySlotUI)
{
// We clicked on an InventorySlot. Lets try to find a corresponding EquipementSlot.
IEnumerable<EquipmentSlotUI> equipementSlots = FindObjectsOfType<EquipmentSlotUI>();
foreach (EquipmentSlotUI equipementSlot in equipementSlots)
{
if (equipementSlot.GetEquipLocation() == removedSourceItem.GetAllowedEquipLocation())
{
destination = equipementSlot;
break;
}
}
}
if (source is EquipmentSlotUI)
{
// We clicked on an EquipementSlot. Lets try to find a empty InventorySlot.
IEnumerable<InventorySlotUI> inventorySlots = FindObjectsOfType<InventorySlotUI>();
foreach (InventorySlotUI inventorySlot in inventorySlots)
{
if (inventorySlot.GetItem() == null)
{
// we find an empty slot.
destination = inventorySlot;
break;
}
}
}
// We find a candidate slot for swaping.
if (destination != null)
{
DropItemIntoContainer(destination);
}
}
lastClickTime = Time.time;
}
}
}
We could have changed DragItem directly, but that’s a bad idea in my opinion, because it should not have to know the logic for Equipement, or Inventory, and will introduce circular dependencies.
It could probably also handled to assign an ActionItem inside an empty ActionSlot, but I will wrap up here for my part.
Don’t hesitate to point ou improvements or mistakes.
Thanks.