【问题标题】:Creating an object of my custom class from a string从字符串创建我的自定义类的对象
【发布时间】:2020-03-11 15:26:08
【问题描述】:

我正在使用 Unity 引擎和 C# 开发一款游戏。我是初学者。

我创建了一个名为“Item”的自定义类,它派生自可编写脚本的对象,它是我游戏中项目的基础。 Item 类型的对象保存在另一个类“Inventory”中,其中包含添加和删除函数,用于从清单中添加和删除 Item 类型的对象。我目前正在研究游戏的保存和加载功能,由于我无法通过将 Item 类型的对象序列化为二进制并将它们放在持久数据路径中来保存它们,因此我创建了保存 NAME 的代码该项目。 我的问题是:如何仅从其名称的字符串创建和添加对象 Item(我的自定义类)。(属性 Item.name 与 Unity 中对象的实际名称共享)。我在我的代码中添加了注释,希望能让我更容易理解我想要做什么。

这是类项目:

public class Item : ScriptableObject
{

    new public string name = "New Item";
    public Sprite icon = null;
    public bool isDefaultItem = false;
    public virtual void Use()
    {
        Debug.Log("USING: " + name);
    }

    public void RemoveFromInventory()
    {
        Inventory.instance.Remove(this);
    }
}

这是类清单,其中包含添加和删除函数,包含一个项目:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Text;
    public class Inventory : MonoBehaviour

{
    public static Inventory instance;
    private bool alreadyExists = false;
    public static int space = 20;
    Vector3 playerPosition;
    private void Awake()
    {
        if (instance != null)
        {
        Debug.LogWarning("More than 1 inventory");
        return;
    }

    instance = this;
}
public List<Item> items = new List<Item>();
public static List<string> index = new List<string>();
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;

//These are the functions to add and remove an item to the inventory, Taking in an item, of type Item, from my custom class Item.

public bool Add (Item item)
{
    if (!item.isDefaultItem)
    {

        if (items.Count >= space)
        {
                Debug.Log("NOT ENOUGH SPACE IN INV");
                return false;
        }
        items.Add(item);
        index.Add(item.name);


    }

        if (onItemChangedCallback != null)
            onItemChangedCallback.Invoke();
    return true;
}

public void Remove(Item item)
{
    items.Remove(item);
    index.Remove(item.name);

    if (onItemChangedCallback != null)
        onItemChangedCallback.Invoke();
}


}

这是实际包含问题所在代码的类;我需要以某种方式实例化或创建一个项目并将其从项目名称添加到库存中。请参阅 LoadInv() 了解我需要将它放在哪里。

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

public class InventoryAttached : MonoBehaviour
{
    public string[] invArray;
    string all;
    //This is the Saving Seperator
    char[] delimiter = { '.' };
    public void SaveInv()
    {
        InvSaveSystem.SaveInv(this);
    }

    public void LoadInv()
    {
        //Code that gets data for the items that need to be added to the inventory
        InvData data = InvSaveSystem.LoadInv(); //This is the Data from my binary formatter
        all = ConvertStringArrayToString(data.invSlot); 
        invArray = all.Split(delimiter);

        //For loop that iterates through the inventory array containing the names of the items stored in the inventory
        for (int i = 0; i < invArray.Length; i++)
        {
            Debug.Log(invArray[i]);
            //Here, I would like to use my Add function to add the items to the inventory
            // It would look something like this: Inventory.instance.Add(invArray[i[]);
        }

    }


    static string ConvertStringArrayToString(string[] array) //Converter Code used to convert to and from string arrays
    {
        // Concatenate all the elements into a StringBuilder.
        StringBuilder builder = new StringBuilder();
        foreach (string value in array)
        {
            builder.Append(value);
            builder.Append('.');
        }
        return builder.ToString();
    }

    static string ConvertStringArrayToStringJoin(string[] array)
    {
        // Use string Join to concatenate the string elements.
        string result = string.Join(".", array);
        return result;
    }
}

仅供参考,这里是InvData类,里面包含了我的保存系统格式化成二进制保存到HD的字符串数组。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using System.Text.RegularExpressions;
[System.Serializable]
public class InvData

{
    public string[] invSlot;


    public InvData(InventoryAttached inv)
    {
        invSlot = new string[Inventory.index.Count];

        for (int i = 0; i < Inventory.index.Count; i++)
        {
            invSlot[i] = Inventory.index[i];
        }
    }



}

【问题讨论】:

  • since I can't save objects of type Item by serializing them to binary and putting them in a persistent data path 为什么不呢?
  • @TheBatman 因为我的自定义类 Item 派生自 Unity 中的 Scriptable Objects,它不是 System.Serializable。
  • 忽略此设计的体系结构问题并仅解决所提出的问题,我将创建一个具有Create(string itemName) 方法的ItemFactory 类,该方法枚举字符串到类型映射的集合。最后使用 System.Activator 创建实例。
  • @ChrisPickford 我完全是自学成才,所以我不确定这种事情的标准架构约定是什么,抱歉。此外,作为初学者,我不完全确定如何执行您的解决方案所建议的操作。您能否以答案格式解释它,或者将我链接到提供示例以及如何操作的资源?谢谢。
  • @LeeJordan 不要担心每个人都从某个地方开始。查找抽象工厂模式并从那里开始。

标签: c# unity3d binary-serialization


【解决方案1】:

.AddComponent(Type.GetType("type_name"));

【讨论】:

  • 我会在几个小时后检查一下,如有任何问题,请与您联系。
猜你喜欢
  • 2018-09-07
  • 1970-01-01
  • 2011-06-23
  • 2013-08-18
  • 1970-01-01
  • 2018-05-19
  • 2021-02-14
  • 1970-01-01
  • 2015-09-08
相关资源
最近更新 更多