保存和加载库存 [英] Save and load inventory

查看:67
本文介绍了保存和加载库存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了清单,并且一切正常.现在,我应该实现库存的保存和加载(在文件上).但是,我发现自己无法继续进行.我当时正在考虑创建一个库存数据脚本以获取可序列化的数据,然后将其保存.我没有使用可编写脚本的对象.您对我有什么建议吗?下面是库存代码.

I've already created the inventory and everything works fine. Now I should implement the saving and loading of the inventory (on file). However, I find myself stuck on how to proceed. I was thinking of creating an Inventory Data script to get serializable data and then save it. I'm not using scriptable object. Would you have any advice for me? Below is the inventory code.

 public class Inventory2 : MonoBehaviour
 {
     public bool inventoryEnabled;
     public GameObject inventory, slotHolder;
     private Transform[] slot;
     public int level;

     void Start()
     {
         level = SceneManager.GetActiveScene().buildIndex;
         GetAllSlots();        
     }   

     void Update()
     {
         if (Input.GetAxis("Inventory") != 0)
         {
             inventoryEnabled = !inventoryEnabled;
         }

         if(inventoryEnabled)
         {
             inventory.SetActive(true);
         }
         else
         {
             inventory.SetActive(false);
         }
     }

     public void OnTriggerEnter(Collider other)
     {
         if (other.tag == "Clues")
         {            
             AddClue(other.GetComponent<Clue2>());            
         }
     }
     public void AddClue(Clue2 clue)
     {
         Text description = clue.GetComponent<Text>();

         for (int i = 0; i < 2; i++)
         {
             if(slot[i].GetComponent<Slot2>().empty == true && clue.pickedUp == false)
             {
                 slot[i].GetComponent<Slot2>().clue = clue;
                 slot[i].GetComponent<Slot2>().descriptionFinal = description;
                 slot[i].GetComponent<Slot2>().empty = false;
                 clue.GetComponent<Clue2>().pickedUp = true;
             }
         }
     }

     public void GetAllSlots()
     {
         slot = new Transform[Clue2.objects];

         for(int i = 0; i < Clue2.objects; i++)
         {
             slot[i] = slotHolder.transform.GetChild(i);
             slot[i].GetComponent<Slot2>().empty = true;
         }
     }
 }

 public class Slot2 : MonoBehaviour
 {
     public Clue2 clue;
     public bool empty;
     public Text descriptionFirst, descriptionFinal;

     void Awake()
     {

     }

     void Update()
     {
         if (clue)
         {
             this.GetComponentInChildren<Text>().text = descriptionFinal.text;
         }
         else
         {
             this.GetComponentInChildren<Text>().text = descriptionFirst.text;
             empty = true;
         }
     }
 }

 public class Clue2 : MonoBehaviour
 {
     public static int objects = 0;
     public static int objectsCollected = 0;
     public Text description;
     public bool pickedUp;

     public GameObject cluePopUpPanel, canvasCluesPanel;
     public Canvas canvasHUD;
     public static bool activeClue = false;

     void Awake()
     {
         objects++;
     }

     void Update()
     {
         if (canvasCluesPanel.gameObject.activeSelf == true && Input.GetAxis("PickUp") != 0)
         {
             activeClue = true;
             cluePopUpPanel.gameObject.GetComponent<UnityEngine.UI.Text>().text = description.text;
         }
     }

     private void OnTriggerEnter(Collider other)
     {
         if (other.tag == "Player")
         {
             if (canvasCluesPanel.gameObject.activeSelf == false)
             {
                 canvasCluesPanel.gameObject.SetActive(true);                
             }
         }
     }

     private void OnTriggerStay(Collider other)
     {
         if (other.tag == "Player" && activeClue == true)
         {
             cluePopUpPanel.gameObject.SetActive(true);
             cluePopUpPanel.GetComponentInChildren<Text>().text = this.GetComponent<Text>().text;
             canvasCluesPanel.gameObject.SetActive(false);
         }

         if (other.tag == "Player" && activeClue == false)
         {
             cluePopUpPanel.gameObject.SetActive(false);
             canvasCluesPanel.gameObject.SetActive(true);
         }        
     }

     private void OnTriggerExit(Collider other)
     {
         if (other.tag == "Player" && activeClue == true)
         {
             cluePopUpPanel.gameObject.SetActive(false);
             canvasCluesPanel.gameObject.SetActive(false);
             activeClue = false;
             if(objectsCollected < objects)
             {
                 objectsCollected++;
             }
         }
         else
         {
             cluePopUpPanel.gameObject.SetActive(false);
             canvasCluesPanel.gameObject.SetActive(false);
             activeClue = false;
         }

         canvasHUD.gameObject.SetActive(true);
     }
 }

推荐答案

可以找到一个很好的教程此处.

A good tutorial can be found here.

作为一个好习惯,将要保存的数据存储在一个类中.像这样创建SlotData.因此,尝试像这样转换它们.此类必须具有属性 System.Serializable .

As a good practice Store the data you want to save in a class. Create the SlotData, like so. So try converting them like so. This class must have the attribute System.Serializable.

一个例子就是这个

[System.Serializable]
public class SlotData
{
    public bool containsItem = false;
    public string Description;
    //other possible elements
    public int amount; 
}

InventoryData只是SlotData的数组.

The InventoryData will be just an array of SlotData.

[System.Serializable]
public class InventoryData
{
    public SlotData[] inventorySlots;
}

2-在保存之前设置数据

您可以在代码中的某个地方更新清单.您必须设置此数据,可能来自单行为.基本上,您可以在课堂上添加所需的所有信息.

2 - Setup the data before saving

Somewhere in your code you update the Inventory. You must setup this data, probably from the monobehaviour. Basically you add all the info you want in your class.

public void PrepareToSave()
{
    //setup the inventory
    var yourInventory = new InventoryData();
    //fill all the slots, you must also calculate their amount
    yourInventory.inventorySlots = new SlotData[CalculateYourAmount];
    //fill all the slots here
    for (int   i= 0; i  < CalculateYourAmount;  i++)
    {   
        //fill all the slots
        yourInventory.inventorySlots[i] = CreateTheSlot();
    }

    //this go to the next step
    SaveYourInventory(yourInventory);
}

3-保存库存

根据您的要求,您可以使用 BinaryFormatter FileStream .

private void SaveYourInventory(InventoryData yourInventory)
{
    var             savePath = Application.persistentDataPath + "/inventory.dat";
    BinaryFormatter bf       = new BinaryFormatter();
    FileStream      file     = File.Create(savePath);
    bf.Serialize(file, yourInventory);
    file.Close();
}

4-加载库存

然后,您可以像这样加载广告资源.

4 - Load the inventory

Then you can just load the inventory like this.

public void LoadYourInventory()
{
    var savePath = Application.persistentDataPath + "/inventory.dat";
    if (File.Exists(savePath))
    {
        BinaryFormatter bf   = new BinaryFormatter();
        FileStream      file = File.Open(savePath, FileMode.Open);
        InventoryData yourInventory = (InventoryData) bf.Deserialize(file);
        file.Close();

        //do what you want with the inventory
        ...
    }
}

您还可以找到Save Manager系统

You can also find a Save Manager system here.

如果您想更高级,可以使用此优化格式化程序(或保存如果您回到保存/加载业务,则可以在将来使用.

And if you want to go more advanced you can use this optimized formatter (or save it for the future if you get back to the save/load business).

这篇关于保存和加载库存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆