UGUI制作背包系统 MVC模式 (下) 脚本篇

 

设计数据模型

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值