以本地资源类(ScriptableObject)实现数据存储/读取
//背包资源类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Inventory")]
//背包类
public class Inventory : ScriptableObject
{
#region
/public static Inventory GetInventory()
{
return Resources.Load
}
#endregion
//物品类列表
public List<Items> itemList = new List<Items>();
}
//物品类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Item" ,menuName = "Inventory/New Item")]
//物品类
public class Items : ScriptableObject
{
public string itemName ;//物品名称
public Sprite ItemImage;//物品图标
public int ItemHild;//物品数量
[TextArea]//文本框,存储多字符串
public string ItemInfo;//物品信息
public bool equip;//可可装备属性
}
//UI预制件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Slot : MonoBehaviour
{
public int slotID;//空格的ID
//public Items slotItem;
public Image slotImage;//物品图标
public Text slotNum;//物品数量
private Button itemButton;//可点击物体按钮
public GameObject itemInSlot;//物品整体UI
public string slotInfo;//物品信息
private void Awake()
{
itemButton = this.gameObject.GetComponentInChildren<Button>();
itemButton.onClick.AddListener(ItemOnClecked);
}
public void ItemOnClecked()
{
InventoryManager.UpdateItemInfo(slotInfo );//点击时显示物品信息,
//(物品位置交换后UI预制件中仍存储原来物品的信息,调用的也是创建时赋值的信息)场景重新加载 时UI预制件中的信息得到更新
}
public void SetupSlot (Items item)//刷新背包时传过来的本地资源中的物品对象
{
if(item == null )//本地背包列表中物品为空时吟唱空白的物品对象,然后返回
{
itemInSlot.SetActive(false);
return;
}
//不为空时对UI预制件进行赋值
slotImage.sprite = item.ItemImage;//图标
slotNum.text = item.ItemHild.ToString();//数量
slotInfo = item.ItemInfo;//物品信息
}
}
//世界中的物品
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//世界中的物品脚本
public class ItemOnWord : MonoBehaviour
{
public Items thisItem;//物品种类
public Inventory platerInventer;//要加入的背包
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject .CompareTag ("Player"))//Tag相同时返回TRUE,
{
AddItems();
}
Destroy(this.gameObject);
}
public void AddItems()
{
if (!platerInventer.itemList.Contains (thisItem ))//List方法包含此元素时返回TRUE,不包含返回FALSE
{
for (int i = 0; i < platerInventer.itemList.Count; i++)//背包中没有该物品时遍历
{
if (platerInventer .itemList[i]==null) //将物品添加到第一个空位置
{
platerInventer.itemList[i] = thisItem;
break;//跳出循环
}
}
}else
{
thisItem.ItemHild += 1;//背包中有该物品时数量加一
}
InventoryManager.RefreshItem();//刷新背包
}
}
//背包管理脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//背包管理脚本
public class InventoryManager : MonoBehaviour
{
public static InventoryManager instance;
public Inventory myBag;
public GameObject parentPanle;
//public Slot slotPrefab;
public GameObject prefab;
public Text itemInfromation;
//运行时的物品List,与本地数据保持一致
public List<GameObject> slot = new List<GameObject>();
private void Awake()//单例模式
{
if (instance != null)
Destroy(this);
instance = this;
}
private void OnEnable()//启用时刷新一次
{
//print("refs");
//print(parentPanle.transform.childCount);
RefreshItem();
instance.itemInfromation.text = " ";
}
public static void UpdateItemInfo(string ItemInfo)
{
instance.itemInfromation.text = ItemInfo;
}
public static void RefreshItem()
{
//清空背包
ClearBag();
//清空后,再根据本地资源类重新生成UI预制件设置其中的Items相关属性
for (int i=0;i< instance.myBag.itemList.Count;i++)
{
//CreateNewItem(item);
instance.slot.Add(Instantiate(instance.prefab));
instance.slot[i].transform.SetParent(instance.parentPanle.transform);
instance.slot[i].GetComponent<Slot>().slotID = i;
instance.slot[i].GetComponent<Slot>().SetupSlot(instance.myBag.itemList[i]);
}
}
//清空UI中背包所有物品的方法
public static void ClearBag()
{
if (instance.parentPanle.transform.childCount == 0)
return;
for (int i = 0; i < instance .parentPanle .transform .childCount ; i++)
{
Destroy(instance.parentPanle.transform.GetChild(i).gameObject);
instance.slot.Clear();
}
}
}
//------------------------物品拖拽/交换位置-----------------------------------//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ItemOnnDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler//拖拽接口
{
public Transform originatParent;
public Inventory myBag;
private int currentItemID;
public void OnBeginDrag(PointerEventData eventData)//按下时
{
originatParent = transform.parent;//记录初始所在父物体
currentItemID = originatParent.GetComponent<Slot>().slotID;//记录初始父物体在界面/本地数据List中位置
transform.SetParent(transform.parent.parent);//点击后将物体UI的父物体设置为与抽屉的父物体同级,方便显示
transform.position = eventData.position;//物体UI位置跟随屏幕滚光标
GetComponent<CanvasGroup>().blocksRaycasts = false;//隐藏物品图标屏幕射线检测,使射线可检测到下层父级物体
}
public void OnDrag(PointerEventData eventData)//拖拽时
{
transform.position = eventData.position;//拖拽时物体UI根数屏幕光标
print(eventData.pointerCurrentRaycast.gameObject.name);//屏幕射线检测到的物体名称
}
public void OnEndDrag(PointerEventData eventData)//拖拽结束时
{
if (eventData.pointerCurrentRaycast.gameObject != null)//如果屏幕射线检测到的物体不为空时
{
if (eventData.pointerCurrentRaycast.gameObject.name == "Item Image")//物品栏有物品时,物品未隐藏可被检测到(物品UI的图标)
{
//原物体UI移动到背包中目标物体UI位置
transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform.parent.parent);//物品UI图标的父级的父级(Slot)
transform.position = eventData.pointerCurrentRaycast.gameObject.transform.parent.parent.position;
//将目标物体UI移动到原物体UI位置
eventData.pointerCurrentRaycast.gameObject.transform.parent.SetParent(originatParent);
eventData.pointerCurrentRaycast.gameObject.transform.parent.position = originatParent.position;
//交换本地数据中物体的存储位置
var temp = myBag.itemList[currentItemID];//本地数据中原物体保存为中间值
//本地数据中原物体移动到目标物体位置
myBag.itemList[currentItemID] = myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID];
//本地数据中目标物体位置变为中间值(原物体)
myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID] = temp;
//交换存储位置
GetComponent<CanvasGroup>().blocksRaycasts = true;//交换完成开启屏幕射线检测,可再次拖拽
return;//目标栏有物体,交换完成退出方法
}
if (eventData.pointerCurrentRaycast.gameObject.name == "Slot(Clone)")//目标栏为空时(检测到的是抽屉)
{
//原物体之间放入目标抽屉
transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform);
transform.position = eventData.pointerCurrentRaycast.gameObject.transform.position;
//将本地数据中的空物体赋值为,本地数据库中的目标物体
myBag.itemList[eventData.pointerCurrentRaycast.gameObject.GetComponentInParent<Slot>().slotID] = myBag.itemList[currentItemID];
//如果如表抽屉不是原来的抽屉时执行
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<Slot>().slotID != currentItemID)
myBag.itemList[currentItemID] = null;//之后本地数据中的目标物体设为空
GetComponent<CanvasGroup>().blocksRaycasts = true;//交换完成开启屏幕射线检测,可再次拖拽
return;//目标栏有物体,交换完成退出方法
}
}
//其他任何位置返回原位(非UI元素时)
transform.SetParent(originatParent);
transform.position = originatParent.position;
GetComponent<CanvasGroup>().blocksRaycasts = true;
}
}