背包系统一
一、创建物品类以及物品类型属性
1.如图所示

2.创建脚本Item类
/// <summary>
/// 物品基类
/// </summary>
public class Item {
public int ID { get; set; }//ID
public string Name { get; set; }//名字
public ItemType Type { get; set; }//类型
public ItemQuality Quality { get; set; }//质量
public string Description { get; set; }//描述
public int Capacity { get; set; }//容量
public int BuyPrice { get; set; }//购买价格
public int SellPrice { get; set; }//售卖价格
public string Sprite { get; set; }//物品图片
public Item()
{
this.ID = -1;
}
//构造函数
public Item(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite)
{
this.ID = id;
this.Name = name;
this.Type = type;
this.Quality = quality;
this.Description = des;
this.Capacity = capacity;
this.BuyPrice = buyPrice;
this.SellPrice = sellPrice;
this.Sprite = sprite;
}
/// <summary>
/// 物品类型
/// </summary>
public enum ItemType
{
Consumable,//消耗品
Equipment,//装备
Weapon,//武器
Material//材料
}
/// <summary>
/// 品质
/// </summary>
public enum ItemQuality
{
Common,//普通
Uncommon,//不普通
Rare,//稀有
Epic,//史诗般
Legendary,//传奇
Artifact//古老
}
/// <summary>
/// 得到提示面板应该显示什么样的内容
/// </summary>
/// <returns></returns>
public virtual string GetToolTipText()
{
string color = "";
switch (Quality)
{
case ItemQuality.Common:
color = "white";
break;
case ItemQuality.Uncommon:
color = "lime";
break;
case ItemQuality.Rare:
color = "navy";
break;
case ItemQuality.Epic:
color = "magenta";
break;
case ItemQuality.Legendary:
color = "orange";
break;
case ItemQuality.Artifact:
color = "red";
break;
}
string text = string.Format("<color={4}>{0}</color>\n<size=10><color=green>购买价格:{1} 出售价格:{2}</color></size>\n<color=yellow><size=10>{3}</size></color>", Name, BuyPrice, SellPrice, Description, color);
return text;
}
}
消耗品类
/// <summary>
/// 消耗品类
/// </summary>
public class Consumable : Item {
public int HP { get; set; }//血量
public int MP { get; set; }//蓝量
public Consumable(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice ,string sprite,int hp,int mp)
:base(id,name,type,quality,des,capacity,buyPrice,sellPrice,sprite)
{
this.HP = hp;
this.MP = mp;
}
public override string GetToolTipText()
{
string text = base.GetToolTipText();
string newText = string.Format("{0}\n\n<color=blue>加血:{1}\n加蓝:{2}</color>", text, HP, MP);
return newText;
}
public override string ToString()
{
string s = "";
s += ID.ToString();
s += Type;
s += Quality;
s += Description;
s += Capacity;
s += BuyPrice;
s += SellPrice;
s += Sprite;
s += HP;
s += MP;
return s;
}
}
装备类
public class Equipment : Item
{
/// <summary>
/// 力量
/// </summary>
public int Strength { get; set; }
/// <summary>
/// 智力
/// </summary>
public int Intellect { get; set; }
/// <summary>
/// 敏捷
/// </summary>
public int Agility { get; set; }
/// <summary>
/// 体力
/// </summary>
public int Stamina { get; set; }
/// <summary>
/// 装备类型
/// </summary>
public EquipmentType EquipType { get; set; }
public Equipment(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice, string sprite,
int strength, int intellect, int agility, int stamina, EquipmentType equipType)
: base(id, name, type, quality, des, capacity, buyPrice, sellPrice, sprite)
{
this.Strength = strength;
this.Intellect = intellect;
this.Agility = agility;
this.Stamina = stamina;
this.EquipType = equipType;
}
public enum EquipmentType
{
None,
Head,
Neck,
Chest,
Ring,
Leg,
Bracer,
Boots,
Shoulder,
Belt,
OffHand
}
public override string GetToolTipText()
{
string text = base.GetToolTipText();
string equipTypeText = "";
switch (EquipType)
{
case EquipmentType.Head:
equipTypeText = "头部";
break;
case EquipmentType.Neck:
equipTypeText = "脖子";
break;
case EquipmentType.Chest:
equipTypeText = "胸部";
break;
case EquipmentType.Ring:
equipTypeText = "戒指";
break;
case EquipmentType.Leg:
equipTypeText = "腿部";
break;
case EquipmentType.Bracer:
equipTypeText = "护腕";
break;
case EquipmentType.Boots:
equipTypeText = "靴子";
break;
case EquipmentType.Shoulder:
equipTypeText = "护肩";
break;
case EquipmentType.Belt:
equipTypeText = "腰带";
break;
case EquipmentType.OffHand:
equipTypeText = "副手";
break;
}
string newText = string.Format("{0}\n\n<color=blue>装备类型:{1}\n力量:{2}\n智力:{3}\n敏捷:{4}\n体力:{5}</color>", text, equipTypeText, Strength, Intellect, Agility, Stamina);
return newText;
}
}
武器类
/// <summary>
/// 武器
/// </summary>
public class Weapon : Item {
public int Damage { get; set; }
public WeaponType WpType { get; set; }
public Weapon(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite,
int damage,WeaponType wpType)
: base(id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite)
{
this.Damage = damage;
this.WpType = wpType;
}
public enum WeaponType
{
None,
OffHand,
MainHand
}
public override string GetToolTipText()
{
string text = base.GetToolTipText();
string wpTypeText = "";
switch (WpType)
{
case WeaponType.OffHand:
wpTypeText = "副手";
break;
case WeaponType.MainHand:
wpTypeText = "主手";
break;
}
string newText = string.Format("{0}\n\n<color=blue>武器类型:{1}\n攻击力:{2}</color>", text, wpTypeText, Damage);
return newText;
}
}
材料类
/// <summary>
/// 材料类
/// </summary>
public class Material : Item {
public Material(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite)
: base(id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite)
{
}
}
二、UI搭建
1.创建一个BagPanel,在其下面创建Scroll View,可以滑动的包,
2.在Content下创建空对象BagGridPanel,并添加组件GridLayoutGroup、Canvas Group。GridLayoutGroup组件Cell Size设置80X80,Spacing:10X8。添加脚本knapsack
3.在BagGridPanel下创建BagFrame物品槽,添加脚本Slot。并拖成预制体
4.在BagFrame下创建itemsprite(Imge)和ItemAmount(Text),添加脚本ItemUI,并拖成预制体

三、编写Json文件
1.https://www.bejson.com/jsoneditoronline/这个网址可以在线编写Json文件
[
{
"id": 1,
"name": "血瓶",
"type": "Consumable",
"quality": "Common",
"description": "这个是用来加血的",
"capacity": 10,
"buyPrice": 10,
"sellPrice": 5,
"hp": 10,
"mp": 0,
"sprite": "Sprites/Items/hp"
},
{
"id": 2,
"name": "蓝瓶",
"type": "Consumable",
"quality": "Common",
"description": "这个是用来加蓝的",
"capacity": 10,
"buyPrice": 10,
"sellPrice": 5,
"hp": 0,
"mp": 10,
"sprite": "Sprites/Items/mp"
},
{
"id": 3,
"name": "胸甲",
"type": "Equipment",
"quality": "Rare",
"description": "这个胸甲很牛B",
"capacity": 1,
"buyPrice": 20,
"sellPrice": 10,
"sprite": "Sprites/Items/armor",
"strength":10,
"intellect":4,
"agility":9,
"stamina":1,
"equipType":"Chest"
},
{
"id": 4,
"name": "皮腰带",
"type": "Equipment",
"quality": "Epic",
"description": "这个腰带可以加速",
"capacity": 1,
"buyPrice": 20,
"sellPrice": 10,
"sprite": "Sprites/Items/belts",
"strength":1,
"intellect":6,
"agility":10,
"stamina":10,
"equipType":"Belt"
},
{
"id": 5,
"name": "靴子",
"type": "Equipment",
"quality": "Legendary",
"description": "这个靴子可以加速",
"capacity": 1,
"buyPrice": 20,
"sellPrice": 10,
"sprite": "Sprites/Items/boots",
"strength":10,
"intellect":5,
"agility":0,
"stamina":10,
"equipType":"Boots"
},
{
"id": 6,
"name": "护腕",
"type": "Equipment",
"quality": "Rare",
"description": "这个护腕可以增加防御",
"capacity": 1,
"buyPrice": 20,
"sellPrice": 10,
"sprite": "Sprites/Items/bracers",
"strength":1,
"intellect":2,
"agility":3,
"stamina":4,
"equipType":"Bracer"
},
{
"id": 7,
"name": "神启手套",
"type": "Equipment",
"quality": "Common",
"description": "很厉害的手套",
"capacity": 1,
"buyPrice": 10,
"sellPrice": 5,
"sprite": "Sprites/Items/gloves",
"strength":2,
"intellect":3,
"agility":4,
"stamina":4,
"equipType":"OffHand"
},
{
"id": 8,
"name": "头盔",
"type": "Equipment",
"quality": "Artifact",
"description": "很厉害的头盔",
"capacity": 1,
"buyPrice": 10,
"sellPrice": 5,
"sprite": "Sprites/Items/helmets",
"strength":2,
"intellect":3,
"agility":4,
"stamina":4,
"equipType":"Head"
},
{
"id": 9,
"name": "项链",
"type": "Equipment",
"quality": "Rare",
"description": "很厉害的项链",
"capacity": 1,
"buyPrice": 10,
"sellPrice": 5,
"sprite": "Sprites/Items/necklace",
"strength":2,
"intellect":3,
"agility":4,
"stamina":4,
"equipType":"Neck"
},
{
"id": 10,
"name": "戒指",
"type": "Equipment",
"quality": "Common",
"description": "很厉害的戒指",
"capacity": 1,
"buyPrice": 20,
"sellPrice": 20,
"sprite": "Sprites/Items/rings",
"strength":20,
"intellect":3,
"agility":4,
"stamina":4,
"equipType":"Ring"
},
{
"id": 11,
"name": "裤子",
"type": "Equipment",
"quality": "Uncommon",
"description": "很厉害的裤子",
"capacity": 1,
"buyPrice": 40,
"sellPrice": 20,
"sprite": "Sprites/Items/pants",
"strength":20,
"intellect":30,
"agility":40,
"stamina":40,
"equipType":"Leg"
},
{
"id": 12,
"name": "护肩",
"type": "Equipment",
"quality": "Legendary",
"description": "很厉害的护肩",
"capacity": 1,
"buyPrice": 100,
"sellPrice": 20,
"sprite": "Sprites/Items/shoulders",
"strength":2,
"intellect":3,
"agility":4,
"stamina":4,
"equipType":"Shoulder"
},
{
"id": 13,
"name": "开天斧",
"type": "Weapon",
"quality": "Rare",
"description": "渔翁移山用的斧子",
"capacity": 1,
"buyPrice": 50,
"sellPrice": 20,
"sprite": "Sprites/Items/axe",
"damage":100,
"weaponType":"MainHand"
},
{
"id": 14,
"name": "阴阳剑",
"type": "Weapon",
"quality": "Rare",
"description": "非常厉害的剑",
"capacity": 1,
"buyPrice": 15,
"sellPrice": 5,
"sprite": "Sprites/Items/sword",
"damage":20,
"weaponType":"OffHand"
},
{
"id": 15,
"name": "开天斧的锻造秘籍",
"type": "Material",
"quality": "Artifact",
"description": "用来锻造开天斧的秘籍",
"capacity": 2,
"buyPrice": 100,
"sellPrice": 99,
"sprite": "Sprites/Items/book"
},
{
"id": 16,
"name": "头盔的锻造秘籍",
"type": "Material",
"quality": "Common",
"description": "用来锻造头盔的秘籍",
"capacity": 2,
"buyPrice": 50,
"sellPrice": 10,
"sprite": "Sprites/Items/scroll"
},
{
"id": 17,
"name": "铁块",
"type": "Material",
"quality": "Common",
"description": "用来锻造其他东西的必备材料",
"capacity": 20,
"buyPrice": 5,
"sellPrice": 4,
"sprite": "Sprites/Items/ingots"
}
]
四、解析Json文件
1.Json文件放在Resources文件夹下
2.创建厂库管理对象脚本InventoryManager
public class InventoryManager : MonoBehaviour
{
#region 单例模式
private static InventoryManager _instance;
public static InventoryManager Instance
{
get
{
if (_instance == null)
{
//下面的代码只会执行一次
_instance = GameObject.Find("InventoryManager").GetComponent<InventoryManager>();
}
return _instance;
}
}
#endregion
/// <summary>
/// 物品信息的列表(集合)
/// </summary>
private List<Item> itemList;
void Awake()
{
ParseItemJson();
}
/// <summary>
/// 解析物品信息
/// </summary>
void ParseItemJson()
{
itemList = new List<Item>();
//文本为在Unity里面是 TextAsset类型
TextAsset itemText = Resources.Load<TextAsset>("Items");
string itemsJson = itemText.text;//物品信息的Json格式
JSONObject j = new JSONObject(itemsJson);
foreach (JSONObject temp in j.list)
{
string typeStr = temp["type"].str;
Item.ItemType type= (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), typeStr);
//下面的事解析这个对象里面的公有属性
int id = (int)(temp["id"].n);
string name = temp["name"].str;
Item.ItemQuality quality = (Item.ItemQuality)System.Enum.Parse(typeof(Item.ItemQuality), temp["quality"].str);
string description = temp["description"].str;
int capacity = (int)(temp["capacity"].n);
int buyPrice = (int)(temp["buyPrice"].n);
int sellPrice = (int)(temp["sellPrice"].n);
string sprite = temp["sprite"].str;
Item item = null;
switch (type)
{
case Item.ItemType.Consumable:
int hp = (int)(temp["hp"].n);
int mp = (int)(temp["mp"].n);
item = new Consumable(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, hp, mp);
break;
case Item.ItemType.Equipment:
//
int strength = (int)temp["strength"].n;
int intellect = (int)temp["intellect"].n;
int agility = (int)temp["agility"].n;
int stamina = (int)temp["stamina"].n;
Equipment.EquipmentType equipType = (Equipment.EquipmentType) System.Enum.Parse( typeof(Equipment.EquipmentType),temp["equipType"].str );
item = new Equipment(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, strength, intellect, agility, stamina, equipType);
break;
case Item.ItemType.Weapon:
//
int damage = (int) temp["damage"].n;
Weapon.WeaponType wpType = (Weapon.WeaponType)System.Enum.Parse(typeof(Weapon.WeaponType), temp["weaponType"].str);
item = new Weapon(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, damage, wpType);
break;
case Item.ItemType.Material:
//
item = new Material(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite);
break;
}
itemList.Add(item);
}
}
五、Inventory背包获取物品并进行存储
1.BagPanel
public class Knapsack : Inventory
{
#region 单例模式
private static Knapsack _instance;
public static Knapsack Instance
{
get
{
if (_instance == null)
{
_instance = GameObject.Find("BagGridPanel").GetComponent<Knapsack>();
}
return _instance;
}
}
#endregion
}
2.InventoryManager
//通过ID获取物品
public Item GetItemById(int id)
{
foreach (Item item in itemList)
{
if (item.ID == id)
{
return item;
}
}
return null;
}
3.Inventory
public class Inventory : MonoBehaviour {
protected Slot[] slotList;//物品槽数组
private float targetAlpha = 1;
private float smoothing = 4;
private CanvasGroup canvasGroup;
public virtual void Start ()
{
slotList = GetComponentsInChildren<Slot>();
canvasGroup = GetComponent<CanvasGroup>();
}
public bool StoreItem(int id)
{
Item item = InventoryManager.Instance.GetItemById(id);//通过ID获取物品
return StoreItem(item);
}
public bool StoreItem(Item item)
{
if (item == null)
{
Debug.LogWarning("要存储的物品的id不存在");
return false;
}
if (item.Capacity == 1)
{
Slot slot = FindEmptySlot();
if (slot == null)
{
Debug.LogWarning("没有空的物品槽");
return false;
}
else
{
slot.StoreItem(item);//把物品存储到这个空的物品槽里面
}
}
else
{
Slot slot = FindSameIdSlot(item);
if (slot != null)
{
slot.StoreItem(item);
}
else
{
Slot emptySlot = FindEmptySlot();
if (emptySlot != null)
{
emptySlot.StoreItem(item);
}
else
{
Debug.LogWarning("没有空的物品槽");
return false;
}
}
}
return true;
}
/// <summary>
/// 这个方法用来找到一个空的物品槽
/// </summary>
/// <returns></returns>
private Slot FindEmptySlot()
{
foreach (Slot slot in slotList)
{
if (slot.transform.childCount == 0)
{
return slot;
}
}
return null;
}
//找相同的物品槽
private Slot FindSameIdSlot(Item item)
{
foreach (Slot slot in slotList)
{
if (slot.transform.childCount >= 1 && slot.GetItemId() == item.ID && slot.IsFilled() == false)
{
return slot;
}
}
return null;
}
4.Slot物品槽
/// <summary>
/// 物品槽
/// </summary>
public class Slot : MonoBehaviour{
public GameObject itemPrefab;//物品预制体
/// <summary>
/// 把item放在自身下面
/// 如果自身下面已经有item了,amount++
/// 如果没有 根据itemPrefab去实例化一个item,放在下面
/// </summary>
/// <param name="item"></param>
public void StoreItem(Item item)
{
if (transform.childCount == 0)
{
GameObject itemGameObject = Instantiate(itemPrefab) as GameObject;
itemGameObject.transform.SetParent(this.transform);
itemGameObject.transform.localScale = Vector3.one;
itemGameObject.transform.localPosition = Vector3.zero;
itemGameObject.GetComponent<ItemUI>().SetItem(item);
}
else
{
transform.GetChild(0).GetComponent<ItemUI>().AddAmount();
}
}
/// <summary>
/// 得到物品的id
/// </summary>
/// <returns></returns>
public int GetItemId()
{
return transform.GetChild(0).GetComponent<ItemUI>().Item.ID;
}
//是否填满
public bool IsFilled()
{
ItemUI itemUI = transform.GetChild(0).GetComponent<ItemUI>();
return itemUI.Amount >= itemUI.Item.Capacity;//当前的数量大于等于容量
}
5.ItemUI
public class ItemUI : MonoBehaviour
{
#region Data
public Item Item { get; private set; }//物品
public int Amount { get; private set; }//物品数量
#endregion
#region UI Component
private Image itemImage;//物品图片
private Text amountText;//物品数量文本
//获得物品图片组件
private Image ItemImage
{
get
{
if (itemImage == null)
{
itemImage = GetComponent<Image>();
}
return itemImage;
}
}
//获得物品数量文本组件
private Text AmountText
{
get
{
if (amountText == null)
{
amountText = GetComponentInChildren<Text>();
}
return amountText;
}
}
#endregion
private float targetScale = 1f;
private Vector3 animationScale = new Vector3(1.4f, 1.4f, 1.4f);
private float smoothing = 4;
//更新UI
public void SetItem(Item item,int amount = 1)
{
transform.localScale = animationScale;
this.Item = item;
this.Amount = amount;
// update ui
ItemImage.sprite = Resources.Load<Sprite>(item.Sprite);
if (Item.Capacity > 1)
AmountText.text = Amount.ToString();
else
AmountText.text = "";
}
//增加物品数量
public void AddAmount(int amount=1)
{
transform.localScale = animationScale;
this.Amount += amount;
//update ui
if (Item.Capacity > 1)
AmountText.text = Amount.ToString();
else
AmountText.text = "";
}
6.测试脚本Player
void Update () {
//G 随机得到一个物品放到背包里面
if (Input.GetKeyDown(KeyCode.G))
{
int id = Random.Range(1, 18);
Knapsack.Instance.StoreItem(id);
}

浙公网安备 33010602011771号