21UGUI背包系统

一、UGUI背包系统展示##

UGUI背包展示

二、背包系统的搭建##

背包格子的搭建成功

三、加载预支物的制作##

预支物的制作
通过按键模拟拾取物品的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class KnapsackManager : MonoBehaviour
{

    public static Dictionary<int, BaseItem> ItemList;//用键值对承储信息


    GameObject item;//实例化的物体

    public GameObject[] Cells;//获取格子信息
    Image imagesingle;//获取预支物身上的图片

    Text textNum;//获取预支物子物体的文字显示信息
    int textInt;//承储变量

    public GameObject PoolCanvas;





    void Awake()
    {
        Load();//加载
    }

    void Start()
    {

    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.X))//通过按下X键模拟拾取物品
        {
            int index = Random.Range(0, 5);
            Pickup(ItemList[index]);
            //print(index);  
        }
    }

    private void Load()//加载需要的资源,如果过多需要保存在数据库。
    {
        ItemList = new Dictionary<int, BaseItem>();
        Weapons sword_blade = new Weapons(0, "魔剑", "最厉害的魔剑", 20000, 12000, "Pictures/blade_sword", 280);
        Weapons sword_blood = new Weapons(1, "嗜血剑", "偷取敌人10%生命值的嗜血剑", 18000, 9000, "Pictures/blood_sword", 250);
        Weapons sword_double = new Weapons(2, "重影剑", "每次攻击都会有几率出现攻击了2次的重影剑", 22000, 13000, "Pictures/double_sword", 300);

        Consumables HP_back = new Consumables(3, "诺顿的血药", "立马回复生命值100", 5, 3, "Pictures/add_HP", 100, 0);
        Consumables Mp_back = new Consumables(4, "诺顿的大蓝药", "立马回复蓝量100", 4, 2, "Pictures/add_MP", 0, 100);

        ItemList.Add(sword_blade.ID, sword_blade);
        ItemList.Add(sword_blood.ID, sword_blood);
        ItemList.Add(sword_double.ID, sword_double);

        ItemList.Add(HP_back.ID, HP_back);
        ItemList.Add(Mp_back.ID, Mp_back);

    }




    public void Pickup(BaseItem baseItem)
    {
        bool isFind = false;
        //实例化物体
        //item = Instantiate(Resources.Load("Prefabs/Item"), transform.position, transform.rotation) as GameObject;
        item = PoolManager.Get("Item", transform.position, transform.rotation) as GameObject;//通过对象池来实现物体的创建与回收
        imagesingle = item.transform.GetComponent<Image>();//获取实例化物体的图片信息
        //imagesingle.overrideSprite = Resources.Load("Pictres/blade_sword",typeof(Sprite));
        imagesingle.overrideSprite = Resources.Load(baseItem.Icon, typeof(Sprite)) as Sprite;//找到对应的物体名字
        for (int i = 0; i < Cells.Length; i++)
        {
            if (Cells[i].transform.childCount > 0)
            {
                //如果格子里面有物体,下标进行数据管理
                if (imagesingle.overrideSprite.name == Cells[i].transform.GetChild(0).transform.GetComponent<Image>().overrideSprite.name)
                {
                    isFind = true;
                    textNum = Cells[i].transform.GetChild(0).transform.GetChild(0).GetComponent<Text>();
                    textInt = int.Parse(textNum.text);
                    textInt += 1;
                    textNum.text = textInt.ToString();//实现了获取相同物品,下标相应变化过程
                    //Destroy(item);
                    // PoolManager.Return(item);
                    StartCoroutine(ReturnToPoll());
                    item.transform.SetParent(PoolCanvas.transform);
                    break;
                }              

            }



        }
        if (isFind == false)
        {
            for (int i = 0; i < Cells.Length; i++)
            {
                if (Cells[i].transform.childCount == 0)
                {
                    item.transform.SetParent(Cells[i].transform);
                    item.transform.localPosition = Vector3.zero;
                    //保留格子;
                    StorItem.Store(Cells[i].transform.name, baseItem);//把格子保留到商店里面去,还有物品
                    print(Cells[i].transform.name);
                    print(baseItem.Description);
                    break;
                }
            }
        }

    }


    IEnumerator ReturnToPoll()
    {
        yield return new WaitForSeconds(0.0f);
        PoolManager.Return(item);
    }

}

四、预支物基类的建立以及各种相应的类处理##

基类的建立:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BaseItem  {
    public int ID {
        get;
        private set;
    }

    public string Name {
        get;
        private set;
    }
    
    public string Description
    {
        get;
        private set;
    }

    public int BuyPrice {
        get;
        private set;
    }

    public int SellPrice {
        get;
        private set;
    }

    public string Icon {
        get;
        private set;
    }

    public BaseItem(int id,string name,string description,int buyPrice,int sellPrice,string icon)
    {
        this.ID = id;
        this.Name = name;
        this.Description = description;
        this.BuyPrice = buyPrice;
        this.SellPrice = sellPrice;
        this.Icon = icon;
    }

}

防具类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Armors : BaseItem {

    public int Defense {
        get;
        private set;
    }
    public Armors(int id, string name, string description, int buyPrice, int sellPrice, string icon, int defense) : base(id, name, description, buyPrice, sellPrice, icon)
    {
        this.Defense = defense;
    }
}
武器类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Weapons : BaseItem {
    public int Attack {
        get;
        private set;
    }
    public Weapons(int id, string name, string description, int buyPrice, int sellPrice, string icon,int attack):base(id,name,description,buyPrice,sellPrice,icon)
    {
        this.Attack = attack;
    }
}

消耗品类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Consumables :BaseItem {
    public int BackHP {
        get;
        private set;
    }
    public int BackMP {
        get;
        private set;
    }

    public Consumables(int id, string name, string description, int buyPrice, int sellPrice, string icon,int backHP,int backMP) : base(id, name, description, buyPrice, sellPrice, icon)
    {
        this.BackHP = backHP;
        this.BackMP = backMP;
    }
}

五、物品(预支物)之间的拖拽交换实现##

1.给预支物添加拖拽脚本,以及实现各种交换功能.
2.给格子,和预支物添加Tag值以便进行交换处理.
3.添加CanvasGroup防止射线检测正确的物体.

交换逻辑代码处理:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;
using System;

public class DragMove : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{

    GameObject PoolCanvas = null;//用来管理生成物体

    GameObject Instead_gameObject = null;//交换变量


    //交换物品,格子里面的信息
    BaseItem item;
    BaseItem itemInstead;


    void start()
    {
        PoolCanvas = GameObject.Find("Knapsack").transform.Find("PoolCanvas").gameObject;
        print(PoolCanvas.name+"123");
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (eventData.button==PointerEventData.InputButton.Left)
        {
            //格子里面信息处理
            item = StorItem.GetItem(transform.parent.name);
            StorItem.DeleteItem(transform.parent.name);


            //transform.SetParent(PoolCanvas.transform, true);
            transform.localScale = new Vector3(0.7f,0.7f,0.7f);
            Instead_gameObject = transform.parent.gameObject;
            transform.GetComponent<CanvasGroup>().blocksRaycasts = false;//给预支物添加CanvasGroup,防止出现物体检测不正确
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (eventData.button==PointerEventData.InputButton.Left)
        {
            GetComponent<RectTransform>().pivot.Set(0,0);
            transform.position = Input.mousePosition;
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        transform.localScale = new Vector3(1f, 1f, 1f);
        if (eventData.button==PointerEventData.InputButton.Left)//空格子之间的交换
        {
            if (eventData.pointerCurrentRaycast.gameObject.tag=="cell")
            {
                transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform);

                //处理格子信息
                StorItem.Store(eventData.pointerCurrentRaycast.gameObject.transform.name,item);
            }
            else if (eventData.pointerCurrentRaycast.gameObject.tag == "Item")//物品之间的交换
            {
                Transform transform_A = eventData.pointerCurrentRaycast.gameObject.transform;
                Transform transform_B_parent = transform_A.parent.transform;

                //处理格子信息
                itemInstead = StorItem.GetItem(eventData.pointerCurrentRaycast.gameObject.transform.parent.name);
                StorItem.DeleteItem(eventData.pointerCurrentRaycast.gameObject.transform.parent.name);

                transform_A.SetParent(Instead_gameObject.transform, true);
                transform_A.localPosition = Vector3.zero;

                //处理格子信息
                StorItem.Store(Instead_gameObject.transform.name,itemInstead);

                
                transform.SetParent(transform_B_parent);
                //处理格子信息
                StorItem.Store(transform_B_parent.name,item);

            }
            else
            {
                transform.SetParent(Instead_gameObject.transform,true);
                //处理格子信息
                StorItem.Store(Instead_gameObject.name,item);
            }
            transform.localPosition = Vector3.zero;
            transform.GetComponent<CanvasGroup>().blocksRaycasts = true;
        }
       
    }

}

六、对象池的应用###

1.在模拟按键拾取物品时,我们一直在Instantiate物品,并且Destory.这会对性能进行一个很大的消耗,那么我们通过对象池可以进行性能的提高。
2.回收方法一般通过协程调用。

对象池的2个方法:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoolManager : MonoBehaviour {

    private static Dictionary<string, ArrayList> pool = new Dictionary<string, ArrayList>();//字典承储信息

    public static Object Get(string prefabName,Vector3 position,Quaternion rotation)//获取方法
    {
        string key = prefabName + "(Clone)";
        Object obj;
        if (pool.ContainsKey(key) && pool[key].Count > 0)
        {
            ArrayList list = pool[key];
            obj = list[0] as Object;
            list.RemoveAt(0);
            if (obj == null)
            {
                obj = Instantiate(Resources.Load("Prefabs/" + prefabName), position, rotation);
            }
            (obj as GameObject).SetActive(true);
            (obj as GameObject).transform.position = position;
            (obj as GameObject).transform.rotation = rotation;
        }
        else
        {
            obj = Instantiate(Resources.Load("Prefabs/" + prefabName), position, rotation);
        }

        return obj;
    }



    public static Object Return(GameObject obj)//回收方法
    {
        string key = obj.name;
        if (pool.ContainsKey(key))
        {
            ArrayList list = pool[key];
            list.Add(obj);
        }
        else
        {
            pool[key] = new ArrayList { obj };

        }
        obj.SetActive(false);
        return obj;
    }
    
}

七、界面的延伸功能##

布局展示

八、物品的消耗,展示功能##

1.通过点击按键模拟消耗物品的功能.
2.物品功能通过KnapsackInfo面板上的展示.

预支物的处理
消耗处理脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


public class ConsumManager : MonoBehaviour,IPointerDownHandler {


    GameObject item;
    Text indexInt;
    int index;
   public GameObject PoolCanvas;

    void start()
    {
        PoolCanvas = GameObject.Find("Knapsack").transform.Find("PoolCanvas").gameObject;

    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (Input.GetMouseButtonDown(1))
        {
            indexInt=transform.GetChild(0).GetComponent<Text>();
            index = int.Parse(indexInt.text);
            if (index != 1)
            {
                index -= 1;
                indexInt.text = index.ToString();
            }
            else
            {
                item = eventData.pointerCurrentRaycast.gameObject;
                PoolManager.Return(item);
                StorItem.DeleteItem(item.transform.parent.name);
                
               //StartCoroutine(ReturnToPoll());
                //item.transform.SetParent(PoolCanvas.transform);
                //Destroy(item);
            }

           
        }
    }


    IEnumerator ReturnToPoll()
    {
        yield return new WaitForSeconds(0.0f);
        PoolManager.Return(item);
    }



}

展示处理信息脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ShowInfo : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler {

    Text ItemInfo;


    public void OnPointerEnter(PointerEventData eventData)
    {
        BaseItem item = StorItem.GetItem(eventData.pointerEnter.transform.parent.name);
       //ItemInfo.text=item.Description;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        
    }

    // Use this for initialization
    void Start () {

        ItemInfo = GameObject.Find("Bg").transform.Find("Info").gameObject.GetComponent<Text>();
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

九、承储数据,商店物品信息管理##

1.通过代码,承储显示面板上的信息。

商店代码处理.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class StorItem  {

    private static Dictionary<string,BaseItem> GridItem=new Dictionary<string,BaseItem>();//保存物品的仓库

    public static void Store(string name,BaseItem item)//保存处理
    {
        if (GridItem.ContainsKey(name))
        {
            GridItem.Add(name, item);
            return;
            
        }

    }

    public static void DeleteItem(string name)//删掉处理
    {
        if (GridItem.ContainsKey(name))
        {
            GridItem.Remove(name);
        }       
    }

    public static BaseItem GetItem(string name)//获取处理
    {
        if (GridItem.ContainsKey(name))
        {
            return GridItem[name];
        }
        else
        {
            return null;
        }
    }

}

总结##

1.对UGUI的控件有了更深入的了解学习.
2.对类的建立,处理有了进一步的认知.
3.对象池的了解及学习.
4.加强了自己的代码能力.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容