思路
1、创建UI面板以承载仓库中的物品和已装备的物品,以及物品名称和物品描述;
2、创建ItemData.cs装载物品的缩略图、描述并创建ItemData对象
3、创建一个脚本,声明并定义承载ItemData对象的数组、承载缩略图的数组。
4、显示缩略图、文本
5、实现物品交换
6、创建鼠标进、出和点击事件,分别用来显示相应物体名称、描述、缩略图和物品交换
实例
一、创建UI面板
含有物品栏、已装备物品、物品名和物品信息文本

二、创建ItemData对象
1、创建ItemData.cs,声明ItemData对象的属性
[CreateAssetMenu(menuName ="Items/Item")]
public class ItemData : ScriptableObject
{
    public string description;
    public Sprite thumbnail;
    public GameObject gameModle;
} 
2、创建ItemData.cs的子类EquipmentData.cs,增加类型属性
[CreateAssetMenu(menuName = "Items/Equipment")]
public class EquipmentData : ItemData
{
    public enum ToolType
    {
        Hoe, WateringCan, Axe, Pickaxe
    }
    public ToolType toolType;
} 
二者可以合并为:
[CreateAssetMenu(menuName ="Items/Item")]
public class ItemData : ScriptableObject
{
    public string description;
    public Sprite thumbnail;
    public GameObject gameModel;
    public enum ToolType
    {
        Hoe, WateringCan, Axe, Pickaxe
    }
    public ToolType toolType;
} 
3、在Unity中,创建各ItemData对象,分配各ItemData对象的物品信息(缩略图、描述、类型等)


三、分配ItemData对象
1、创建Manager空物体,添加InventoryManager.cs组件,设置单例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InventorySlot;
public class InventoryManager : MonoBehaviour
{
    public static InventoryManager Instance { get; private set; }
    private void Awake()
    {
        if (Instance != null && Instance != this){ Destroy(this); }
        else { Instance = this; }
    }
} 
2、编辑InventoryManager.cs,创建ItemData对象数组(物品栏中的物品)和ItemData对象
//ItemData对象数组(物品栏中的物品)
public ItemData[] tools = new ItemData[8];
//装备槽中已装备的物品
public ItemData equippedTool = null; 
3、在Unity中为tools数组(物品栏中的物品)分配ItemData对象

4、目的:可以通过引用InventoryManager类,直接调用ItemData类的物品的物品信息
四、显示UI物品缩略图
1、直接显示手持物品槽中物品的缩略图(本实例中UI未设置)
(1) 给Manage添加UIManager.cs组件,设置单例
    public static UIManager Instance { get; private set; }
    private void Awake()
    {
        if (Instance != null && Instance != this) { Destroy(this);}
        else{ Instance = this; }
    } 
(2) 编辑UIManager.cs,添加显示缩略图的方法,并在Start方法中调用这个方法
//手持物品的物品槽中的子物体的图片(缩略图)
public Image toolEquipSlotImage;
private void Start()
{
    RenderInventory();
}
public void RenderInventory()
{
    //临时变量equippedTool(手持物品)
    ItemData equippedTool = InventoryManager.Instance.equippedTool;
    if(equippedTool != null)
    {
        toolEquipSlotImage.sprite = equippedTool.thumbnail;
        toolEquipSlotImage.gameObject.SetActive(true);
        return;
    }
    toolEquipSlotImage.gameObject.SetActive(false);
} 
2、显示已装备物品的缩略图(后续更改为添加InventorySlot.cs子类HandInventorySlot.cs组件)
(1) 给已装备物品槽(见UI面板图)添加InventorySlot.cs组件,创建一个单独的显示缩略图的方法
    //待显示的ItemData对象
    ItemData itemToDisplay;
    //待显示物品的的子物体
    public Image itemDisplayImage;
    public void Display(ItemData itemToDisplay)
    {
        if (itemToDisplay != null && itemToDisplay.thumbnail != null)
        {
            itemDisplayImage.sprite = itemToDisplay.thumbnail;
            this.itemToDisplay = itemToDisplay;
            itemDisplayImage.gameObject.SetActive(true);
            return;
        }
        itemDisplayImage.gameObject.SetActive(false);
        this.itemToDisplay = null;
    } 
(2) 新建HandInventorySlot.cs
public class HandInventorySlot : InventorySlot 
(3) 编辑UIManager.cs,添加显示缩略图的方法
    //已装备物品(物品栏旁边的装备栏)
    public HandInventorySlot toolHandSlot;
    public void RenderInventory()
    {
        //显示已装备物品缩略图
        toolHandSlot.Display(InventoryManager.Instance.equippedTool);
    } 
3、显示物品栏中的物品的缩略图
(1) 编辑预制体InventorySlot,添加InventorySlot.cs组件(每个物品栏中的物品都能显示自己的缩略图)

(2) 编辑UIManager.cs,创建预制体InventorySlot数组(组成物品栏中的物品)
public InventorySlot[] toolSlots; 

(3) 在UIManager.cs中创建RenderInventoryPanel方法,显示物品栏中物品对应的缩略图
void RenderInventoryPanel(ItemData[] slots, InventorySlot[] uiSlots)
{
    for (int i = 0; i < uiSlots.Length; i++)
    {
        uiSlots[i].Display(slots[i]);
    }
} 
(4) 编辑UIManager.cs中的RenderInventory方法,调用RenderInventoryPanel方法(注意参数)
public void RenderInventory()
{
    ItemData[] inventoryToolSlot = InventoryManager.Instance.tools;
    RenderInventoryPanel(inventoryToolSlot, toolSlots);
} 
五、显示文本
1、编辑UIManager.cs,添加显示文本的方法
public Text itemNameText;
public Text itemDescriptionText;
public void DisplayItemInfo(ItemData data)
{
    if(data == null)
    {
        itemNameText.text = "";
        itemDescriptionText.text = "";
        return;
    }
    itemNameText.text = data.name;
    itemDescriptionText.text = data.description;
} 
2、编辑InventorySlot.cs,设置鼠标悬停,调用DisplayItemInfo方法显示文本
public class InventorySlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    ItemData itemToDisplay;
    public void OnPointerEnter(PointerEventData eventData)
    {
        UIManager.Instance.DisplayItemInfo(itemToDisplay);
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        UIManager.Instance.DisplayItemInfo(null);
    }
} 
六、实现物品交换
1、编辑InventorySlot.cs,为物品栏中的物品分配索引值
//物品栏中被点击的物品的索引
int slotIndex;
//分配索引
public void AssignIndex(int slotIndex)
{
    this.slotIndex = slotIndex;
} 
2、编辑UIManager.cs,为物品栏中各物品分配索引值,并在Start方法中调用分配索引值的方法
public InventorySlot[] toolSlots;
private void Start()
{
    AssignSlotIndex();
}
public void AssignSlotIndex()
{
    for (int i = 0; i < toolSlots.Length; i++)
    {
        toolSlots[i].AssignIndex(i);
    }
} 
3、编辑InventoryManager.cs,创建物品由物品栏到装备栏的方法
public void InventoryToHand(int slotIndex)
{
        //取出物品栏中的物品(在位置A)缓存到toolToEquip这个临时变量(临时位置)中
        ItemData toolToEquip = tools[slotIndex];
        //把已装备的物品转移到移出的物品的位置(位置A)上
        tools[slotIndex] = equippedTool;
        //把临时变量中的物品从临时位置转移到装备物品的位置上
        equippedTool = toolToEquip;
        //更新物品缩略图
        UIManager.Instance.RenderInventory();
} 
4、编辑InventorySlot.cs,增加点击事件
public class InventorySlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler,IPointerClickHandler
{
public virtual void OnPointerClick(PointerEventData eventData)
{
    InventoryManager.Instance.InventoryToHand(slotIndex);
}
} 
5、编辑InventoryManager.cs,创建物品由装备栏到物品栏的方法
    public void HandToInventory()
    {
            for(int i = 0;i < tools.Length; i++)
            {
                if(tools[i] == null)
                {
                    tools[i] = equippedTool;
                    equippedTool = null;
                    break;
                }
            }
            UIManager.Instance.RenderInventory();
    }
 
6、编辑HandInventorySlot.cs,设置点击已装备物品时,调用覆盖步骤4的点击事件的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using static InventorySlot;
public class HandInventorySlot : InventorySlot
{
    public override void OnPointerClick(PointerEventData eventData)
    {
        InventoryManager.Instance.HandToInventory();
    }
} 
 
编辑UIManager.cs,设置显示已装备物品
public void RenderInventory()
{
    ItemData[] inventoryToolSlot = InventoryManager.Instance.tools;
    RenderInventoryPanel(inventoryToolSlot, toolSlots);
    // 显示已装备物品缩略图
    toolHandSlot.Display(InventoryManager.Instance.equippedTool);
}
 
                


















