背包系统详解

背包系统:
** 首先我们得分析背包的组成:一个背包系统有一个背包的背景UI以及格子UI和物品UI 组成差不多我们就得写三个类,代码量比较大就是物品类!**
我们先创建好预制体
在这里插入图片描述
UI设置好了之后就是开始写脚本

InventoryPanel.cs

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class InventotyInfo
{
    public int id;
    public int num;
    public int index;

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    public int Num
    {
        get { return num; }
        set { num = value; }
    }

    public int Index
    {
        get { return index; }
        set { index = value; }
    }

    public void AddNum(int number)
    {
        num += number;
    }
}
public class InventoryPanel : BasePanel
{   
    public static InventoryPanel instance;
    public Button closeButton;
    public Button arrangeBtton;
    public Transform front;
    private SlotItem[] slots ;
    //背包信息
    public List<InventotyInfo> inventotyInfos=new List<InventotyInfo>();
    //背包临时信息
    public List<InventotyInfo> tempInventoryInfos = new List<InventotyInfo>();

    public Button queryButton01;
    public Button queryButton02;
    public Button queryButton03;

    private void Awake()
    {
        instance = this;
        slots = transform.GetChild(1).GetChild(2).GetComponentsInChildren<SlotItem>();
        for (int i = 0; i < slots.Length; i++)
        {
            slots[i].index = i;
            slots[i].isItem = false;
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        inventotyInfos = GameObject.Find("MainMenuPanel").GetComponent<MainMenuPanel>().GetInventory();
        if(inventotyInfos.Count>0)
        {
            ShowAllGoods();
        }
        tempInventoryInfos= GameObject.Find("MainMenuPanel").GetComponent<MainMenuPanel>().GetBuyInventory();
        if(tempInventoryInfos!=null)
        {
            foreach (var info in tempInventoryInfos)
            {
                IncreaseGoods(info.id, info.num);
            }
            GameObject.Find("MainMenuPanel").GetComponent<MainMenuPanel>().CleanBuyInventory();
        }
     
        closeButton?.onClick.AddListener(() =>
        {
            Destroy(this.gameObject);
            MainMenuPanel mainMenuPanel= GameObject.Find("MainMenuPanel").GetComponent<MainMenuPanel>();
            mainMenuPanel.SetUIPanelState();
            mainMenuPanel.SetInventory(inventotyInfos);
        });

        arrangeBtton?.onClick.AddListener(() =>
        {
            ArrangeAllIsItemSlot();
        });
       

        queryButton01.onClick.AddListener(() =>
        {
            CleanSlotInfo();
            QueryInventory(1001);
            
        });

        queryButton03.onClick.AddListener(() =>
        {
            CleanSlotInfo();
            ShowAllGoods();
        });

        queryButton02.onClick.AddListener(()=>{
            CleanSlotInfo();
            QueryInventory(1002);
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void IncreaseGoods(int id,int num=1)
    {
        SlotItem slot;
        //首先查找背包中物品是否已存在
        slot = FindSameSlot(id);
        if(slot!=null)
        {
            InventotyInfo info = FindInventory(id);
            if(info!=null)
            {
                info.AddNum(num);
            }
            else
            {
                info = new InventotyInfo();
                info.id = id;
                info.num = num;
                info.index = slot.index;
                inventotyInfos.Add(info);
            }
            slot.transform.GetChild(0).GetComponent<GoodsItem>().PlusNubmer(num);
            return;
        }

        //物品在背包中不存在,查询背包中第一个空格子
        slot = FindEmptySlot();
        if(slot!=null)
        {
            InventotyInfo info = new InventotyInfo();
            info.id = id;
            info.num = num;
            info.index = slot.index;
            inventotyInfos.Add(info);
            slot.isItem = true;
            slot.id = id;
            GoodsItem item = CreateItem<GoodsItem>(slot.transform);
            item.SetId(id,num);
        }
        else
        {
            Debug.Log("没有空格子并且背包中也没有此物品!");
        }
    }


    public SlotItem FindEmptySlot()
    {
        foreach(var slot in slots)
        {
            if(slot.isItem==false)
            {
                return slot;
            }
        }
        return null;
    }

    public SlotItem FindSameSlot(int id)
    {
        foreach(var slot in slots)
        {
            if(slot.isItem)
            {
                if (slot.id == id)
                {
                    
                    return slot;
                }
            }
        }
        return null;
    }

    public Transform GetFront()
    {
        return front;
    }

    public void  ArrangeAllIsItemSlot()
    {
        foreach (var slot in slots)
        {
            if (slot.isItem)
            {
                Insert(slot);
            }
        }

        foreach(var info in inventotyInfos)
        {
            Debug.Log(info.index);
        }
    }

    public void Insert(SlotItem tempSlot)
    {
        for(int i=0;i<tempSlot.index-1;i++)
        {
            if(slots[i].isItem==false)
            {
                slots[i].isItem = true;
                slots[i].id = tempSlot.id;
                GoodsItem go = CreateItem<GoodsItem>(slots[i].transform);
                go.SetId(tempSlot.id, tempSlot.transform.GetChild(0).GetComponent<GoodsItem>().GetGoodsNumber());
                FindInventory(slots[i].id).index = slots[i].index;
                tempSlot.isItem = false;
                tempSlot.id = 0;
                Destroy(tempSlot.transform.GetChild(0).gameObject);
                break;
            }
        }
    }

    public InventotyInfo FindInventory(int id)
    {
        foreach(var info in inventotyInfos)
        {
            if(info.id==id)
            {
                return info;
            }
        }
        return null;
    }

    public void CleanSlotInfo()
    {
        foreach( var slot in slots)
        {
            if (slot.transform.childCount>0)
            {
                slot.id = 0;
                slot.isItem = false;
                slot.transform.GetChild(0).GetComponent<GoodsItem>().ClearInfo();
            }
        }
    }

    public void QueryInventory(int id)
    {
        SlotItem slot;
        foreach(var info in inventotyInfos)
        {
            if(info.id==id)
            {
                slot = FindEmptySlot();
                if(slot!=null)
                {
                    slot.isItem = true;
                    slot.id = id;
                    GoodsItem item = CreateItem<GoodsItem>(slot.transform);
                    item.SetId(id,info.num);
                }
            }
        }
    }

    public void ShowAllGoods()
    {
        foreach (var info in inventotyInfos)
        {
              slots[info.index].isItem = true;
              slots[info.index].id = info.id;
              GoodsItem item = CreateItem<GoodsItem>(slots[info.index].transform);
              item.SetId(info.id, info.num);
        }
    }
}

** 这个脚本里面的一些代码是没用的因为有的功能还需要其他脚本要使用还得自己把没用的代码删掉,或者评论联系我要工程源码。
**
SlotItem.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SlotItem: MonoBehaviour
{
    public int index;
    public int id = 0;
    public bool isItem = false;
    // Start is called before the first frame update
    void Start()
    {
    }
    // Update is called once per frame
    void Update()
    {

    }
}

GoodsItem.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Linq;

public class GoodsItem :BaseItem, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public int id = 0;//表明物品id
    private int num = 0;//物品数量
    private Text itemnum;//显示物品数量的文本
    private GoodsInfo goodsinfo = null;//物品信息
    private SlotItem parent;//该背包物品的网格
    private Image image;//背包物品显示的图片
    Vector3 CIPosition;//要交换位置的物品位置
    private RectTransform goodsRect;



    private Transform nowParent;
    private Transform oldParent;
    private Transform frontParent;
    private RectTransform canvas;
    private Camera uiCamera;
    private Vector2 offset;//临时记录点击点与UI的相对位置
    private CanvasGroup canvasGroup;
    // Start is called before the first frame update
    void Awake()
    {
        data = DataCache.GetInstance();
        image = this.GetComponent<Image>() as Image;
        itemnum = this.GetComponentInChildren<Text>();
        goodsRect = this.transform.GetComponent<RectTransform>();
        frontParent = GameObject.Find("InventoryPanel").transform.GetComponent<InventoryPanel>().GetFront();
        canvas = GameObject.Find("Canvas").transform.GetComponent<RectTransform>();
        canvasGroup = this.GetComponent<CanvasGroup>();
        oldParent = transform.parent;
        uiCamera = GameObject.Find("UICamera").GetComponent<Camera>();
    }
    void Start()
    {
        transform.GetComponent<Button>().onClick.AddListener(() =>
        {
            CreateItem<GoodsDescriptItem>(true).Init(goodsinfo);
        });
    }

    public void SetId(int id, int num = 1)
    {
        transform.localPosition = Vector3.zero;
        this.id = id;//把id赋值给该类的id
        goodsinfo= data.Get<List<GoodsInfo>>().Where(i => i.GoodsId == id).FirstOrDefault();
        this.SetIconName(goodsinfo.GoodsName);//这个函数用来获得物品名称
        SetImg();//该函数用来设置图片信息
        itemnum.gameObject.SetActive(true);//设置为可见
        this.num = num;
        itemnum.text = num.ToString();//显示数量
    }
    public void SetImg()
    {
        string path = goodsinfo.ImagePath;//设置图片的路径 必须要放在resources里面才可以
        image.sprite = Resources.Load(path, typeof(Sprite)) as Sprite;//将该路径的图片导入到image中
    }


    public void PlusNubmer(int num = 1)
    {
        //增加物品数量
        this.num += num; ;
        itemnum.text = this.num.ToString();
    }
    public void ClearInfo()
    {
        //清除物品
        id = 0;
        goodsinfo = null;
        num = 0;
        GameObject.Destroy(this.gameObject);
    }
    // Update is called once per frame
    void Update()
    {

    }

    public void SetIconName(string goodsname)
    {
        image.name = goodsname;
    }
    //拖拽功能的实现
    public void OnBeginDrag(PointerEventData eventData)
    {
        nowParent = transform.parent;
        transform.SetParent(frontParent);
        Vector2 mouseDown = eventData.position;
        canvasGroup.blocksRaycasts = false;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 pos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas, Input.mousePosition,uiCamera, out pos);
        goodsRect.anchoredPosition = pos;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (eventData.pointerCurrentRaycast.gameObject != null)
        {
            Debug.Log(eventData.pointerCurrentRaycast.gameObject.name);
            if (eventData.pointerCurrentRaycast.gameObject.tag == "Slot")
            {
                Transform target = eventData.pointerCurrentRaycast.gameObject.transform;
                transform.SetParent(target);
                SetRectTransformInfo(transform);
                nowParent.GetComponent<SlotItem>().isItem = false;
                nowParent.GetComponent<SlotItem>().id = 0;
                target.GetComponent<SlotItem>().id = id;
                target.GetComponent<SlotItem>().isItem = true;
                GameObject.Find("InventoryPanel").GetComponent<InventoryPanel>().FindInventory(id).index = target.GetComponent<SlotItem>().index;

            }
            else if (eventData.pointerCurrentRaycast.gameObject.tag == "Goods")
            {
                //交换位置
                Transform target = eventData.pointerCurrentRaycast.gameObject.transform;
                Transform targetParent = target.parent;
                if (targetParent == nowParent)
                {
                    GoBack();
                }
                else
                {
                    transform.SetParent(targetParent);
                    SetRectTransformInfo(transform);
                    targetParent.GetComponent<SlotItem>().isItem = true;
                    targetParent.GetComponent<SlotItem>().id = id;
                    GameObject.Find("InventoryPanel").GetComponent<InventoryPanel>().FindInventory(id).index = targetParent.GetComponent<SlotItem>().index;
                    target.SetParent(nowParent);
                    SetRectTransformInfo(target);
                    nowParent.GetComponent<SlotItem>().isItem = true;
                    nowParent.GetComponent<SlotItem>().id = target.GetComponent<GoodsItem>().id;
                    GameObject.Find("InventoryPanel").GetComponent<InventoryPanel>().FindInventory(target.GetComponent<GoodsItem>().id).index = nowParent.GetComponent<SlotItem>().index;
                }
            }
            else
            {
                GoBack();
            }
        }
        else
        {
            GoBack();
        }
        canvasGroup.blocksRaycasts = true;
    }

    public void GoBack()
    {
        transform.SetParent(nowParent);
        transform.localPosition = Vector3.zero;
    }


    public static void SetRectTransformInfo(Transform tsf)
    {
        if (tsf == null)
        {
            return;
        }
        RectTransform rectTsf = tsf.GetComponent<RectTransform>();
        rectTsf.localScale = Vector3.one;
        rectTsf.anchoredPosition = Vector2.zero; 
    }

    public int  GetGoodsNumber()
    {
        return num;
    }
}

简单传个视频:后续上传算了Bilibili再审核

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值