470 lines
15 KiB
C#
470 lines
15 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using static SimpleInventorySystem.GridUI;
|
|
using System;
|
|
|
|
namespace SimpleInventorySystem
|
|
{
|
|
[RequireComponent(typeof(RectTransform), typeof(CanvasGroup))]
|
|
public class ItemUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
private RectTransform rectTransform;
|
|
private Image image;
|
|
public Canvas canvas;
|
|
private CanvasGroup canvasGroup;
|
|
private float scale = 1f;
|
|
public SlotUI previousSlot { get; private set; }
|
|
private SlotUI slot;
|
|
private Cell[] cells;
|
|
private bool isDragging;
|
|
public int width;
|
|
public int height;
|
|
private Size imageSizeOnGrid;
|
|
private Orientation imageOrientation = Orientation.Portrait;
|
|
public ItemTags ItemTag = ItemTags.Any;
|
|
public List<ItemUI> ContainedItems = new List<ItemUI>();
|
|
public ItemUI ParentContainer;
|
|
public GameObject container;
|
|
public GameObject containerUIPrefab;
|
|
public Item itemPrefab;
|
|
public bool Equipped;
|
|
public bool Stackable
|
|
{
|
|
get { return StackLimit > 1; }
|
|
}
|
|
private int count;
|
|
public int StackLimit = 1;
|
|
|
|
public int Count
|
|
{
|
|
get { return count; }
|
|
set
|
|
{
|
|
if (!Stackable)
|
|
{
|
|
count = 1;
|
|
}
|
|
else
|
|
{
|
|
count = value;
|
|
}
|
|
|
|
SetRenderItemUIPropertyValue();
|
|
}
|
|
}
|
|
private RenderItemUIProperty renderProp;
|
|
[HideInInspector] public bool PickedUpOnFrame;
|
|
[HideInInspector] public List<GameObject> ContextWindows = new List<GameObject>();
|
|
[HideInInspector] public bool IsLinkedSlotClone;
|
|
public bool PointerIsHoveredOver { get { return InventorySystem.IsMouseOverItemUITop(this); } }
|
|
public LimitStackSlotCapacity limitStackSlotCapacity;
|
|
//public Item item;
|
|
|
|
private void Awake()
|
|
{
|
|
rectTransform = GetComponent<RectTransform>();
|
|
image = transform.GetComponentInChildren<Image>();
|
|
canvasGroup = GetComponent<CanvasGroup>();
|
|
renderProp = GetComponent<RenderItemUIProperty>();
|
|
limitStackSlotCapacity = GetComponent<LimitStackSlotCapacity>();
|
|
|
|
if (width <= 0 || height <= 0)
|
|
{
|
|
Debug.LogError("Inventory ItemUI must contain a positive integer value for Width and Height: " + name);
|
|
}
|
|
|
|
Transform handler = transform.Find("Handler");
|
|
int eulerAngle = Mathf.Abs(Mathf.CeilToInt(handler.rotation.eulerAngles.z));
|
|
switch (eulerAngle)
|
|
{
|
|
case 270:
|
|
imageOrientation = (height > width) ? Orientation.Portrait : Orientation.Landscape;
|
|
break;
|
|
case 180:
|
|
imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait;
|
|
break;
|
|
case 90:
|
|
imageOrientation = (height > width) ? Orientation.Portrait : Orientation.Landscape;
|
|
break;
|
|
default:
|
|
imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait;
|
|
break;
|
|
}
|
|
|
|
//InstantiateItem();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an integer number if it has a container with a GridUI. the number returned is either -1 if no gridUI exists, or the capacity in terms of 1x1 cells.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int ContainerCapacity()
|
|
{
|
|
GridUI gridUI = null;
|
|
if(container != null && container.TryGetComponent<GridUI>(out gridUI))
|
|
{
|
|
return gridUI.gridSize.Width * gridUI.gridSize.Height;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
private void SetRenderItemUIPropertyValue()
|
|
{
|
|
if (renderProp != null)
|
|
{
|
|
renderProp.value = Count.ToString();
|
|
}
|
|
}
|
|
|
|
public void InstantiateItem()
|
|
{
|
|
//if (item == null && itemPrefab != null)
|
|
//{
|
|
// item = Instantiate(itemPrefab);
|
|
//}
|
|
}
|
|
|
|
public SlotUI GetSlotUI()
|
|
{
|
|
return slot;
|
|
}
|
|
|
|
public void OnBeginDrag(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
public void OnDrag(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
public void OnEndDrag(PointerEventData eventData)
|
|
{
|
|
//rectTransform.localPosition = new Vector3(0, 0);
|
|
}
|
|
|
|
public void Drop()
|
|
{
|
|
//Debug.Log("OnEndDrag");
|
|
if (image != null)
|
|
{
|
|
canvasGroup.alpha = 1f;
|
|
image.maskable = true;
|
|
}
|
|
canvasGroup.blocksRaycasts = true;
|
|
isDragging = false;
|
|
|
|
InventorySystem.instance.DraggedItem = null;
|
|
|
|
if (slot == null)
|
|
{
|
|
Debug.Log("ItemUI: OnEndDrag: Returning to parent");
|
|
ReturnToSlot();
|
|
}
|
|
else
|
|
{
|
|
// TODO: this need improvement
|
|
Equipped = slot.EquipSlot;
|
|
}
|
|
}
|
|
|
|
public void GrabAndDragItem()
|
|
{
|
|
if (!isDragging)
|
|
{
|
|
Debug.Log("GRAB AND DRAG");
|
|
//Debug.Log("OnPointerDown");
|
|
|
|
//Debug.Log("OnBeginDrag");
|
|
canvasGroup.alpha = .7f;
|
|
canvasGroup.blocksRaycasts = false;
|
|
SetImageScale(1);
|
|
if (slot != null)
|
|
previousSlot = slot;
|
|
transform.SetParent(canvas.transform);
|
|
//rectTransform.pivot = new Vector2(.5f, .5f);
|
|
//rectTransform.position += new Vector3(50, -50, 0);
|
|
if (slot != null)
|
|
{
|
|
slot.RemoveDragDropItem();
|
|
slot = null;
|
|
}
|
|
if (cells != null)
|
|
{
|
|
foreach (Cell c in cells)
|
|
{
|
|
if (c != null)
|
|
{
|
|
c.inUse = false;
|
|
//c.overlapped = false;
|
|
//s.ShowImage();
|
|
if (c.GetSlot() != null && c.GetSlot() != this.slot)
|
|
{
|
|
c.GetSlot().UnsetCell();// RemoveDragDropItem(true);
|
|
}
|
|
}
|
|
}
|
|
cells = null;
|
|
}
|
|
isDragging = true;
|
|
InventorySystem.instance.DraggedItem = this;
|
|
PickedUpOnFrame = true;
|
|
|
|
// Destroy each associated window, since we won't rely on windows if we are moving this item
|
|
for(int i = ContextWindows.Count - 1; i >= 0; i--)
|
|
{
|
|
ContextWindows[i].SetActive(true);
|
|
}
|
|
ContextWindows.Clear();
|
|
}
|
|
}
|
|
|
|
public void AddToContainedItems(ItemUI item)
|
|
{
|
|
ContainedItems.Add(item);
|
|
item.ParentContainer = this;
|
|
}
|
|
public void RemoveFromContainedItems(ItemUI item)
|
|
{
|
|
ContainedItems.Remove(item);
|
|
item.ParentContainer = null;
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
if (eventData.button == PointerEventData.InputButton.Left)
|
|
{
|
|
GrabAndDragItem();
|
|
}
|
|
}
|
|
|
|
public void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
if(eventData.button == PointerEventData.InputButton.Left)
|
|
{
|
|
GrabAndDragItem();
|
|
}
|
|
else if (eventData.button == PointerEventData.InputButton.Right)
|
|
{
|
|
InventorySystem.instance.OpenContextMenu(this);
|
|
}
|
|
/*else if (eventData.button == PointerEventData.InputButton.Right)
|
|
{
|
|
InventorySystem.instance.OpenContextMenu(this);
|
|
}*/
|
|
}
|
|
|
|
|
|
|
|
public void SetImageScale(float scale)
|
|
{
|
|
image.transform.localScale /= this.scale;
|
|
this.scale = scale;
|
|
image.transform.localScale *= scale;
|
|
}
|
|
|
|
public void SetSlot(SlotUI slot)
|
|
{
|
|
this.slot = slot;
|
|
}
|
|
|
|
|
|
// TODO: Make sure it was dropped somewhere, if not, return it to the original parent
|
|
public void ReturnToSlot()
|
|
{
|
|
if (previousSlot != null)
|
|
{
|
|
Debug.Log("RETURNED: " + previousSlot.gameObject.name);
|
|
previousSlot.DropOntoSlot(this.gameObject);
|
|
}
|
|
}
|
|
|
|
// Start is called\ before the first frame update
|
|
void Start()
|
|
{
|
|
imageSizeOnGrid = new Size(width * InventorySystem.instance.DefaultSizeOnGrid.Width, height * InventorySystem.instance.DefaultSizeOnGrid.Height);
|
|
|
|
if (canvas == null)
|
|
{
|
|
canvas = SimpleInventorySystem.InventorySystem.instance.inventoryUI;
|
|
}
|
|
|
|
if (Count == 0)
|
|
{
|
|
Count = 1;
|
|
}
|
|
SetRenderItemUIPropertyValue();
|
|
}
|
|
|
|
public Orientation ImageOrientation()
|
|
{
|
|
return imageOrientation;
|
|
}
|
|
|
|
public Size SizeAfterOrientation()
|
|
{
|
|
Debug.Log(imageOrientation);
|
|
if (imageOrientation == Orientation.Landscape)
|
|
{
|
|
if (width >= height)
|
|
{
|
|
return new Size(width, height);
|
|
}
|
|
else
|
|
{
|
|
return new Size(height, width);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (height >= width)
|
|
{
|
|
return new Size(width, height);
|
|
}
|
|
else
|
|
{
|
|
return new Size(height, width);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void HideSlots()
|
|
{
|
|
if (cells != null)
|
|
{
|
|
foreach (Cell cell in cells)
|
|
{
|
|
if (cell != null)
|
|
{
|
|
SlotUI slot = cell.GetSlot();
|
|
if (slot != null)
|
|
slot.HideImage();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetSlots(List<Cell> cellList)
|
|
{
|
|
cells = new Cell[cellList.Count];
|
|
for (int i = 0; i < cellList.Count; i++)
|
|
{
|
|
if (cellList[i] != null)
|
|
{
|
|
cells[i] = cellList[i];
|
|
cells[i].inUse = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsSingleCellItem()
|
|
{
|
|
return width == 1 && height == 1;
|
|
}
|
|
|
|
public bool AddToStack(int value = 1)
|
|
{
|
|
if (Stackable && Count < StackLimit)
|
|
{
|
|
Count+=value;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool RemoveFromStack(int value = 1)
|
|
{
|
|
if (Stackable && Count > 0)
|
|
{
|
|
Count-= value;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void UnsetSlots()
|
|
{
|
|
cells = null;
|
|
}
|
|
|
|
void FixedUpdate()
|
|
{
|
|
if (isDragging)
|
|
{
|
|
// TODO: fix this
|
|
rectTransform.position = InventorySystem.instance.MouseInCanvasPosition;
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if(PointerIsHoveredOver && InventorySystem.instance.DraggedItem == null)
|
|
{
|
|
if (Input.GetMouseButtonDown(0) && !isDragging && InventorySystem.instance.DraggedItem == null && !slot.DroppedOnFrame)
|
|
{
|
|
GrabAndDragItem();
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(1) && InventorySystem.instance.DraggedItem == null)
|
|
{
|
|
InventorySystem.instance.OpenContextMenu(this);
|
|
}
|
|
}
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
PickedUpOnFrame = false;
|
|
}
|
|
|
|
if (isDragging)
|
|
{
|
|
if (image != null)
|
|
{
|
|
image.maskable = false;
|
|
}
|
|
|
|
if (InventorySystem.instance.PressedKeyRotation(true))
|
|
{
|
|
//Debug.Log("Rotate");
|
|
Transform handler = transform.Find("Handler");
|
|
handler.Rotate(new Vector3(0, 0, 1), -90);
|
|
handler.localPosition = new Vector3(0, 0, 0);
|
|
int eulerAngle = Mathf.Abs(Mathf.CeilToInt(handler.rotation.eulerAngles.z));
|
|
//Debug.Log(imageSizeOnGrid.width + ", " + imageSizeOnGrid.height);
|
|
switch (eulerAngle)
|
|
{
|
|
case 270:
|
|
handler.localPosition = new Vector3(imageSizeOnGrid.Width / 4, 0, 0);
|
|
imageOrientation = (width > height) ? Orientation.Portrait : Orientation.Landscape;
|
|
break;
|
|
case 180:
|
|
handler.localPosition = new Vector3(imageSizeOnGrid.Width / 2, -imageSizeOnGrid.Height / 2, 0);
|
|
imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait;
|
|
break;
|
|
case 90:
|
|
handler.localPosition = new Vector3(0, -imageSizeOnGrid.Height, 0);
|
|
imageOrientation = (width > height) ? Orientation.Portrait : Orientation.Landscape;
|
|
break;
|
|
default:
|
|
handler.localPosition = new Vector3(0, 0, 0);
|
|
imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
//PointerIsHoveredOver = false;
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
//PointerIsHoveredOver = true;
|
|
}
|
|
}
|
|
} |