设计数据模型
Item为父类,子类
武器 防具 消耗品 继承它
Item类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Collider))]
/// <summary>
/// 背包系统 item类, 属性:名字,sprite (icon),描述, 类型,购买价格,卖出价格,Id, 负重,功能。
/// </summary>
public class Item : MonoBehaviour
{
#region Item 属性
/// <summary>
/// 自身的Id
/// </summary>
public int Id
{ get; set; }
/// <summary>
/// 名字
/// </summary>
public string Name
{ get; set; }
/// <summary>
/// 描述
/// </summary>
public string Des
{ get; set; }
/// <summary>
/// 类型
/// </summary>
public ItemType m_ItemType { get; protected set; }
/// <summary>
/// 购买价格
/// </summary>
public int buyPrice { get; set; }
/// <summary>
/// 售出价格
/// </summary>
public int sellPrice { get; set; }
/// <summary>
/// 重量
/// </summary>
public float Weight { get; set; }
public string IconSrc { get; set; }
#endregion
public Item(int Id,string Name,string Des,int buyPrice,int sellPrice,float Weight, string Icon, ItemType ItemType=ItemType.other)
{
this.Id = Id;
this.Name = Name;
this.Des = Des;
this.buyPrice = buyPrice;
this.sellPrice = sellPrice;
this.Weight = Weight;
this.m_ItemType = ItemType;
this.IconSrc = Icon;
}
}
public enum ItemType{
weapon,
consume,
armor,
other
}
防具类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Armor : Item
{
#region 防具属性
/// <summary>
/// 力量
/// </summary>
public int Power { get; set; }
/// <summary>
/// 防御 力
/// </summary>
public int Defance { get; set; }
/// <summary>
/// 敏捷
/// </summary>
public int Agility { get; set; }
/// <summary>
///生命
/// </summary>
public int HP { get; set; }
/// <summary>
/// 魔力
/// </summary>
public int MP { get; set; }
/// <summary>
/// 灵力
/// </summary>
public int Wankan { get; set; }
/// <summary>
/// 体力
/// </summary>
public int PPower { get; set; }
#endregion
public Armor(int Id, string Name, string Des, int buyPrice, int sellPrice, float Weight,string icon, int power, int defance,int agility,int hp,int mp,int wankan,int ppower,ItemType ItemType = global::ItemType.armor) : base(Id, Name, Des, buyPrice, sellPrice, Weight,icon, ItemType)
{
Power = power;
Defance = defance;
Agility = agility;
HP = hp;
MP = mp;
Wankan = wankan;
PPower = ppower;
}
}
武器类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : Item
{
/// <summary>
/// 攻击力
/// </summary>
///
public int ATK { get; set; }
/// <summary>
/// 是否损坏
/// </summary>
public bool isBreak { get; set; }
/// <summary>
/// 耐久度
/// </summary>
public int UseCount { get; set; }
/// <summary>
/// 当前使用耐久度
/// </summary>
public int CurrentUse { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="Id">武器Id </param>
/// <param name="Name">武器名字</param>
/// <param name="Des">武器描述 </param>
/// <param name="buyPrice">购买价格 </param>
/// <param name="sellPrice">卖出价格</param>
/// <param name="Weight">重量</param>
/// <param name="attcak">攻击力</param>
/// <param name="isBreak">是否损坏</param>
/// <param name="UseCount">是否损坏</param>
/// <param name="ItemType">类型武器</param>
public Weapon(int Id, string Name, string Des, int buyPrice, int sellPrice, float Weight,string icon, int attcak, bool isBreak, int UseCount, ItemType ItemType = global::ItemType.weapon) : base(Id, Name, Des, buyPrice, sellPrice, Weight,icon, ItemType)
{
ATK = attcak;
this.isBreak = isBreak;
this.UseCount = UseCount;
}
}
消耗类, 还可以 丰富点, 解除异常的药剂,增加力量的药剂 等等...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Consumble : Item
{
/// <summary>
/// 恢复的HP
/// </summary>
public int BackHP { get; set; }
/// <summary>
/// 恢复的MP
/// </summary>
public int BackMP { get; set; }
/// <summary>
/// 消耗品构造函数
/// </summary>
/// <param name="Id"></param>
/// <param name="Name"></param>
/// <param name="Des"></param>
/// <param name="buyPrice"></param>
/// <param name="sellPrice"></param>
/// <param name="Weight"></param>
/// <param name="backHP">恢复的HP</param>
/// <param name="backMP">恢复的MP</param>
/// <param name="ItemType"></param>
public Consumble(int Id, string Name, string Des, int buyPrice, int sellPrice, float Weight, string icon, int backHP,int backMP, ItemType ItemType = global::ItemType.consume) : base(Id, Name, Des, buyPrice, sellPrice, Weight,icon, ItemType)
{
this.BackHP = BackHP;
this.BackMP = backMP;
}
}
背包管理 类 挂载在 背包父物体canvas上, 控制 层 control
在 inspector面板中 把 挂载有 GridPanelUI的 Gridpanel 拖给它
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
public class knapsackManager : MonoBehaviour {
private Dictionary<int, Item> ItemDic = new Dictionary<int, Item>();
public GridPanelUI GridPanelUI;
static knapsackManager _instance;
RectTransform m_RectTransform;
bool isShowTooptip = false;
bool isDrag = false;
Transform oriItem;
Transform endItem;
public TooptipUI tooptip;
public DragItemUI DragItemUI;
public static knapsackManager Instance { get { return _instance; } }
private void Awake()
{
_instance = this;
m_RectTransform = GetComponent<RectTransform>();
LoadItem();
//Sprite a= Resources.Load<Sprite>("icon/J_01");
// GridPanelUI.grids[0].GetChild(0).GetComponent<UnityEngine.UI.Image>().sprite = a;
GridUI.OnEnter += GridUIOnEnter;
GridUI.OnExit += GridUIOnExit;
GridUI.OnLeftBeginDrag += OnEnterDrag;
GridUI.OnLeftEndDrag += OnEndDrag;
}
private void Update()
{
Vector2 position;
RectTransformUtility.ScreenPointToLocalPointInRectangle(m_RectTransform, Input.mousePosition, null, out position);
if (!isDrag)
{
if (isShowTooptip)
{
tooptip.Show();
tooptip.SetLolcalpos(position);
}
}
else
{
DragItemUI.Show();
DragItemUI.SetLolcalpos(position);
}
}
#region 事件回调
#region enter exit
void GridUIOnEnter(string gridTransfrom)
{
// Debug.Log(gridTransfrom);
Item item = ItemModel.GetItem(gridTransfrom);
// 注意 Debug时,该Item 为null时, 是因为 使用了构造函数 而item类 继承了 MonoBehaviour
//坑1 7.避免使用构造函数
//不要在构造函数中初始化任何变量,使用Awake或Start实现这个目的。即使是在编辑模式中Unity也自动调用构造函数,这通常发生在一个脚本被编译之后,因为需要调用构造函数来取向一个脚本的默认值。构造函数不仅会在无法预料的时刻被调用,它也会为预设或未激活的游戏物体调用。 //因此如果你想实现,如,一个单件模式,不要使用构造函数,而是使用Awake。其实上,没有理由一定要在继续自MononBehaviour类的构造函数中写任何代码。 //单件模式使用构造函数可能会导致严重的后果,带来类似随机null引用异常。
// Debug.Log(item);
if (null==item) {
return;
}
isShowTooptip = true;
//显示数据 属性
string text = GetTooltipText(item);
tooptip.UpdateText(text);
}
void GridUIOnExit(string gridTransfrom)
{
isShowTooptip = false;
tooptip.Hide();
}
#endregion
#region Drag
public void OnEnterDrag(Transform GridTran)
{
if (GridTran.childCount == 0) { return;}
else
{
oriItem = GridTran;
isDrag = true;
Item item = ItemModel.GetItem(GridTran.name);
DragItemUI.UpdateImg(item.IconSrc);
//开始拖时 ,删除掉前面的物体 改动在这里
for (int i = 0; i < GridTran.childCount; i++)
{
Destroy(GridTran.GetChild(i).gameObject);
}
}
}
public void OnEndDrag(Transform oriItem,Transform endItem)
{
this.endItem = endItem;
isDrag = false;
DragItemUI.Hide();
if (endItem==null)//扔东西
{
ItemModel.DeleItem(oriItem.name);
// Destroy(oriItem.GetChild(0).gameObject);
}else if (endItem.transform.CompareTag("grid"))
{
//如果 格子 为空 直接放
if (endItem.childCount == 0)
{
Item item = ItemModel.GetItem(oriItem.name);
ItemModel.DeleItem(oriItem.name);
CreatNewItem(item, endItem);
}
//交换
else
{
//在开始拖的时候 Destory 改动
// Destroy(endItem.GetChild(0).gameObject);
Item item = ItemModel.GetItem(oriItem.name);
Item nextitem = ItemModel.GetItem(endItem.name);
if (oriItem.name == endItem.name)
{
Debug.Log("error");
}
if (oriItem.childCount > 0)
{
Destroy(oriItem.GetChild(0).gameObject);
}
CreatNewItem(item, endItem);
CreatNewItem(nextitem, oriItem);
//ItemModel.DeleItem(oriItem.name);
//ItemModel.DeleItem(endItem.name);
}
}
else
{
Item item = ItemModel.GetItem(oriItem.name);
CreatNewItem(item, oriItem);
}
}
#endregion
#endregion
/// <summary>
/// 获取 提示框物体字体
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
string GetTooltipText(Item item)
{
if (item.Name == null)
return "";
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<color=red>{0}</color>\n\n", item.Name);
switch (item.m_ItemType)
{
case ItemType.armor:
Armor armor = item as Armor;
sb.AppendFormat("力量:{0}\n防御:{1}\n敏捷:{2}\n生命:{3}\n魔力:{4}\n灵力:{5}\n体力:{6}\n\n", armor.Power,armor.Defance,armor.Agility,armor.HP,armor.MP,armor.Wankan,armor.PPower);
break;
case ItemType.consume:
Consumble consumble = item as Consumble;
sb.AppendFormat("生命:{0}\n魔力:{1}\n\n",consumble.BackHP,consumble.BackMP);
break;
case ItemType.weapon:
Weapon weapon = item as Weapon;
sb.AppendFormat("攻击力:{0}\n耐久度:{1}/{2}\n\n", weapon.ATK, weapon.CurrentUse, weapon.UseCount);
break;
default:
//sb.AppendFormat("售出价格:{0}\n\n", item.sellPrice);
break;
}
sb.AppendFormat("<size=25><color=white>重量:{0}\n售出价格:{1}</color></size>\n\n <color=yellow><size=20>描述:{2}</size></color>", item.Weight,item.sellPrice,item.Des);
return sb.ToString();
}
/// <summary>
///储存物体
/// </summary>
/// <param name="ItemId"></param>
public void StoreItem(int ItemId)
{
if (!ItemDic.ContainsKey(ItemId))
return;
Transform emptyGrid = GridPanelUI.GetEnemyGrid();
if (emptyGrid == null)
{
Debug.Log("背包已满!");
return;
}
Item item = ItemDic[ItemId];
CreatNewItem(item, emptyGrid);
// Debug.Log("item"+item.Name);
tooptip.UpdateText(item.Name);
ItemModel.StormItem(emptyGrid.name, item);
//Item NewIt = ItemModel.GetItem(emptyGrid.name);
//Debug.Log(NewIt.Name);
//ItemModel.ShowDir();
}
void CreatNewItem(Item item,Transform parentGrid)
{
GameObject ItemTemp = Resources.Load<GameObject>("prefabs/Item");
// ItemTemp.GetComponent<ItemUI>().UpdateText(item.Name);
ItemTemp.GetComponent<ItemUI>().UpdateImg(item.IconSrc);
GameObject itemGo = Instantiate(ItemTemp);
itemGo.transform.SetParent(parentGrid);
itemGo.transform.localPosition = Vector3.zero;
itemGo.transform.localScale = Vector3.one;
ItemModel.StormItem(parentGrid.name, item);
}
/// <summary>
/// 加载 装备
/// </summary>
void LoadItem()
{
ItemDic = new Dictionary<int, Item>();
//武器
Weapon w1 = new Weapon(0, "杀羊刀","咩咩咩,用来杀羊",5, 3,1, "icon/J_01", 10, false, 500);
Weapon w2 = new Weapon(1, "杀牛刀", "哞哞哞,用来杀牛", 6, 3, 1, "icon/J_03", 10, false, 480);
Weapon w3 = new Weapon(2, "杀猪刀", "杀猪专用", 7, 4, 1, "icon/J_08", 10, false, 470);
Weapon w4 = new Weapon(3, "杀鸡刀", "锋利的刀,用来杀鸡", 4, 2, 1, "icon/s_009", 10, false, 455);
//消耗品
Consumble C1 = new Consumble(4, "小蓝瓶","很普通的药剂,可以恢复蓝量", 2, 1, 0.1f, "icon/s_013",1, 10);
Consumble C2 = new Consumble(5, "小红瓶", "用小红果熬成的药剂,可以恢复血量", 2, 1, 0.1f, "icon/s_017", 10 , 1);
//防具
Armor a1 = new Armor(6, "牛皮头盔", "用牛皮做的头盔", 4, 2, 0.6f, "icon/s_019", 2, 3, 1, 10, 3, 2, 3);
Armor a2 = new Armor(7, "牛皮盔甲", "用牛皮做的盔甲", 5, 3, 0.8f, "icon/s_023", 1, 5, 1, 10, 3, 2, 2);
Armor a3 = new Armor(8, "牛皮肩", "用牛皮做的护肩", 4, 2, 0.6f, "icon/s_025", 1, 3, 1, 5, 3, 1, 1);
Armor a4 = new Armor(9, "牛皮靴", "用牛皮做的靴子", 4, 2, 0.5f, "icon/s_026", 1, 3, 5, 3,2, 1, 2);
// 加入 武器
ItemDic.Add(w1.Id, w1);
ItemDic.Add(w2.Id, w2);
ItemDic.Add(w3.Id, w3);
ItemDic.Add(w4.Id, w4);
//加入 消耗品
ItemDic.Add(C1.Id, C1);
ItemDic.Add(C2.Id, C2);
//加入防具
ItemDic.Add(a1.Id, a1);
ItemDic.Add(a2.Id, a2);
ItemDic.Add(a3.Id, a3);
ItemDic.Add(a4.Id, a4);
}
}
View层
此处的GridUI 类 后续 贴出;
GridpPanelUI
把Inspect面板上的锁头 点开, 然后把按住shit+鼠标左键,选择所有的 grid
拖给 grids
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 视图层
/// </summary>
public class GridPanelUI : MonoBehaviour {
public Transform[] grids;
/// <summary>
/// 找到空格子;
/// </summary>
/// <returns></returns>
public Transform GetEnemyGrid()
{
for (int i=0; i < grids.Length; i++)
{
if (grids[i].childCount == 0)
{
return grids[i];
}
}
return null;
}
}
View层
ItemUI 挂载在Item上。 item是 背包中的物品
层级视图
属性面板
然后保存成prefab View 层
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ItemUI : MonoBehaviour {
public Text TextItem;
public Image ItemImg;
// Use this for initialization
public void UpdateText(string name)
{
TextItem.text = name;
}
public void UpdateImg(Sprite spri)
{
ItemImg.sprite = spri;
}
public void UpdateImg(string src)
{
// Debug.Log(src);
Sprite a = Resources.Load<Sprite>(src);
// Debug.Log(a);
ItemImg.sprite = a;
}
}
GridUI类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System;
public class GridUI : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler, IBeginDragHandler,IDragHandler,IEndDragHandler{
#region enter exit
public static Action<string> OnEnter;
public static Action<string> OnExit;
public void OnPointerEnter(PointerEventData eventData)
{
if (eventData.pointerEnter.CompareTag("grid"))
{
// Debug.Log(transform);
if (OnEnter != null)
{
// Debug.Log(transform.name);
OnEnter(transform.name);
}
}
}
public void OnPointerExit(PointerEventData eventData)
{
if (OnExit != null)
{
OnExit(transform.name);
}
}
#endregion
#region drag
public static Action<Transform> OnLeftBeginDrag;
public static Action<Transform,Transform> OnLeftEndDrag;
void IBeginDragHandler.OnBeginDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (OnLeftBeginDrag != null)
OnLeftBeginDrag(transform);
}
}
void IDragHandler.OnDrag(PointerEventData eventData)
{
}
void IEndDragHandler.OnEndDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (OnLeftEndDrag != null)
{
if (eventData.pointerEnter == null)
{ OnLeftEndDrag(transform, null); }
else
{
OnLeftEndDrag(transform, eventData.pointerEnter.transform);
}
}
}
}
#endregion
}
DragItemUI 继承ItemUI; View 层, 复制一份ItemUI作为DragItemUI 不用存为prefab,修改名字,作为 到时候 拖动时生存的item;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DragItemUI : ItemUI
{
public void SetLolcalpos(Vector2 pos)
{
transform.localPosition = pos;
}
public void Show()
{
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
}
属性 提示框
ToopTip类 View层
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TooptipUI : MonoBehaviour {
public Text OutLineText;
public Text InsidText;
public void UpdateText(string text)
{
// Debug.Log("1");
OutLineText.text = text;
InsidText.text = text;
}
public void SetLolcalpos(Vector2 pos)
{
transform.localPosition = pos;
}
public void Show()
{
OutLineText.gameObject.SetActive(true);
}
public void Hide()
{
OutLineText.gameObject.SetActive(false);
}
}
数据层, model
存放 每一个 格子下的物品数字; 用每一个格子的名字作为key存入字典;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemModel
{
static Dictionary<string, Item> GridItem = new Dictionary<string, Item>();
/// <summary>
/// 储存 Item数据
/// </summary>
public static void StormItem(string key,Item item)
{
if (GridItem.ContainsKey(key))
GridItem.Remove(key);
// Debug.Log(key+"物品名字"+ item.Name);
GridItem.Add(key, item);
// Debug.Log(GridItem[key].Name);
}
/// <summary>
/// 取 Item数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static Item GetItem( string key)
{
// Debug.Log(key);
// Debug.Log( GridItem[key]);
if (GridItem.ContainsKey(key))
{
return GridItem[key];
}
else
// Debug.Log("没有此物品");
return null;
}
public static void DeleItem(string key)
{
if (GridItem.ContainsKey(key))
{
GridItem.Remove(key);
}
}
public static void ShowDir()
{
Debug.Log(GridItem.Count);
foreach (KeyValuePair<string, Item> kv in GridItem)
{
// Debug.Log(kv.Key+kv.Value.Name);
}
}
}
模拟输入
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputDectore : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(1))
{
int r = Random.Range(0, 10);
knapsackManager.Instance.StoreItem(r);
}
}
}