參考連結:
http://www.manew.com/thread-39589-1-1.html
http://www.manew.com/thread-89881-1-1.html
http://www.manew.com/thread-90065-1-1.html
效果圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICO3IjNyUjM1EDOxYDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
[RequireComponent(typeof(GridLayoutGroup))]
public class Bag : MonoBehaviour {
private List<Transform> gridList = new List<Transform>();
private string gridPrefabName = "Prefab/Grid";
private string itemPrefabName = "Prefab/Item";
private int column = 5;
private int row = 3;
void Awake ()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
GameObject go = Instantiate(Resources.Load(gridPrefabName)) as GameObject;
go.transform.SetParent(transform, false);
gridList.Add(go.transform);
}
}
}
//添加物品
public void AddItem(string itemName, int count = 1)
{
//如果有相同的物品,則隻是更改包裡該物品的數量;否則執行個體化該物品,改數量
bool hasSameItem = false;
for (int i = 0; i < gridList.Count; i++)
{
//如果有物品
if(gridList[i].childCount > 0)
{
Transform tra = gridList[i].GetChild(0);
//如果有該物品
string name = itemName.Substring(itemName.LastIndexOf('/') + 1);
if (tra.GetComponent<Image>().sprite.name.Equals(name))
{
hasSameItem = true;
ModifyCount(tra.GetChild(0).GetComponent<Text>(), count);
break;
}
}
}
if(!hasSameItem)
{
for (int i = 0; i < gridList.Count; i++)
{
if(gridList[i].childCount == 0)
{
GameObject go = Instantiate(Resources.Load(itemPrefabName)) as GameObject;
go.GetComponent<Image>().sprite = Resources.Load<Sprite>(itemName);
go.transform.SetParent(gridList[i], false);
ModifyCount(go.transform.GetChild(0).GetComponent<Text>(), count);
break;
}
}
}
}
private void ModifyCount(Text text, int count)
{
int temp = int.Parse(text.text);
temp += count;
text.text = temp.ToString();
}
//整理
public void Tidy()
{
List<Transform> tempList = new List<Transform>();
for (int i = 0; i < gridList.Count; i++)
{
if (gridList[i].childCount > 0) tempList.Add(gridList[i].GetChild(0));
}
for (int i = 0; i < tempList.Count; i++)
{
tempList[i].SetParent(gridList[i]);
tempList[i].position = gridList[i].position;
}
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
//ICanvasRaycastFilter可以控制射線是否穿透物品,也可以使用CanvasGroup的blocksRaycasts
public class Item : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, ICanvasRaycastFilter {
private static Transform canvasTra;
private Transform nowParent;//一般來說,物品是格子的子物體,nowParent記錄的是目前物品屬于哪個格子
private bool isRaycastLocationValid = true;//預設射線不能穿透物品
public void OnBeginDrag(PointerEventData eventData)
{
if (canvasTra == null) canvasTra = GameObject.Find("Canvas").transform;
nowParent = transform.parent;
transform.SetParent(canvasTra);//将目前拖拽的物品置前
isRaycastLocationValid = false;
}
public void OnDrag(PointerEventData eventData)
{
transform.position = Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData)
{
GameObject go = eventData.pointerCurrentRaycast.gameObject;
if (go != null)
{
Debug.Log(go.name);
if (go.tag.Equals("Grid"))//放置到空格子
{
SetParentAndPosition(transform, go.transform);
}
else if (go.tag.Equals("Item"))//交換位置,注意可能需要把物品下的子物體的Raycast Target關掉
{
SetParentAndPosition(transform, go.transform.parent);
SetParentAndPosition(go.transform, nowParent);
}
else
{
SetParentAndPosition(transform, nowParent);
}
}
else
{
SetParentAndPosition(transform, nowParent);
}
isRaycastLocationValid = true;
}
private void SetParentAndPosition(Transform child, Transform parent)
{
child.SetParent(parent);
child.position = parent.position;
}
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return isRaycastLocationValid;
}
}
using UnityEngine;
using System.Collections;
public class TestBag : MonoBehaviour {
public Bag bag;
void Start ()
{
}
void Update ()
{
if (Input.GetKeyDown(KeyCode.Q)) bag.AddItem("Sprite/a" + Random.Range(1, 5));
if (Input.GetKeyDown(KeyCode.W)) bag.Tidy();
}
}