unity中背包系统(Newtonsoft储存数据)

先创建单列模式方便继承

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

public class Singleton<T> : MonoBehaviour where T : Component
{
    public static T instance {  get; private set; }
    protected virtual void Awake()
    {
        // as 强制转换类型
        instance=this as T;
    }

}

数据储存类 继承单列模式,使用Newtonsoft来储存数据

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;

public class SaveLoadManager : Singleton<SaveLoadManager>
{
    string jsonFolder;//目录
    List<ISaveable> saveableList=new List<ISaveable>();

    Dictionary<string,GameData> saveDataDic=new Dictionary<string,GameData>();

    protected override void Awake()
    {
        base.Awake();
        jsonFolder = Application.persistentDataPath + "/Save/";//文件路径
    }
    public void Regiser(ISaveable saveable)
    {
          saveableList.Add(saveable);
    }
    void OnStartGame()
    {
        var resultPath = jsonFolder + "data.sav";
        if(File.Exists(resultPath))//如果文件存在
        {
            File.Delete(resultPath);
        }
    }
    
   public void SaveGameData()
    {
        saveDataDic.Clear();
        foreach (var saveable in saveableList)
        {
            saveDataDic.Add(saveable.GetType().Name, saveable.GeneraterGameData());
        }
        var resultPath = jsonFolder + "data.sav";
        //序列化字典 独立排序
        var jsonData= JsonConvert.SerializeObject(saveDataDic, Formatting.Indented);
        //没有文件夹
        if (!File.Exists(resultPath))
        {
            //创建文件
            Directory.CreateDirectory(jsonFolder);
        }
        File.WriteAllText(resultPath, jsonData);
    }
    public void LoadGameData()
    {
        var resultPath = jsonFolder + "data.sav";
        if (!File.Exists(resultPath)) return;
        //读取数据
        var stringData= File.ReadAllText(resultPath);
        //反序列化
        var jsonData=JsonConvert.DeserializeObject<Dictionary<string,GameData>>(stringData);

        foreach (var saveable in saveableList)
        {
            //类名注册
            saveable.RestoreGameData(jsonData[saveable.GetType().Name]);
        }
    }
}

其中的GameData,是自定义的数据类


using System.Collections.Generic;
using UnityEngine;

public class GameData 
{
    //储存物品栏名字,物体id
    public Dictionary<string, int> dataDict;
    //物体id,物体数量
    public Dictionary<int, int> itemDictionary;
}

ISaveable接口 要储存数据的类,继承这个接口


//接口
public interface ISaveable 
{
    void SaveableRegiser()
    {
        SaveLoadManager.instance.Regiser(this);
    }
   
    GameData GeneraterGameData();

    void RestoreGameData(GameData saveData);
}

创建物体类的信息 用scriptableobject来创建物体信息

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

[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/New Item")]//可以在鼠标右单击 创建 找到  可以创建一New Item类的文件
public class Item : ScriptableObject//数据本地化
{
    public int id;//标识
    public Sprite itemImage;//物体图片
    public int itemNumber; //物体数量
    [TextArea]
    public string desprict;

}

创建物体数据管理类 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using Unity.VisualScripting;

public class ItemManager : Singleton<ItemManager>,ISaveable
{
    public List<Item> itemList;
    public Dictionary<int, int> itemDictionary=new Dictionary<int, int>();
    private void Start()
    {
        //注册数据
        ISaveable saveable = this;
        saveable.SaveableRegiser();

    }

    public void ItemDictionary()
    {
        itemDictionary.Clear();
        foreach (var item in itemList)
        {
            itemDictionary.Add(item.id, item.itemNumber);
        }
    }
    public void ItemList()
    {
        foreach (var item in itemList)
        {
            foreach(var dic in itemDictionary)
            {
                if(item.id==dic.Key)
                {
                    item.itemNumber=dic.Value;
                }
            }
        }
    }
    public void ItemDictionaryShow()
    {
        foreach(var dic in itemDictionary)
        {
            Debug.Log("物体 id key"+dic.Key+"物体数量 value"+dic.Value);
        }
    }

    //创建数据
    public GameData GeneraterGameData()
    {
        GameData data = new GameData();
        ItemDictionary();
        data.itemDictionary = this.itemDictionary;
        return data;
    }
    //加载数据
    public void RestoreGameData(GameData saveData)
    {
        this.itemDictionary = saveData.itemDictionary;
        ItemList();
    }
}

物体在ui上的类,用于选择,和交换位置

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

public class UIItemButton : MonoBehaviour,IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler//检测UI
{
    public Item itemScriptableObject;
    public Image image;
    public Text text;

    Transform originalParent;
    Button button;
    Canvas canvas;


    bool isMouseOver = false;
    private void Awake()
    {
        button = GetComponent<Button>();
        canvas = GetComponent<Canvas>();
    }

    private void Start()
    {
        button.onClick.AddListener(ButtonOnClick);
        image.sprite = itemScriptableObject.itemImage;
    }
   public void ButtonOnClick()
    {
        Debug.Log("按下"+gameObject.name);
        ItemShowPanel.instance.ItemInformationShow(itemScriptableObject);
    }

    // 当鼠标进入UI元素时调用
    public void OnPointerEnter(PointerEventData eventData)
    {
        Color currentColor = image.color;
        currentColor.a = 0.5f;
        image.color = currentColor;
        isMouseOver = true;
    }
    // 当鼠标离开UI元素时调用
    public void OnPointerExit(PointerEventData eventData)
    {
        Color currentColor = image.color;
        currentColor.a = 1f;
        image.color = currentColor;
        isMouseOver = false;
    }

    //开始拖拽
    public void OnBeginDrag(PointerEventData eventData)
    {
        originalParent = transform.parent;
        transform.SetParent(transform.parent.parent);

        Vector3 screenPos = eventData.position;
        screenPos.z =5;
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
        transform.position = worldPos;
    }
    //拖拽中
    public void OnDrag(PointerEventData eventData)
    {
        Vector3 screenPos = eventData.position;
        screenPos.z = 5;
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
        transform.position = worldPos;

 
    }
    //拖拽结束
    public void OnEndDrag(PointerEventData eventData)
    {
        Vector3 screenPos = eventData.position;
        screenPos.z =5 ;
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
        transform.position = worldPos;

        //射线检测是否含有UIGrid
        Vector2 mousePosition = Input.mousePosition;
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = mousePosition;
        List<RaycastResult> raycastResults = new List<RaycastResult>();
        EventSystem.current.RaycastAll(pointerEventData, raycastResults);

        bool isHaveGrid = false;
        foreach (RaycastResult result in raycastResults)
        {
            GameObject hitObject = result.gameObject;
            // 检查 UI 元素是否挂载了UIGrid脚本
            UIGrid script = hitObject.GetComponent<UIGrid>();
            if (script != null)
            {
                isHaveGrid = true;
                //是否有子物体
                UIItemButton childrenItem = script.GetComponentInChildren<UIItemButton>();
                //有物体
                if (childrenItem != null)
                {
                    //交换位置
                    childrenItem.transform.SetParent(originalParent);
                    childrenItem.transform.position = originalParent.position;
                    //背包字典更改数据  用名字绑定物体id
                    InvontoryManager.instance.RemoveValue(itemScriptableObject.id);
                    InvontoryManager.instance.UpdateValueData(originalParent.gameObject.name, childrenItem.itemScriptableObject.id);
                 

                    transform.SetParent(script.transform);
                    transform.position = script.transform.position;
                    originalParent = transform.parent;
                    InvontoryManager.instance.AddData(hitObject.name, itemScriptableObject.id);
                }
                else
                {
                    transform.SetParent(script.transform);
                    transform.position = script.transform.position;
                    originalParent = transform.parent;
                    //背包字典更改数据  用名字绑定物体id
                    InvontoryManager.instance.UpdateValueData(hitObject.name, itemScriptableObject.id);
                }            
                break;
            }              
        }
        //放在没格子的地方
        if(!isHaveGrid)
        {
            Debug.Log(originalParent);
            //返回原位置
            transform.SetParent(originalParent);
            transform.position = originalParent.position;
        }
    }
   //增加到背包中
    public void AddInInvory()
    {
        InvontoryManager.instance.AddItem(gameObject);
    }
    //减少背包物体
    public void ReduceInInvory(int number)
    {
        InvontoryManager.instance.ReduceItem(gameObject,number);
    }

    void Update()
    {
        if (isMouseOver && Input.GetKeyDown(KeyCode.Delete))
        {
            InvontoryManager.instance.RemoveItem(gameObject);
        }
    }

}

背包管理类,能加载数据,加载物体

using JetBrains.Annotations;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using static UnityEngine.Rendering.DebugUI;

public class InvontoryManager : Singleton<InvontoryManager>,ISaveable
{
    public GameObject Gird;

    public GameObject[] itemS;

    //字典必须实例化
    //背包数据
    public Dictionary<string, int> dataDict=new Dictionary<string, int>();


    private void Start()
    {
        //注册数据
        ISaveable saveable = this;
        saveable.SaveableRegiser();

    }

    //加载数据到背包中
    public void LoadInvontoryData()
    {
        ClearAllChildren();
        // 遍历字典的键
        foreach (KeyValuePair<string, int> kvp in dataDict )
        {
            string key = kvp.Key;
            int value = kvp.Value;

            foreach (Transform childTransform in transform)
            {
                GameObject childObject = childTransform.gameObject;
                if (childObject.name == key)
                {
                  var loadItem=  Instantiate(itemS[value], childObject.transform);

                    UIItemButton newItem = loadItem.GetComponent<UIItemButton>();
                    newItem.text.text = newItem.itemScriptableObject.itemNumber.ToString();
                    Debug.Log(" 加载数据"+newItem.itemScriptableObject.itemNumber.ToString());
                }
            }
        }
    }
    //清除背包格子下面的子对象
    public void ClearAllChildren()
    {
        foreach (Transform childTransform in transform)
        {
            GameObject childObject = childTransform.gameObject;
            if (childObject.transform.childCount != 0)
            {
                ClearAllChildren(childObject);
            }
        }        
    }
    //清除子对象
    public void ClearAllChildren(GameObject parent)
    {
        int childCount = parent.transform.childCount;

        for (int i = childCount - 1; i >= 0; i--)
        {
            Transform child = parent.transform.GetChild(i);
            ClearAllChildren(child.gameObject);
            Destroy(child.gameObject);
        }
    }
    //放入背包网格中
    public void AddItemInBag(GameObject _itemToAdd)
    {
        bool isEnough=true;
        //遍历外层背包
        foreach (Transform childTransform in transform)
        {
            isEnough = false;
            GameObject childObject = childTransform.gameObject;
            //没有子物体
            if (childObject.transform.childCount==0)
            {
                isEnough = true;
                UIItemButton newItem = _itemToAdd.GetComponent<UIItemButton>();
                Instantiate(newItem, childObject.transform);
                newItem.itemScriptableObject.itemNumber = 1;
                newItem.text.text = newItem.itemScriptableObject.itemNumber.ToString();

                //背包字典增加数据  用名字绑定物体id
                AddData(childObject.name, newItem.itemScriptableObject.id);

                Debug.Log(childObject.name);           
                break;
            }
        }
        if (!isEnough)
        {
            GameObject newGrid= Instantiate(Gird, transform);
            UIItemButton newItem = _itemToAdd.GetComponent<UIItemButton>();
            Instantiate(newItem, newGrid.transform);
            newItem.itemScriptableObject.itemNumber = 1;
            newItem.text.text = newItem.itemScriptableObject.itemNumber.ToString();
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    //增加物体
    public void AddItem(GameObject _itemToAdd)
    {
        UIItemButton newItem = _itemToAdd.GetComponent<UIItemButton>();
        bool isHaveItem = false;
        // 获取子对象上的多个特定类型组件
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == newItem.itemScriptableObject.id)
            {
                button.itemScriptableObject.itemNumber++;
                button.text.text = button.itemScriptableObject.itemNumber.ToString();
                isHaveItem = true;
                break;
            }
        }
        if (!isHaveItem)
        {
            AddItemInBag(_itemToAdd);
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void AddItem(GameObject _itemToAdd,int number)
    {
        UIItemButton newItem = _itemToAdd.GetComponent<UIItemButton>();
        bool isHaveItem = false;
        // 获取子对象上的多个特定类型组件
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == newItem.itemScriptableObject.id)
            {
                button.itemScriptableObject.itemNumber+= number;
                button.text.text = button.itemScriptableObject.itemNumber.ToString();
                isHaveItem = true;
                break;
            }
        }
        if (!isHaveItem)
        {
            AddItemInBag(_itemToAdd);
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void ReduceItem(GameObject _itemToReduce)
    {
        UIItemButton newItem = _itemToReduce.GetComponent<UIItemButton>();

        // 获取子对象上的多个特定类型组件
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == newItem.itemScriptableObject.id)
            {
                button.itemScriptableObject.itemNumber --;
                button.text.text = button.itemScriptableObject.itemNumber.ToString();
                if (button.itemScriptableObject.itemNumber <= 0)
                {
                    RemoveItem(_itemToReduce);
                }
                break;
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void ReduceItem(GameObject _itemToReduce,int number)
    {
        UIItemButton newItem = _itemToReduce.GetComponent<UIItemButton>();

        // 获取子对象上的多个特定类型组件
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == newItem.itemScriptableObject.id)
            {
                button.itemScriptableObject.itemNumber-= number;
                button.text.text = button.itemScriptableObject.itemNumber.ToString();
                if(button.itemScriptableObject.itemNumber <=0)
                {
                    RemoveItem(_itemToReduce);
                }

                break;
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void ReduceItem(int itemID, int number)
    {
        // 获取子对象上的多个特定类型组件
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == itemID)
            {
                button.itemScriptableObject.itemNumber -= number;
                button.text.text = button.itemScriptableObject.itemNumber.ToString();
                if (button.itemScriptableObject.itemNumber <= 0)
                {
                    RemoveItem(itemID);
                }

                break;
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    //删除物体 背包清除
    public void RemoveItem(GameObject _itemToRemove)
    {
        UIItemButton item = _itemToRemove.GetComponent<UIItemButton>();
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {
            var objectID=button.itemScriptableObject.id;

            if (button.itemScriptableObject.id == item.itemScriptableObject.id)
            {
                button.itemScriptableObject.itemNumber = 1;

                字典背包列表移除
                RemoveValue(button.itemScriptableObject.id);
            
                Destroy(button.gameObject);
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void RemoveItem(int itemID)
    {
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        foreach (UIItemButton button in UIItemButtons)
        {

            if (button.itemScriptableObject.id == itemID)
            {
                button.itemScriptableObject.itemNumber = 1;

                字典背包列表移除
                RemoveValue(button.itemScriptableObject.id);

                Destroy(button.gameObject);
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }

    public int ReturnItemNumebr(int itemID)
    {
        UIItemButton[] UIItemButtons = instance.transform.GetComponentsInChildren<UIItemButton>();
        int number = 0;
        foreach (UIItemButton button in UIItemButtons)
        {
            if (button.itemScriptableObject.id == itemID)
            {
                number=button.itemScriptableObject.itemNumber;
            }
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
        return number;
    }

    #region 字典处理
    public void AddData(string key, int value)
    {
        if (!dataDict.ContainsKey(key))
        {
            dataDict.Add(key, value);
        }
        else
        {
            Debug.LogWarning("Key already exists in the dictionary!");
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public int GetData(string key)
    {
        if (dataDict.ContainsKey(key))
        {
            //保存数据
            SaveLoadManager.instance.SaveGameData();
            ItemManager.instance.ItemDictionaryShow();
            return dataDict[key];
        }
        else
        {
            Debug.LogWarning("Key does not exist in the dictionary!");
            return 0;
        }

    }  
    public void UpdateData(string key, int newValue)
    {
        if (dataDict.ContainsKey(key))
        {
            dataDict[key] = newValue;
        }
        else
        {
            Debug.LogWarning("Key does not exist in the dictionary!");
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    public void UpdateValueData(string newName,int objectID)
    {
         List<string> keysToRemove = new List<string>();

            foreach (var kvp in dataDict)
            {
                var key = kvp.Key; // 键
                var value = kvp.Value; // 值

                if (value == objectID)
                {
                    keysToRemove.Add(kvp.Key);                  
                    break;
                }
            }
            foreach (var key in keysToRemove)
            {
                dataDict.Remove(key);
            }
            AddData(newName, objectID);
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    //根据值来删除 数据  必须用个列表来存储,不然会出问题
    public void RemoveValue(int objectID)
    {
        List<string> keysToRemove = new List<string>();

        foreach (var kvp in dataDict)
        {
            if (kvp.Value == objectID)
            {
                keysToRemove.Add(kvp.Key);
            }
        }

        foreach (var key in keysToRemove)
        {
            RemoveData(key);
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    //根据键删除数据
    public void RemoveData(string key)
    {
        if (dataDict.ContainsKey(key))
        {
            dataDict.Remove(key);
        }
        else
        {
            Debug.LogWarning("Key does not exist in the dictionary!");
        }
        //保存数据
        SaveLoadManager.instance.SaveGameData();
        ItemManager.instance.ItemDictionaryShow();
    }
    #endregion

    //private void Update()
    //{

    //    //if (Input.GetKeyDown(KeyCode.S))
    //    //{
    //    //    SaveLoadManager.instance.SaveGameData();
    //    //    ItemManager.instance.ItemDictionaryShow();
    //    //}
    //    //if (Input.GetKeyDown(KeyCode.P))
    //    //{
    //    //    SaveLoadManager.instance.LoadGameData();
    //    //    LoadInvontoryData();
    //    //}

    //}

    //创建数据
    public GameData GeneraterGameData()
    {
        GameData data = new GameData();

        data.dataDict = this.dataDict;
        return data;
    }
    //加载数据
    public void RestoreGameData(GameData saveData)
    {
        this.dataDict = saveData.dataDict;
    }
}

物体显示面板,用于物体的处理

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

public class ItemShowPanel : Singleton<ItemShowPanel>
{
    [SerializeField] Image image;
    [SerializeField] Text numberText;
    [SerializeField] Text descriptionText;
    [SerializeField] Sprite defaultSprite;
    [SerializeField] Slider slider;
    [SerializeField] Text  sliderText;

    [Header("Button")]
    [SerializeField] Button testUseItemButton;
    [SerializeField] Button testDelItemButton;

    private int itemID;

    private void Start()
    {
        slider.onValueChanged.AddListener(OnSliderValueChanged);
    }

    private void OnEnable()
    {
        ButtonPressBehavior.buttonFunctionTable.Add(testUseItemButton.gameObject.name, OnUseItemButtonClik);
        ButtonPressBehavior.buttonFunctionTable.Add(testDelItemButton.gameObject.name, OnDelItemButtonClik);
    }
    private void OnDisable()
    {
        ButtonPressBehavior.buttonFunctionTable.Clear();
    }
    public void ItemInformationShow(Item  item)
    {
        image.sprite = item.itemImage;
        numberText.text=item.itemNumber.ToString();
        descriptionText.text = item.desprict;
        itemID = item.id;
        slider.maxValue = item.itemNumber;
    }
    public void DefaultSituation()
    {
        image.sprite = defaultSprite;
        descriptionText.text = "";
        numberText.text = "";
        sliderText.text = "";
        slider.value = 0;
    }
    public void OnUseItemButtonClik()
    {
        int intValue = Mathf.RoundToInt(slider.value);
        for (int i = 0; i < intValue; i++)
        {
            EventManager.instance.TriggerEvent(itemID);
            Debug.Log("EventManager.instance.TriggerEvent(itemID);次数" + intValue);
        }
        OnDelItemButtonClik();
    }
    //删除按钮
    public void OnDelItemButtonClik()
    {
        int intValue = Mathf.RoundToInt(slider.value);
        if (InvontoryManager.instance.ReturnItemNumebr(itemID) == intValue)
        {
            InvontoryManager.instance.ReduceItem(itemID, intValue);
            DefaultSituation();

        }
        else
        {
            InvontoryManager.instance.ReduceItem(itemID, intValue);
            numberText.text = InvontoryManager.instance.ReturnItemNumebr(itemID).ToString();
        }

        slider.maxValue = InvontoryManager.instance.ReturnItemNumebr(itemID);

    }

    void OnSliderValueChanged(float value)
    {
        sliderText.text = Mathf.RoundToInt(value).ToString();
    }
}

事件管理类,用物品id来注册事件

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

public class EventManager : Singleton<EventManager>
{
    private Dictionary<int, Action> eventDictionary;

    public EventManager()
    {
        eventDictionary = new Dictionary<int, Action>();
    }
    //出现重复委托
    //public void AddEvent(int objectId, Action eventAction)
    //{
    //    if (eventDictionary.ContainsKey(objectId))
    //    {
    //        eventDictionary[objectId] += eventAction;
    //    }
    //    else
    //    {
    //        eventDictionary[objectId] = eventAction;
    //    }
    //}

    //确保只有一次委托
    public void AddEvent(int objectId, Action eventAction)
    {
        if (eventDictionary.ContainsKey(objectId))
        {
            RemoveEvent(objectId);
        }

        eventDictionary[objectId] = eventAction;
    }



    public void RemoveEvent(int objectId, Action eventAction)
    {
        if (eventDictionary.ContainsKey(objectId))
        {
            eventDictionary[objectId] -= eventAction;

            if (eventDictionary[objectId] == null)
            {
                eventDictionary.Remove(objectId);
            }
        }
    }
    public void RemoveEvent(int objectId)
    {
        if (eventDictionary.ContainsKey(objectId))
        {
            eventDictionary.Remove(objectId);
        }
    }

    public void TriggerEvent(int objectId)
    {
        if (eventDictionary.ContainsKey(objectId))
        {
            eventDictionary[objectId]?.Invoke();
        }
    }

}

在世界坐标上的物体

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class LootitemAddMissile : LootItem
{
    [SerializeField] GameObject UIitemPrefab;

    UIItemButton uiItem;

    protected override void Awake()
    {
        base.Awake();
        uiItem = UIitemPrefab.GetComponent<UIItemButton>();
        EventManager.instance.AddEvent(uiItem.itemScriptableObject.id, AddMissileNumber);
        Debug.Log("导弹注册事件");
    }
    protected override void PickUp()
    {
        base.PickUp();
        uiItem.AddInInvory();
    }
  public void AddMissileNumber()
    {
       //自己要触发的功能


        
    }
}

物体基础类 

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

public class LootItem : MonoBehaviour
{
    protected Player player;
    [SerializeField] float minSpeed;
    [SerializeField] float maxSpeed;
    [SerializeField] protected AudioData pickUpSFX;

    protected Text LootText;
    Animator animator;

    int pickUpStateID = Animator.StringToHash("PickUp");
    protected virtual void Awake()
    {
        animator = GetComponent<Animator>();
        player = FindObjectOfType<Player>();//找到挂有Player的物体的脚本
        LootText = GetComponentInChildren<Text>(true);//true 获得禁用时的组件
    }
    private void OnEnable()
    {
        StartCoroutine(nameof(MoveCorotine));
    }
    //跟随玩家移动
    IEnumerator MoveCorotine()
    {
        float speed = Random.Range(minSpeed, maxSpeed);
        Vector3 direction = Vector3.left;//向左   
        while (isActiveAndEnabled)
        {
            if (player.isActiveAndEnabled)
            {
                direction = (player.transform.position - transform.position).normalized;

            }
            transform.Translate(direction * speed * Time.deltaTime);
            yield return null;
        }

    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        PickUp();
    }
    protected virtual void PickUp()
    {
        StopAllCoroutines();
        animator.Play(pickUpStateID);
        AudioManager.instance.PlayRandomSFX(pickUpSFX);

    }

}

加载数据放在背包打开的时候就行

        //加载背包数据
        SaveLoadManager.instance.LoadGameData();
        InvontoryManager.instance. LoadInvontoryData();

创建物体信息

 编写物体信息,id为唯一值创建ui物体信息预制体

创建场景中物体,挂载ui物体信息 预制体

 背包ui界面

 背包面板用Scroll View,内容填充用Grid layout Group

显示界面

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值