一、脚本编程
1、修改SlotUI.cs
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;
namespace MFarm.Inventory
{
public class SlotUI : MonoBehaviour,IPointerClickHandler,IBeginDragHandler,IDragHandler,IEndDragHandler
{
[Header("组件的获取")]
[SerializeField] private Image slotImage;
[SerializeField] private TextMeshProUGUI amountText;
public Image slotHightlight;
[SerializeField] private Button button;
[Header("格子类型")]
public SlotType slotType;
public bool isSelected;
public int slotIndex;
//物品信息
public ItemDetails itemDetails;
public int itemAmount;
private InventoryUI inventoryUI=>GetComponentInParent<InventoryUI>();
private void Start()
{
isSelected = false;
if (itemDetails.itemID == 0)
{
UpdateEmptySlot();
}
}
//更新格子UI和信息
public void UpdateSlot(ItemDetails item, int amount)
{
itemDetails = item;
slotImage.sprite = item.itemIcon;
itemAmount = amount;
amountText.text = amount.ToString();
slotImage.enabled = true;
button.interactable = true;
}
//将Slot更新为空
public void UpdateEmptySlot()
{
if (isSelected)
{
isSelected = false;
}
slotImage.enabled = false;
amountText.text = string.Empty;
button.interactable = false;
}
public void OnPointerClick(PointerEventData eventData)
{
if (itemAmount == 0) return;
isSelected=!isSelected;
inventoryUI.UpdateSlotHightlight ( slotIndex );
}
public void OnBeginDrag(PointerEventData eventData)
{
if (itemAmount != 0)
{
inventoryUI.dragItem.enabled = true;
inventoryUI.dragItem.sprite = slotImage.sprite;
inventoryUI.dragItem.SetNativeSize();
isSelected = true;
inventoryUI.UpdateSlotHightlight(slotIndex);
}
}
public void OnDrag(PointerEventData eventData)
{
inventoryUI.dragItem.transform.position=Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData)
{
inventoryUI.dragItem.enabled = false;
// Debug.Log(eventData.pointerCurrentRaycast.gameObject);
if (eventData.pointerCurrentRaycast.gameObject != null)
{
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<SlotUI>() == null)
return;
var targetSlot = eventData.pointerCurrentRaycast.gameObject.GetComponent<SlotUI>();
int targetIndex = targetSlot.slotIndex;
//在Player自身背包范围内进行交换
if (slotType == SlotType.Bag && targetSlot.slotType == SlotType.Bag)
{
InventoryManager.Instance.SwapItem(slotIndex, targetIndex);
}
//清空所有高亮
inventoryUI.UpdateSlotHightlight(-1);
}
/* else //测试丢在地上
{
if(itemDetails.canDropped)
{
//鼠标对应世界地图坐标
var pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));
EventHandler.CallInstantiateItemInScene(itemDetails.itemID, pos);
}
}*/
}
}
}
2、修改InventoryManager.cs文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MFarm.Inventory
{
public class InventoryManager : Singleton<InventoryManager>
{
[Header("物品数据")]
public ItemDataList_SO itemDataList_SO;
[Header("背包数据")]
public InventoryBag_SO playerBag;
private void Start()
{
EventHandler.CallUpdateInventoryUI(InventoryLocation.Player, playerBag.itemList);
}
public ItemDetails GetItemDetails(int ID)
{
return itemDataList_SO.itemDetailsList.Find(i=>i.itemID==ID);
}
//添加物品
public void AddItem( Item item ,bool toDestory)
{
int index = GetItemIndexInBag(item.itemID);//拿到物品ID或判断有没有物品
AddItemAtIndex(item.itemID,index,1);
Debug.Log(GetItemDetails (item.itemID).itemID +"Name:"+ GetItemDetails(item.itemID).itemName);
if (toDestory)
{
Destroy(item.gameObject);
}
//更新UI
EventHandler.CallUpdateInventoryUI(InventoryLocation.Player, playerBag.itemList);
}
private bool CheckBagCapacity() //判断背包里有没有空位置
{
for (int i = 0; i < playerBag.itemList.Count; i++)
{
if (playerBag.itemList[i].itemID ==0)
return true ;
}
return false ;
}
private int GetItemIndexInBag(int ID)//判断背包里有没有物品
{
for (int i = 0; i < playerBag.itemList.Count; i++)
{
if (playerBag.itemList[i].itemID == ID)
return i;
}
return -1;
}
//在指定位置添加物品
private void AddItemAtIndex(int ID, int index, int amount)
{
if (index == -1&& CheckBagCapacity()) //背包里没有物品,同时有空位
{
var item = new InventoryItem { itemID = ID, itemAmount = amount };
for (int i = 0; i < playerBag.itemList.Count; i++)
{
if (playerBag.itemList[i].itemID == 0)
{
playerBag.itemList[i]= item;
break;
}
}
}
else//背包有这个物品
{
int currentAmount = playerBag.itemList[index].itemAmount+amount;
var item = new InventoryItem { itemID = ID,itemAmount = currentAmount };
playerBag.itemList[index] = item;
}
}
//背包范围内交换物品
public void SwapItem(int formIndex, int toIndex)
{
InventoryItem currentItem = playerBag.itemList[formIndex];
InventoryItem targeItem = playerBag.itemList[toIndex];
if (targeItem.itemID != 0)
{
InventoryItem T= playerBag.itemList[formIndex];
playerBag.itemList[formIndex] = playerBag.itemList[toIndex];
playerBag.itemList[toIndex] = T;
}
else
{
playerBag.itemList[toIndex] = playerBag.itemList[formIndex]; ;
playerBag.itemList[formIndex]=new InventoryItem();
}
EventHandler.CallUpdateInventoryUI(InventoryLocation.Player, playerBag.itemList);
}
}
}
3、创建ItemManager.cs文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MFarm.Inventory
{
public class ItemManager : MonoBehaviour
{
public Item itemPrefabs;
private Transform itemParent;
private void OnEnable()
{
EventHandler.InstantiateItemInScene += InstantiateItemInScene;
}
private void OnDisable()
{
EventHandler.InstantiateItemInScene -= InstantiateItemInScene;
}
private void Start()
{
itemParent = GameObject.FindWithTag("ItemParent").transform;
}
private void InstantiateItemInScene(int ID, Vector3 pos)
{
var item = Instantiate(itemPrefabs, pos, Quaternion.identity,itemParent);
item.itemID = ID;
}
}
}
4、编辑EventHandler.cs文件
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements.Experimental;
public static class EventHandler
{
public static event Action<InventoryLocation, List<InventoryItem>> UpdateInventoryUI;
public static void CallUpdateInventoryUI(InventoryLocation location, List<InventoryItem> list)
{
UpdateInventoryUI?.Invoke(location, list);
}
public static event Action<int, Vector3> InstantiateItemInScene;
public static void CallInstantiateItemInScene(int ID, Vector3 pos)
{
InstantiateItemInScene?.Invoke(ID, pos);
}
}
二、开发操作
1、将ItemManager.cs文件赋予ItemManager文件
三、脚本逻辑
未完待续......