第三部分:背包——数据定义部分

        实现一个简易的背包系统(相关数据定义部分):

一:数据定义部分

        1:物品数据ItemData_SO:

        包含了物品类型,物品名字,物品图标,图片消息描述以及物品是否可以堆叠。

//物品的数据信息
[CreateAssetMenu(fileName ="New Item",menuName ="Item/Item Data")]
public class ItemData_SO : ScriptableObject
{
    public ItemType itemType;        //物品类型

    public string itemName;          //物品名字

    public Sprite itemIcon;          //物品图标

    [TextArea]
    public string itemDescription;   //物品详细描述

    public bool statckable;          //物品是否可以被堆叠


}

        2:背包物品数据InventoryItem

        包含了物品的数据以及物品的个数。

[System.Serializable]
public class InventoryItem
{
    public ItemData_SO itemData;

    public int itemAmount;
}

        3:背包数据

        包含了物品的列表,背包的容量,以及当前背包中的物品数量。

        实现了AddItem(往背包中添加物品的方法):分为可堆叠和不可堆叠两种情况。

        可堆叠:查找背包中是否有相同物体(根据ItemData判断),如果查找到了,直接使其的物品数量++即可。否则转入新创建的情况。

        不可堆叠:遍历items,一旦找到了items里面的itemData为null的情况(指定位置上没有物品),则直接在该位置上创建新物品。

//背包的数据
[CreateAssetMenu(fileName ="New Inventory",menuName ="Inventory/Inventory Data")]
public class InventoyrData_SO : ScriptableObject
{
    public List<InventoryItem> items;

    public int itemCapacity;   //当前背包的容量是多少 
     
    public int itemCount;      //当前背包中一共有多少物品

    //在当前背包中添加物品
    public bool AddItem(ItemData_SO itemData)
    {
        if (itemCount == itemCapacity) return false;
        //可堆叠的情况
        if (itemData.statckable)
        {
            for (int i = 0; i < items.Count; i++)
            {
                //直接进行叠加操作
                if (items[i].itemData == itemData)
                {
                    items[i].itemAmount++;
                    return true;
                }
            }
        }
        //需要在背包中新添加这个物品
        for (int i = 0; i < items.Count; i++)
        {
            if (items[i].itemData==null)
            {
                items[i].itemData = itemData;
                items[i].itemAmount = 1;
                itemCount++;
                return true;
            }
        }
        //没有添加成功,说明背包满了 
        return false;
    }
}

二:UI显示部分

        分为三层内容:Container(容器),SlotHolder(方格),ItemUI(图片物品)

        1:ItemUI(物品UI):

        包含其隶属于哪个背包和它所在的下标,以及itemUI的属性:ItemData物品数据,Image物品图标,amountText个数显示;

        SetUpItemUI:更新方法,传入物品数据和物品个数,设置相应的UI图片显示。

public class ItemUI : MonoBehaviour
{
    public InventoryData_SO Bag { get; set; } //物品所属与哪个背包
    public int Index { get; set; } = -1; //物品在背包中的下标值

    [HideInInspector] public ItemData_SO itemData;

    [SerializeField] private Image itemIcon;

    [SerializeField] private TextMeshProUGUI amountText;

    private async void LoadSprite()
    {
        var spriteAssetReference = new AssetReference(itemData.serializeSprite.spriteAddress);
        itemIcon.sprite = await spriteAssetReference.LoadAssetAsync<Sprite>().Task;
    }

    public void SetUpItemUI(ItemData_SO itemData, int amount)
    {
        if (amount == 0)
        {
            Bag.items[Index].itemData = null;
            this.itemData = null;
            itemIcon.gameObject.SetActive(false);
            itemIcon.sprite = null;
            return;
        }

        if (amount < 0) itemData = null;

        if (itemData != null)
        {
            this.itemData = itemData;
            LoadSprite();
            amountText.text = amount.ToString();
            itemIcon.gameObject.SetActive(true);
        }
        else
        {
            itemIcon.gameObject.SetActive(false);
        }
    }

    #region 获取实际物品的接口(从背包数据库中获取)

    public InventoryItem GetInventoryItem => Bag.items[Index];

    public int GetItemAmount => Bag.items[Index].itemAmount;

    //public ItemData_SO GetItemData => Bag.items[Index].itemData;
    public ItemData_SO GetItemData => itemData;

    #endregion
}

        2:SlotHolder(存放物品UI的具体方格):

        自身的属性有slotType(方格类型),itemUI(子物体图片UI)

        UpdateItem:设置图片UI所属的背包(Switch选择语句),通过背包数据库找到ItemUI下标Index所指代的实际的物品,然后进行下行更新图片UI。

public class SlotHolder : MonoBehaviour
{
    public SlotType slotType;

    public ItemUI itemUI;

    //通过SlotType获取对应的背包数据库 依次来更新其中的ItemUI
    public void UpdateItem()
    {
        itemUI.Bag = slotType switch
        {
            SlotType.ConsumableBag => InventoryManager.Instance.consumableInventory,
            SlotType.EquipmentBag => InventoryManager.Instance.euqipmentsInventory,
            SlotType.PrimaryWeapon => InventoryManager.Instance.playerEuqipmentInventory,
            SlotType.SecondaryWeapon => InventoryManager.Instance.playerEuqipmentInventory,
            SlotType.Action => InventoryManager.Instance.actionInventory,
            _ => null
        };
        //通过背包数据库 找到ItemUI下标对应的物品 对ItemUI进行更新
        var item = itemUI.Bag.items[itemUI.Index];
        itemUI.SetUpItemUI(item.itemData, item.itemAmount);
    }

}

            3:Container(存放所有SlotHolder的容器):

            创建SlotHloder列表(可以在编辑器中赋值)。RefreshContainerUI:刷新操作,调用列表中所有SlotHloder的更新方法。

public class ContainerUI : MonoBehaviour
{
    public SlotHolder[] slotHolders;

    //刷新每个格子的内容 在获取物品的时候调用
    public void RefreshContainerUI()
    {
        for(int i=0;i<slotHolders.Length;i++)
        {
            slotHolders[i].itemUI.Index = i;
            slotHolders[i].UpdateItem();
        }
    }
}

        InventoryManager:

        内含所有的背包数据和背包容器,在Start时初始化状态。

public class InventoryManager : Singleton<InventoryManager>
{
    [Header("背包数据")]
    public InventoyrData_SO consumableInventory;
    
    public InventoyrData_SO euqipmentsInventory;

    public InventoyrData_SO playerEuqipmentInventory;

    public InventoyrData_SO actionInventory;

    [Header("背包容器")]
    public ContainerUI consumableContainer;        //消耗品背包

    public ContainerUI equipmentsContainer;        //装备背包

    public ContainerUI actionContainer;            //快捷栏上的背包

    public ContainerUI playerEquipmentContainer;   //人物正在装备的装备背包

    private ContainerUI currentShowContainer;      //当前选择的背包 (指角色面板中的背包选项,不包括人物正在穿的装备)

    [Header("内容组件")]
    public TextMeshProUGUI titleText;

    [Header("拖拽相关")]
    public Canvas dragCanvas;

    public class DragData
    {
        public SlotHolder orignalSlot;
        public RectTransform orignalParent;
    }

    public DragData currentDrag;

    public ContainerUI CurrentShowContainer { 
        get => currentShowContainer;
        set
        {
            currentShowContainer = value;
            if (value == consumableContainer) SelectConsumableContainer();
            else if (value == equipmentsContainer) SelectEuqipmentsContainer();
        } 
    }

    private void Start()
    {
        CurrentShowContainer = consumableContainer;
        CurrentShowContainer.RefreshContainerUI();
        equipmentsContainer.RefreshContainerUI();
        actionContainer.RefreshContainerUI();
        playerEquipmentContainer.RefreshContainerUI();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值