Unity2D初级背包设计后篇 拓展举例与不足分析

Unity2D初级背包设计中篇 MVC分层撰写(万字详解)-优快云博客

如果你已经搞懂了中篇,那么对这个背包的拓展将极为简单,我就在这里举个例子吧

目录

1.添加物品描述信息

2.拓展思路与不足分析

        1.没有删除只有丢弃功能,所以可以添加垃圾桶

        2.格子有限,可以再做的大一些,也可以添加翻页功能

3.排序与分类功能

4. 逻辑层再封装

5.背包存储可以转为json而不再是让编辑器保存


1.添加物品描述信息

M层修改:

统一到SoltData之中获得 

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

[Serializable]
public class SlotData {
    public ItemData item;
    public int currentCount = 0; // 物品数量

    private Action OnChange;

    #region 增(Add)

    // 添加物品到槽位
    public void Add(int numToAdd = 1) {
        this.currentCount += numToAdd;
        OnChange?.Invoke();
    }

    // 设置槽位的物品和数量
    public void AddItem(ItemData item, int count = 1) {
        this.item = item;
        this.currentCount = count;
        OnChange?.Invoke();
    }

    #endregion

    #region 删(Remove)

    // 减少槽位中的物品数量
    public void Reduce(int numToReduce = 1) {
        currentCount -= numToReduce;
        if (currentCount == 0) {
            Clear();
        }
        else {
            OnChange?.Invoke();
        }
    }

    // 清空槽位
    public void Clear() {
        item = null;
        currentCount = 0;
        OnChange?.Invoke();
    }

    #endregion

    #region 查(Check)

    // 检查槽位是否为空
    public bool IsEmpty() {
        return currentCount == 0;
    }

    // 检查槽位是否可以添加物品
    public bool CanAddItem() {
        return currentCount < item.maxCount;
    }

    // 获取槽位的空余空间
    public int GetFreeSpace() {
        return item.maxCount - currentCount;
    }

    #endregion

    #region 改(Update)

    // 移动槽位数据
    public void MoveSlot(SlotData data) {
        this.item = data.item;
        this.currentCount = data.currentCount;
        OnChange?.Invoke();
    }

    // 添加监听器
    public void AddListener(Action OnChange) {
        this.OnChange = OnChange;
    }

    //获取物品描述
    public string GetDescription() {
        return item.Description;
    }
    #endregion
}

V层修改:

背包UI持有该描述的组件 因此将显示和隐藏写到BagUI类 

using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class BagUI : MonoBehaviour {
    [SerializeField] private Button close;
    [SerializeField] private GameObject BG;
    [SerializeField] private GameObject slotGrid;
    [SerializeField] private List<SlotUI> soltuiList = new List<SlotUI>();
    [SerializeField] private TextMeshProUGUI DText;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start() {
        InitElement();
        InitSlotUI();
       
    }

    // Update is called once per frame
    void Update() {
        ColseBag();
    }
    public void InitElement() {
        if(BG==null)
        BG = transform.Find("BG").gameObject;
        if (close == null)
        close = transform.Find("BG/BgElement/Close").GetComponent<Button>();
        if(slotGrid)
        slotGrid = transform.Find("BG/SlotGrid").gameObject;

        if (close != null) {
            close.onClick.AddListener(() => {
                if (BG != null)
                    BG.SetActive(!BG.activeSelf);
                else {
                    Debug.LogWarning("没找到BG对象");
                    return;
                }
            });
        }
        else
            Debug.LogWarning("没有加载到close按钮");

    }

    public void UpdataUI() {
        for (int i = 0; i < InventoryManager.Instance.BagInventory.slotList.Count; i++) {
            soltuiList[i].SetData(InventoryManager.Instance.BagInventory.slotList[i]);
        }
    }

    public void InitSlotUI() {
        if (slotGrid != null) {
            foreach (SlotUI slotUi in slotGrid.GetComponentsInChildren<SlotUI>()) {
                soltuiList.Add(slotUi);
            }
        }
        UpdataUI();
    }


    public void ColseBag() {
        if (Input.GetKeyDown(KeyCode.Tab))
            BG.SetActive(!BG.activeSelf);
    }

    public void ShowDescription(string description) {
        DText.gameObject.SetActive(true);

        DText.text = description;
    }
    public void HideDescription() {
        DText.gameObject.SetActive(false);
        DText.text = "";
    }

}

        之后当鼠标移入SoltUI之后,触发上面两种方法 ,这里可以采用事件发送的方法,也可以直接去持有对象

        

using System;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class SlotUI : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler, IPointerExitHandler {
    protected SlotData slotData;
    
    protected Image icon;
    protected TextMeshProUGUI num;

   [SerializeField]private BagUI bagUI;

    private void Start() {
       
        icon = transform.Find("icon").GetComponent<Image>();
        num = transform.Find("num").GetComponent<TextMeshProUGUI>();
    
    }
    public SlotData GetData(){ 
        return slotData;
    }

    /// <summary>
    /// 为该脚本上的对象赋值一个SlotData
    /// </summary>
    public void SetData(SlotData slotData) { 
        this.slotData = slotData;

        //事件监听 - 订阅者
        slotData.AddListener(UpdateUI2Slot);

        UpdateUI2Slot();
    }

    / <summary>
    / 监听对象
    / </summary>
    //public void ChangeUI(){
    //    UpdateUI2Slot();
    //}

    private void UpdateUI2Slot(){

        if (slotData==null || slotData.item == null || slotData.currentCount <= 0) {
           
            icon.enabled = false;
            num.enabled = false;
        }
        else {
            icon.enabled = true;
            num.enabled = true;
            icon.sprite = slotData.item.itemSprite;
            num.text = slotData.currentCount.ToString();

        }
    }

    public void OnPointerClick(PointerEventData eventData) {
        Debug.Log("发生了点击");
        ItemMoveHandler.Instance.OnSlotClick(this);
    }

    public void OnPointerEnter(PointerEventData eventData) {
        Debug.Log("鼠标进入");
        if (slotData.item != null)
        bagUI.ShowDescription(slotData.GetDescription());
    }

    public void OnPointerExit(PointerEventData eventData) {
        Debug.Log("鼠标离开");
        if (slotData.item != null)
            bagUI.HideDescription();
    }
}

 

2.拓展思路与不足分析

        1.没有删除只有丢弃功能,所以可以添加垃圾桶

        2.格子有限,可以再做的大一些,也可以添加翻页功能

3.排序与分类功能

这个我将会在通用背包文章之中进行详细解释

4. 逻辑层再封装

因为物品小类自有的枚举工具/消耗品/可捡起的枚举在配置上比较烦

应该做到实时判断,也就是策划只需要给物品配置 ,然后一键导入就行了

    只需要:

    不再需要:

5.背包存储可以转为json而不再是让编辑器保存

以上,2D初级背包结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈基咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值