当前位置:网站首页>Unity advanced backpack system

Unity advanced backpack system

2022-06-11 04:22:00 Sea moon

Preface

Before the implementation of a primary backpack system , It doesn't classify items .

This time, the classified storage and display of items are added .

Asset Structure

In order to classify and manage items , stay ScriptableObject Use lists to store three types of items , Weapons 、 Food and materials . The element in this list is a special class , It contains the names of such objects , And a list of such items stored . In the item configuration table , What's stored is Item Class object , In the backpack item data sheet , What's stored is InventoryItem object , The difference between them is ,InventoryItem The object of class has a number of attributes .

Item number

101~199 It's weapons

201~299 It's food

301~399 It's material

Determine the type of item , With articles index / 100 that will do .

Code

Item configuration table

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

[CreateAssetMenu]
public class ItemsConfigurationAdvanced : ScriptableObject
{
    [Header(" Item classification list ")]
    public List<ItemList> lists;
}

[System.Serializable]
public class ItemList
{
    public string listName;
    public List<Item> items;
}

Backpack item configuration table

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

[CreateAssetMenu]
public class InventoryConfigurationAdvanced : ScriptableObject
{
    [Header(" A categorized list of items held by players ")]
    public List<InventoryItemList> lists;
}

[System.Serializable]
public class InventoryItemList
{
    public string listName;
    public List<InventoryItem> items;

    public InventoryItemList(string name)
    {
        listName = name;
        items = new List<InventoryItem>();
    }
}

Backpack items

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

[Serializable]
public class InventoryItem : Item
{
    public int num;

    public InventoryItem(Item item, int num) : base(item)
    {
        this.num = num;
    }
}

notes : The constructor of the backpack item class calls the copy constructor of the base class

Items

using System;
using UnityEngine;
using UnityEngine.UI;

[Serializable]
public class Item
{
    public int id;
    public string name;
    public string description;
    public Texture2D icon;
    public GameObject model;

    public Item(Item item)
    {
        id = item.id;
        name = item.name;
        description = item.description;
        icon = item.icon;
        model = item.model;
    }
}

Item data manager

using System.Collections.Generic;
using UnityEngine;

/// <summary>
///  Provide item configuration table and backpack items 
/// </summary>
public class BackpackManagerAdvanced : Singleton<BackpackManagerAdvanced>
{
    public ItemsConfigurationAdvanced itemsConfiguration = Resources.Load<ItemsConfigurationAdvanced>("Configurations/Items Configuration Advanced");
    public InventoryConfigurationAdvanced inventoryConfiguration = Resources.Load<InventoryConfigurationAdvanced>("Configurations/Inventory Configuration Advanced");

    /// <summary>
    ///  Get the item with the specified number from the backpack 
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    InventoryItem Contains(int index)
    {
        if (inventoryConfiguration.lists == null)
        {
            inventoryConfiguration.lists = new List<InventoryItemList>();
        }

        if(inventoryConfiguration.lists[index / 100 - 1] == null)
        {
            inventoryConfiguration.lists[index / 100 - 1] = new InventoryItemList(itemsConfiguration.lists[index / 100 - 1].listName);
        }

        foreach (var i in inventoryConfiguration.lists[index / 100 - 1].items)
        {
            if (i.id == index)
                return i;
        }
        return null;
    }

    /// <summary>
    ///  Save the specified item number to the backpack 
    /// </summary>
    /// <param name="index"></param>
    public void SaveItemToInventory(int index)
    {
        InventoryItem temp = Contains(index);

        if (temp != null)
            temp.num++;
        else
            inventoryConfiguration.lists[index / 100 - 1].items.Add(new InventoryItem(GetItem(index), 1));
    }

    /// <summary>
    ///  Get the item with the specified number from the item configuration table 
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public Item GetItem(int index)
    {
        foreach (var i in itemsConfiguration.lists[index / 100 - 1].items)
        {
            if (i.id == index)
                return i;
        }
        return null;
    }
}

Backpack panel class

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

public class BackpackPanel : BasePanel
{
    static readonly string path = "Prefabs/UI/BackpackPanel";

    public BackpackPanel() : base(new PanelType(path)) { }

    /*----------- Configurable parameters -----------*/

    public int column = 5;                  // Number of columns 
    public float itemSize = 280;            // Item grid size 
    public float interval = 20;             // The gap between the grids 
    public float viewPortHeight = 1500;      // Height of window 

    // Record the last displayed maximum index , To remove the invisible grid 
    int lastMinDisplayIndex;
    int lastMaxDisplayIndex;
    // Slide the container of the list 
    public RectTransform content;
    // Stores the currently displayed grid and its number 
    Dictionary<int, GameObject> curDisplayGrids = new Dictionary<int, GameObject>();

    public Item selectedItem;// Currently selected item 
    public override void OnEnter()
    {
        panelBindingTool.GetOrAddComponentInChildren<Button>(" close ").onClick.AddListener(() =>
        {
            panelStack.Pop();
        }
        );

        panelBindingTool.GetOrAddComponentInChildren<Button>(" details ").onClick.AddListener(() =>
        {
            panelStack.Push(new ItemDetailPanel(selectedItem));
        }
        );

        panelBindingTool.GetOrAddComponentInChildren<Button>(" weapons ").onClick.AddListener(() =>
        {
            listIndex = 1;
            InitThisTypeOfBackpack();
        }
        );

        panelBindingTool.GetOrAddComponentInChildren<Button>(" food ").onClick.AddListener(() =>
        {
            listIndex = 2;
            InitThisTypeOfBackpack();
        }
        );

        panelBindingTool.GetOrAddComponentInChildren<Button>(" material ").onClick.AddListener(() =>
        {
            listIndex = 3;
            InitThisTypeOfBackpack();
        }
        );

        InitThisTypeOfBackpack();

        OrbitCamera.Instance.work = false;
    }

    int listIndex = 1;// Currently displayed item categories  100~199  weapons  200~299  food  300~399  material 
    void InitThisTypeOfBackpack()
    {
        DestroyCurDisplayGrids();

        content = panelBindingTool.GetOrAddComponentInChildren<RectTransform>("Content");       // Get the components of the container 
        content.sizeDelta = new Vector2(0, Mathf.CeilToInt(BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items.Count / column) * (itemSize + interval));      // Calculate the height of the container according to the number of items ( Rounding up )

        GameManager.Instance.listIndex = listIndex;
        GameManager.Instance.MethodField = DisplayBackpackGridAdvanced;      // take DisplayBagItem Function Injection GameManager Of Update in , Real time update 

        // Initial display of the first item 
        DisplayItemBeief(BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items[0]);
        selectedItem = BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items[0];
    }

    void DestroyCurDisplayGrids()
    {
        for(int i = 0;i<curDisplayGrids.Count;i++)
        {
            GameObject.Destroy(curDisplayGrids[i]);
        }
        curDisplayGrids.Clear();
        lastMinDisplayIndex = 0;
        lastMaxDisplayIndex = 0;
    }
    // Destroy the grid being displayed and initialize the relevant parameters 

    public override void OnExit()
    {
        GameManager.Instance.NonMonoUpdateMethod = null;      // Cancel Injection 
        GameManager.Instance.MethodField = null;      // Cancel Injection 
        panelManager.DestroyPanel(this.panelType);

        OrbitCamera.Instance.work = true;
    }

    public override void OnPause()
    {
        panelBindingTool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
    }

    public override void OnResume()
    {
        panelBindingTool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
    }

    public void DisplayItemBeief(Item item)
    {
        panelBindingTool.GetOrAddComponentInChildren<Text>("Item Name").text = item.name;
        panelBindingTool.GetOrAddComponentInChildren<Text>("Item Description").text = item.description;
        panelBindingTool.GetOrAddComponentInChildren<Image>("Item Image").sprite = Sprite.Create(item.icon, new Rect(0, 0, item.icon.width, item.icon.height), new Vector2(0.5f, 0.5f));
    }

    public void DisplayBackpackGridAdvanced(int listIndex)
    {
        /*----------- Calculate the visible range -----------*/

        int minDisplayIndex = (int)(content.anchoredPosition.y / (itemSize + interval)) * column;      // Rounding down : 0,0 190,3 950,15
        int maxDisplayIndex = (int)((content.anchoredPosition.y + viewPortHeight) / (itemSize + interval)) * column + column; //  The items in the following column , Showing a little also needs to show , So you need to display one more line 

        /*----------- Those that cross the border do not show -----------*/

        if (minDisplayIndex < 0)
            minDisplayIndex = 0;

        if (maxDisplayIndex > BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items.Count)
            maxDisplayIndex = BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items.Count;

        /*--------- Displays the grid within the visible range ------*/

        for (int i = minDisplayIndex; i < maxDisplayIndex; i++)
        {
            if (curDisplayGrids.ContainsKey(i))                 // The displayed grid , Don't create it again 
                continue;
            else
            {
                GameObject obj = PoolManager.Instance.getObject("BackpackGrid", "Prefabs/UI/BackpackGrid");       // Cells not shown , Get... From the pool 
                obj.transform.SetParent(content);
                obj.transform.localPosition = new Vector3(i % column * (itemSize + interval), i / column * (itemSize + interval) * (-1), 0);          // Put the grid in the right place 
                obj.GetComponent<BackpackGrid>().InitInfo(BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items[i]);                 // Initialize grid information 
                obj.GetComponent<BackpackGrid>().OnClick(this, BackpackManagerAdvanced.Instance.inventoryConfiguration.lists[listIndex-1].items[i]);
                curDisplayGrids[i] = obj;                                                               // Enter the currently displayed grid into the dictionary according to the number 
            }
        }

        /*---------- Remove the invisible grid ---------*/

        for (int i = lastMaxDisplayIndex; i > maxDisplayIndex; i--)
        {
            if (curDisplayGrids.ContainsKey(i))
            {
                PoolManager.Instance.recycleObject("BackpackGrid", curDisplayGrids[i]);
                curDisplayGrids.Remove(i);
            }
        }

        for (int i = lastMinDisplayIndex; i < minDisplayIndex; i++)
        {
            if (curDisplayGrids.ContainsKey(i))
            {
                PoolManager.Instance.recycleObject("BackpackGrid", curDisplayGrids[i]);
                curDisplayGrids.Remove(i);
            }
        }

        lastMaxDisplayIndex = maxDisplayIndex;
        lastMinDisplayIndex = minDisplayIndex;
    }
}

effect

原网站

版权声明
本文为[Sea moon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110411057857.html