21UGUI背包系统

一、UGUI背包系统展示##

UGUI背包展示

二、背包系统的搭建##

21UGUI背包系统_第1张图片
背包格子的搭建成功

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

21UGUI背包系统_第2张图片
预支物的制作
通过按键模拟拾取物品的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class KnapsackManager : MonoBehaviour
{

    public static Dictionary 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();
        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();//获取实例化物体的图片信息
        //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().overrideSprite.name)
                {
                    isFind = true;
                    textNum = Cells[i].transform.GetChild(0).transform.GetChild(0).GetComponent();
                    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().blocksRaycasts = false;//给预支物添加CanvasGroup,防止出现物体检测不正确
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (eventData.button==PointerEventData.InputButton.Left)
        {
            GetComponent().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().blocksRaycasts = true;
        }
       
    }

}

六、对象池的应用###

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

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

public class PoolManager : MonoBehaviour {

    private static Dictionary pool = new Dictionary();//字典承储信息

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

七、界面的延伸功能##

21UGUI背包系统_第3张图片
布局展示

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

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

21UGUI背包系统_第4张图片
预支物的处理
消耗处理脚本:
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();
            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();
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

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

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

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


public class StorItem  {

    private static Dictionary GridItem=new Dictionary();//保存物品的仓库

    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.加强了自己的代码能力.

你可能感兴趣的:(21UGUI背包系统)