使用Json实现背包系统的数据存储(二)

一、美术准备(做个斧头)

在blender里面做个斧头作为需要捡起来的物体。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里放进去发现贴图颜色略有变化,我这里使用的是URP,不清楚原因,还请大家指教,有解决办法万分感谢。

二、Json数据与GUI界面连接起来

我们需要每次吃到斧头后,将斧头的数据放入到背包中(背包类的List列表)
所以我们需要一个ItemOnWorld,即世界物体与背包数据的交互

public class ItemOnWorld : MonoBehaviour
{
    [Header("物体所属的背包")]
    public BagManager Bag;

    private Item item=new Item();
    [Header("物体属性")]
    public string name;
    public int number;
    public string des;
    public string type;
    public string spritePath;


    private void Awake()//将属性赋予物体
    {
        item.name = name;
        item.number = number;
        item.des = des;
        item.type = type;
        item.spritePath = spritePath;
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            AddNewItem();
            Destroy(this.gameObject);
        }
    }

    private void AddNewItem()
    {

        foreach (var m_item in Bag.Mydata.bagData)//检测有没有同名物体,没有就添加
        {
            if (m_item.name==item.name)
            {
                m_item.number += 1;
                Debug.Log("物体:" + item.name + ",的数量:" + m_item.number);
                return;
            }

        }
        Bag.Mydata.bagData.Add(item);
        Debug.Log("加入物体");
    }
}

把这个挂到物体身上,参数填好,然后进行测试,复制5个斧头,然后查看数据是否正确添加到背包数据里
在这里插入图片描述
测试成功
在这里插入图片描述

三、将数据与背包的界面联系起来

,我们创建一个BagGuiManager脚本用来管理GUI界面,我们要做的就是使用这个脚本根据背包数据创建对应的图片。
写一个RefreshItem方法对背包进行刷新(重新根据背包数据生成物体)
CreatGUIItem是根据传入的item对slot进行赋值,(根据背包里的item数据生成GUI的具体实现)

using UnityEngine;
using UnityEngine.UI;

public class BagGuiManager : MonoBehaviour
{
    public static BagGuiManager instacne;

    private void Awake()
    {
        if (instacne != null)
        {
            Destroy(this);
        }
        instacne = this;
    }

    [Header("背包")]
    public BagManager bag;

    public Slot slot;//对应的格子
    public GameObject slotGrid;
    public Text itemDes;//物品描述

    private void OnEnable()
    {
        RefreshItem();
        itemDes.text = "";
    }

    public void CreatGUIItem(Item item)
    {
        Slot newItem = Instantiate(slot, slotGrid.transform, false);//为item,实例化一个slot并赋值
      
        newItem.soltItem = item;
        newItem.name = item.name;
        newItem.number.text = item.number.ToString();
        Debug.Log("显示的数量:" + item.number);

        //显示图片
        GameObject m_Image = Resources.Load(item.spritePath) as GameObject;
        newItem.soltImage = m_Image.GetComponent<Image>();
    }

    public void RefreshItem()//刷新数量,重新生成
    {
        for (int i = 0; i < instacne.slotGrid.transform.childCount; i++)
        {
            if (instacne.slotGrid.transform.childCount == 0)
            {
                Debug.Log("没有物体可销毁");
                break;
            }
            Destroy(instacne.slotGrid.transform.GetChild(i).gameObject);
            Debug.LogError("Destory");
        }

        //foreach (var item in bag.Mydata.bagData)
        //{
        //
        //    CreatGUIItem(item);
        //}
        for (int i = 0; i < bag.Mydata.bagData.Count; i++)
        {
            Debug.Log("重新生成");
            CreatGUIItem(bag.Mydata.bagData[i]);
        }
    }
}

我们使用for或者foreach遍历背包数据,为每一个item创建slot,将item的数据赋予slot。我们为solt加一个button,点击的时候就将item的描述赋予背包GUI描述的位置(背包下方)

using UnityEngine;
using UnityEngine.UI;

public class Slot : MonoBehaviour
{
    public Item soltItem;
    public string name;
    public Image soltImage;
    public Text number;

    public void ItemOnClick()
    {
        Debug.Log("点击solt");
        BagGuiManager.instacne.itemDes.text = soltItem.des;
    }
}

slot是一个预制体,它是显示在背包中的图片,它拥有数量和图片的属性,创造slot就是创造背包中的ui,
这里的图片赋值使用的是资源加载方式,
一,将做好的图片预制体放在Resources目录,根据路径加载这个预制体,从而获得其图片并赋值。(as 加载方式)

GameObject m_Image = Resources.Load(item.spritePath) as GameObject;
newItem.soltImage.sprite = m_Image.GetComponent<Image>().sprite;

二,通过Resouces.Load泛型加载
(泛型加载方式)

newItem.soltImage.sprite = Resources.Load<Sprite>(item.spritePath);//不能使用as Sprite,
//会失败,要使用泛型的加载

在这里插入图片描述
最后我们需要每次添加新物体的时候都对GUI背包进行刷新,即在ItemOnWorld 中碰到物体,添加到数据背包的时候,添加一步刷新GUI界面,并且调用BagManager中的SaveGame方法
在这里插入图片描述
在这里插入图片描述

成功将背包数据和背包GUI联系起来
在这里插入图片描述
最后我们在背包脚本中调用读取方法,在每次游戏开始时,读取Json数据,刷新背包GUI。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、完整代码参考

using UnityEngine;
using UnityEngine.UI;

public class BagGuiManager : MonoBehaviour
{
    public static BagGuiManager instacne;

    private void Awake()
    {
        if (instacne != null)
        {
            Destroy(this);
        }
        instacne = this;
    }

    [Header("背包")]
    public BagManager bag;

    public Slot slot;
    public GameObject slotGrid;
    public Text itemDes;

    private void OnEnable()
    {
        RefreshItem();
        itemDes.text = "";
    }

    public void CreatGUIItem(Item item)
    {
        Slot newItem = Instantiate(slot, slotGrid.transform, false);
        //newItem.gameObject.transform.SetParent(slotGrid.transform,false);//设置父物体
        newItem.soltItem = item;
        newItem.name = item.name;
        newItem.number.text = item.number.ToString();
        Debug.Log("显示的数量:" + item.number);

        //显示图片
        
        //GameObject m_Image = Resources.Load(item.spritePath) as GameObject;
        //newItem.soltImage.sprite = m_Image.GetComponent<Image>().sprite;//做成预制体,然后通过加载预制体赋予图片,as 加载方式

        newItem.soltImage.sprite = Resources.Load<Sprite>(item.spritePath);//不能使用as Sprite,会失败,要使用泛型的加载
    }

    public void RefreshItem()//刷新数量,重新生成
    {
        for (int i = 0; i < instacne.slotGrid.transform.childCount; i++)
        {
            if (instacne.slotGrid.transform.childCount == 0)
            {
                Debug.Log("没有物体可销毁");
                break;
            }
            Destroy(instacne.slotGrid.transform.GetChild(i).gameObject);
            Debug.LogError("Destory");
        }

        //foreach (var item in bag.Mydata.bagData)
        //{
        //
        //    CreatGUIItem(item);
        //}
        for (int i = 0; i < bag.Mydata.bagData.Count; i++)
        {
            Debug.Log("重新生成");
            CreatGUIItem(bag.Mydata.bagData[i]);
        }
    }
}
using UnityEngine;
using UnityEngine.UI;

public class Slot : MonoBehaviour
{
    public Item soltItem;
    public string name;
    public Image soltImage;
    public Text number;

    public void ItemOnClick()
    {
        Debug.Log("点击solt");
        BagGuiManager.instacne.itemDes.text = soltItem.des;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemOnWorld : MonoBehaviour
{
    //[Header("物体所属的背包")]
    //public BagManager Bag;

    private Item item=new Item();
    [Header("物体属性")]
    public string name;
    public int number;
    public string des;
    public string type;
    public string spritePath;


    private void Awake()//将属性赋予物体
    {
        item.name = name;
        item.number = number;
        item.des = des;
        item.type = type;
        item.spritePath = spritePath;
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            AddNewItem();
            Destroy(this.gameObject);
        }
    }

    private void AddNewItem()
    {

        foreach (var m_item in BagManager.instacne.Mydata.bagData)//检测有没有同名物体,没有就添加
        {
            if (m_item.name==item.name)
            {
                m_item.number += number;
                Debug.Log("物体:" + item.name + ",的数量:" + m_item.number);
                BagGuiManager.instacne.RefreshItem();
                return;
            }

        }
        BagManager.instacne.Mydata.bagData.Add(item);
        Debug.Log("加入物体");
        BagGuiManager.instacne.RefreshItem();
        // BagGuiManager.instacne.CreatGUIItem(item);

    }
}

五、仓库地址

https://github.com/euphoriaer/Mybag.git

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值