Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 库存项目实施_C#_Unity3d - Fatal编程技术网

C# 库存项目实施

C# 库存项目实施,c#,unity3d,C#,Unity3d,目前,我有一个清单实现,它是这样工作的 -有一个名为项目的基类,这是库存数组包含的,然后有从项目继承的类武器和消耗品,然后是从武器继承的类枪。但是,我有一个问题,我希望物品具有可更改的属性,也就是说,我希望枪类能够容纳枪中的弹药量,但是如果它被更改,那么考虑到它使用的是该类的相同实例,那么它将更改库存中所有特定类型枪的弹药。我听说过iClonable,但它显然已贬值,不应使用 我的项目脚本: using UnityEngine; using System.Collections.Generic;

目前,我有一个清单实现,它是这样工作的 -有一个名为
项目
的基类,这是库存数组包含的,然后有从
项目
继承的类
武器
消耗品
,然后是从
武器
继承的类
。但是,我有一个问题,我希望物品具有可更改的属性,也就是说,我希望
类能够容纳枪中的弹药量,但是如果它被更改,那么考虑到它使用的是该类的相同实例,那么它将更改库存中所有特定类型枪的弹药。我听说过iClonable,但它显然已贬值,不应使用

我的项目脚本:

using UnityEngine;
using System.Collections.Generic;

public class Items : MonoBehaviour
{
    static Dictionary<int, Item> items = new Dictionary<int, Item>();

    private static bool initialized;

    [SerializeField]
    Texture2D[] itemIcons;

    private void Start()
    {
        Gun desertEagle = new Gun();
        desertEagle.damage = 40;
        desertEagle.range = 20;
        desertEagle.maxAmmunition = 7;
        desertEagle.firemode = FireMode.Semi;
        desertEagle.firerate = 1;

        desertEagle.name = "Desert Eagle";
        desertEagle.description = "Desert Eagle (.50 Cal) is a semi-automatic pistol with an ammo capacity of 7 rounds";
        desertEagle.equippable = true;
        desertEagle.icon = itemIcons[1];

        Consumable donut = new Consumable();
        donut.food = 30;

        donut.name = "Donut";
        donut.description = "A ring full of legendary awesomeness";
        donut.equippable = true;
        donut.icon = itemIcons[2];

        Consumable coffee = new Consumable();
        coffee.water = 30;
        coffee.stamina = 50;

        coffee.name = "Coffee";
        coffee.description = "A delicious beverage to help you get up in the morning. Goes well with donuts.";
        coffee.equippable = true;
        coffee.icon = itemIcons[3];

        RegisterItem(1, desertEagle);
        RegisterItem(2, donut);
        RegisterItem(3, coffee);

        initialized = true;
    }

    public static void RegisterItem(int id, Item item)
    {
        items.Add(id, item);
    }

    public static void UnregisterItem(int id)
    {
        items.Remove(id);
    }

    public static Item GetItem(int id)
    {
        return items[id];
    }
}

public class ItemStack
{

    Item item;
    int amount;
    int max = 10;

    public void Add(int amount)
    {
        if (item.stackable && this.amount + amount <= max) this.amount += amount;
        else if (item.stackable) this.amount = max;
    }

    public void Remove(int amount)
    {
        if (item.stackable) this.amount -= amount;
    }
}

public class Item
{
    public string name = "Item";
    public string description = "Your everyday standard item.";
    public bool equippable = false;
    public bool stackable = true;
    public Mesh model;
    public Texture2D icon;
}

public class Weapon : Item
{
    public float damage = 5;
    public float range = 1;
}

public class Gun : Weapon
{
    public int ammunition = 1;
    public int maxAmmunition = 1;
    public FireMode firemode = FireMode.Semi;
    public int firerate = 1;
    public new float range = 10;
}

public enum FireMode
{
    Semi,
    Automatic,
    Burst
}

public class Consumable : Item
{
    public float food;
    public float water;
    public float health;
    public float stamina;
}using UnityEngine;
using System.Collections.Generic;

Json和类型方法

因此,正如我之前所评论的,可以使用json和Type创建字典并克隆注册的对象。我已经更改了你的代码来实现这一点。见下文:

using UnityEngine;
using System.Collections.Generic;
using System;//Included to use Type and [Serializable]

public class Items : MonoBehaviour
{
    public struct SerializedObject //struct to hold the type of the object and the json string
    {
        public Type type;
        public string json;
    }

    static Dictionary<int, SerializedObject> items = new Dictionary<int, SerializedObject>();//dictionary must hold both type and json string to be used with JsonUtility

    private static bool initialized;

    [SerializeField]
    Texture2D[] itemIcons;

    private void Start()
    {
        Gun desertEagle = new Gun();
        desertEagle.damage = 40;
        desertEagle.range = 20;
        desertEagle.maxAmmunition = 7;
        desertEagle.firemode = FireMode.Semi;
        desertEagle.firerate = 1;

        desertEagle.name = "Desert Eagle";
        desertEagle.description = "Desert Eagle (.50 Cal) is a semi-automatic pistol with an ammo capacity of 7 rounds";
        desertEagle.equippable = true;
        desertEagle.icon = itemIcons[1];


        Consumable donut = new Consumable();
        donut.food = 30;

        donut.name = "Donut";
        donut.description = "A ring full of legendary awesomeness";
        donut.equippable = true;
        donut.icon = itemIcons[2];

        Consumable coffee = new Consumable();
        coffee.water = 30;
        coffee.stamina = 50;

        coffee.name = "Coffee";
        coffee.description = "A delicious beverage to help you get up in the morning. Goes well with donuts.";
        coffee.equippable = true;
        coffee.icon = itemIcons[3];

        //For each object store the Type and serialize the data using JsonUtility
        SerializedObject so_desertEagle;
        so_desertEagle.type = desertEagle.GetType();
        so_desertEagle.json = JsonUtility.ToJson(desertEagle);
        SerializedObject so_donut;
        so_donut.type = donut.GetType();
        so_donut.json = JsonUtility.ToJson(donut);
        SerializedObject so_coffee;
        so_coffee.type = coffee.GetType();
        so_coffee.json = JsonUtility.ToJson(coffee);
        RegisterItem(1, so_desertEagle);
        RegisterItem(2, so_donut);
        RegisterItem(3, so_coffee);

        /*//Made this for testing 
        Item gunCopy = GetItem(1);
        Gun desertEagle2 = (Gun) gunCopy;
        desertEagle2.ammunition--;

        Debug.Log(desertEagle.ammunition + " / " + desertEagle2.ammunition);
        //Debug result is "1 / 0"
        */
        initialized = true;
    }

    public static void RegisterItem(int id, SerializedObject item)
    {
        items.Add(id, item);
    }

    public static void UnregisterItem(int id)
    {
        items.Remove(id);
    }



    public static Item GetItem(int id)
    {
        return (Item) JsonUtility.FromJson(items[id].json, items[id].type); //Use JsonUtility to create a copy of the serialized object
    }
}

[Serializable]
public class ItemStack
{

    Item item;
    int amount;
    int max = 10;

    public void Add(int amount)
    {
        if (item.stackable && this.amount + amount <= max) this.amount += amount;
        else if (item.stackable) this.amount = max;
    }

    public void Remove(int amount)
    {
        if (item.stackable) this.amount -= amount;
    }
}

[Serializable]//JsonUtility only works with [Serializable] objects
public class Item
{
    public string name = "Item";
    public string description = "Your everyday standard item.";
    public bool equippable = false;
    public bool stackable = true;
    public Mesh model; //I would recommend storing the meshes in another dictionary and setting a reference here
    public Texture2D icon;
}

[Serializable]
public class Weapon : Item
{
    public float damage = 5;
    public float range = 1;
}

[Serializable]
public class Gun : Weapon
{
    public int ammunition = 1;
    public int maxAmmunition = 1;
    public FireMode firemode = FireMode.Semi;
    public int firerate = 1;
    public new float range = 10;
}

[Serializable]
public enum FireMode
{
    Semi,
    Automatic,
    Burst
}

[Serializable]
public class Consumable : Item
{
    public float food;
    public float water;
    public float health;
    public float stamina;
}
如果您需要在运行时注册这些项,我建议将它们序列化为JSON并存储JSON和类型。以下链接可能对此有所帮助:


对不起,我不明白你想要什么。正如一个旁注,你可以考虑让你的<代码>消耗品一个接口(比如<代码> IcSimaby),这个名字暗示了它。然后你可以用
Coffee
Donut
之类的课程来实现它。不知道我是否理解你的问题。你想共享弹药吗?如果你有2只沙漠鹰,它们会分享你的弹药。就这样?如果是这样的话,你只需要将弹药用作消耗品。基本上,如果一件物品的价值发生了变化,因为该物品的同一实例被用作物品列表中存储的物品,那么库存中所有该物品的价值都发生了变化。我想我找到了问题所在,并找到了两种解决方法。已经发布了答案。如果不是你想要的,请告诉我。如果是,请接受答案。ComputerFido请让我知道我的答案是否解决了您的问题,如果解决了,请接受。我会看看json的东西,但我不认为我会使用开关,因为这可能会变得非常混乱。如果您感兴趣,我已经在答案中添加了JsonUtility解决方案。它已经在这里测试过了,效果很好。还对我所做的更改添加了一些注释,并在部分代码中添加了一些建议。
using UnityEngine;
using System.Collections.Generic;
using System;//Included to use Type and [Serializable]

public class Items : MonoBehaviour
{
    public struct SerializedObject //struct to hold the type of the object and the json string
    {
        public Type type;
        public string json;
    }

    static Dictionary<int, SerializedObject> items = new Dictionary<int, SerializedObject>();//dictionary must hold both type and json string to be used with JsonUtility

    private static bool initialized;

    [SerializeField]
    Texture2D[] itemIcons;

    private void Start()
    {
        Gun desertEagle = new Gun();
        desertEagle.damage = 40;
        desertEagle.range = 20;
        desertEagle.maxAmmunition = 7;
        desertEagle.firemode = FireMode.Semi;
        desertEagle.firerate = 1;

        desertEagle.name = "Desert Eagle";
        desertEagle.description = "Desert Eagle (.50 Cal) is a semi-automatic pistol with an ammo capacity of 7 rounds";
        desertEagle.equippable = true;
        desertEagle.icon = itemIcons[1];


        Consumable donut = new Consumable();
        donut.food = 30;

        donut.name = "Donut";
        donut.description = "A ring full of legendary awesomeness";
        donut.equippable = true;
        donut.icon = itemIcons[2];

        Consumable coffee = new Consumable();
        coffee.water = 30;
        coffee.stamina = 50;

        coffee.name = "Coffee";
        coffee.description = "A delicious beverage to help you get up in the morning. Goes well with donuts.";
        coffee.equippable = true;
        coffee.icon = itemIcons[3];

        //For each object store the Type and serialize the data using JsonUtility
        SerializedObject so_desertEagle;
        so_desertEagle.type = desertEagle.GetType();
        so_desertEagle.json = JsonUtility.ToJson(desertEagle);
        SerializedObject so_donut;
        so_donut.type = donut.GetType();
        so_donut.json = JsonUtility.ToJson(donut);
        SerializedObject so_coffee;
        so_coffee.type = coffee.GetType();
        so_coffee.json = JsonUtility.ToJson(coffee);
        RegisterItem(1, so_desertEagle);
        RegisterItem(2, so_donut);
        RegisterItem(3, so_coffee);

        /*//Made this for testing 
        Item gunCopy = GetItem(1);
        Gun desertEagle2 = (Gun) gunCopy;
        desertEagle2.ammunition--;

        Debug.Log(desertEagle.ammunition + " / " + desertEagle2.ammunition);
        //Debug result is "1 / 0"
        */
        initialized = true;
    }

    public static void RegisterItem(int id, SerializedObject item)
    {
        items.Add(id, item);
    }

    public static void UnregisterItem(int id)
    {
        items.Remove(id);
    }



    public static Item GetItem(int id)
    {
        return (Item) JsonUtility.FromJson(items[id].json, items[id].type); //Use JsonUtility to create a copy of the serialized object
    }
}

[Serializable]
public class ItemStack
{

    Item item;
    int amount;
    int max = 10;

    public void Add(int amount)
    {
        if (item.stackable && this.amount + amount <= max) this.amount += amount;
        else if (item.stackable) this.amount = max;
    }

    public void Remove(int amount)
    {
        if (item.stackable) this.amount -= amount;
    }
}

[Serializable]//JsonUtility only works with [Serializable] objects
public class Item
{
    public string name = "Item";
    public string description = "Your everyday standard item.";
    public bool equippable = false;
    public bool stackable = true;
    public Mesh model; //I would recommend storing the meshes in another dictionary and setting a reference here
    public Texture2D icon;
}

[Serializable]
public class Weapon : Item
{
    public float damage = 5;
    public float range = 1;
}

[Serializable]
public class Gun : Weapon
{
    public int ammunition = 1;
    public int maxAmmunition = 1;
    public FireMode firemode = FireMode.Semi;
    public int firerate = 1;
    public new float range = 10;
}

[Serializable]
public enum FireMode
{
    Semi,
    Automatic,
    Burst
}

[Serializable]
public class Consumable : Item
{
    public float food;
    public float water;
    public float health;
    public float stamina;
}
public static Item GetItem(int id)
{
    switch(id)
    {
        case 1:
            Gun desertEagle = new Gun();
            desertEagle.damage = 40;
            desertEagle.range = 20;
            desertEagle.maxAmmunition = 7;
            desertEagle.firemode = FireMode.Semi;
            desertEagle.firerate = 1;

            desertEagle.name = "Desert Eagle";
            desertEagle.description = "Desert Eagle (.50 Cal) is a semi-automatic pistol with an ammo capacity of 7 rounds";
            desertEagle.equippable = true;
             desertEagle.icon = itemIcons[1];
             return gun;
        case 2:
            Consumable donut = new Consumable();
            donut.food = 30;

            donut.name = "Donut";
            donut.description = "A ring full of legendary awesomeness";
            donut.equippable = true;
            donut.icon = itemIcons[2];
            return donut;
        case 3:
            Consumable coffee = new Consumable();
            coffee.water = 30;
            coffee.stamina = 50;

            coffee.name = "Coffee";
            coffee.description = "A delicious beverage to help you get up in the morning. Goes well with donuts.";
            coffee.equippable = true;
            coffee.icon = itemIcons[3];
            return coffee;
    }
    return null;
}