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;
}