【UGUI】背包案例(五)

本文详细介绍了一个背包系统的逻辑处理和Unity实现过程,包括道具整理、购买、出售和丢弃等功能。通过使用委托事件和UI交互,实现了背包内道具的智能管理和玩家与背包的互动。

这篇博客主要实现功能:背包整理、道具购买、出售、丢弃

这边博客基本上都是逻辑处理,每个人思路不同,如果看的有点懵之类,完全可以自己整理思路来写,没有功能性的代码,所以看不懂也不用担心,在这个系列完结后,我会附上原工程文件

这篇大部分都是逻辑代码,这个类就挂在背包得Panel下就可以了

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public delegate void KnapsackEvent(GameObject tager);


public class Knapsack : MonoBehaviour
{
    /// <summary>
    /// 道具预制件
    /// </summary>
    public GameObject prpoPre;

    public Text money;
    /// <summary>
    /// 整理
    /// </summary>
    public Button b_clearUp;
    /// <summary>
    /// 出售
    /// </summary>
    public Button b_sell;
    /// <summary>
    /// 丢弃
    /// </summary>
    public Button b_discard;

    /// <summary>
    /// 格子的父节点
    /// </summary>
    public Transform content;

    /// <summary>
    /// 记录所有格子
    /// </summary>
    private List<Grid> grids;
    /// <summary>
    /// 记录所有装备
    /// </summary>
    private List<Prpo> prpos;
    // Use this for initialization
    void Start()
    {
        grids = new List<Grid>();
        grids.AddRange(content.GetComponentsInChildren<Grid>());


        b_clearUp.onClick.AddListener(delegate { ClearUp(); });

        Prpo.onSell += Sell;
        Prpo.onBuy += Buy;
        Prpo.onDiscard += Discard;
    }

    private void OnDestroy()
    {
        Prpo.onSell -= Sell;
        Prpo.onBuy -= Buy;
        Prpo.onDiscard -= Discard;
    }
    /// <summary>
    /// 整理背包
    /// </summary>
    public void ClearUp()
    {
        //先获取背包下所有的道具
        prpos = new List<Prpo>();
        prpos.AddRange(content.GetComponentsInChildren<Prpo>());

        //先将背包格子清空
        foreach (var item in prpos)
        {
            item.transform.SetParent(PrpoManager.instance.m_canvas.transform);
            //Debug.Log("parent" + item.transform.parent);
        }
        //Debug.Log("背包已清空");

        //将已经整理好的物品存起来,用来和未存放的道具对比,如果道具相同就合并
        List<Prpo> storeprpos = new List<Prpo>();
        //存储需要合并的道具,数字相加,多余的Image就删掉
        List<Prpo> deleteprpos = new List<Prpo>();
        //Debug.Log("prpos.Count"+ prpos.Count);
        for (int i = 0; i < prpos.Count; i++)
        {
            
            if (i == 0)
            {
                prpos[i].transform.SetParent(grids[i].transform);
                storeprpos.Add(prpos[i]);
                //Debug.Log("grids[0].transform.childCount" + grids[i].transform.childCount);
            }
            else
            {
                //Debug.Log("grids[i].transform.childCount" + grids[i].transform.childCount);
                
                //Debug.Log("storeprpos.count" + storeprpos.Count);
                bool iscanadd = true;
                foreach (var item in storeprpos)
                {
                    if (item.GetComponent<Image>().sprite == prpos[i].GetComponent<Image>().sprite)
                    {
                       
                        Merge(item.transform, prpos[i].transform);
                        deleteprpos.Add(prpos[i]);
                        iscanadd = false;
                        break;
                    }
                }
                if (iscanadd)
                {
                    Debug.Log(i);
                    prpos[i].transform.SetParent(grids[storeprpos.Count].transform);
                    storeprpos.Add(prpos[i]);
                }

            }
        }
        foreach (var item in storeprpos)
        {
            item.transform.localPosition = Vector3.zero;
        }
        for (int i = 0; i < deleteprpos.Count; i++)
        {
            Destroy(deleteprpos[i].gameObject);

        }
    }

    public void Sell(GameObject tager)
    {
        //得到道具数量
        int t_number = int.Parse(tager.GetComponentInChildren<Text>().text);
        //得到道具id
        int t_id = int.Parse(tager.GetComponent<Image>().sprite.name);
        //获取它的价格
        int price = PrpoManager.instance.prpos[t_id].p_price;
        //售价等于原价的40%,舍弃小数点
        price = (int)(price * 0.4f);
        //售价乘以数量
        money.text = (int.Parse(money.text) + price * t_number).ToString();
        //售出后销毁
        Destroy(tager);

    }

    public void Discard(GameObject tager)
    {
        Destroy(tager);
    }

    public void Buy(GameObject tager)
    {
    	//先获取背包下所有的道具
        prpos = new List<Prpo>();
        prpos.AddRange(content.GetComponentsInChildren<Prpo>());

        if (prpos.Count>= grids.Count)//背包满了
        {
	        tager.GetComponent<Prpo>().ResetPoint();
            return;
        }
        //得到道具id
        int t_id = int.Parse(tager.GetComponent<Image>().sprite.name);
        //获得价格
        int price = PrpoManager.instance.prpos[t_id].p_price;
        //如果余额不够,就返回
        if (int.Parse(money.text) < price)
        {
	        tager.GetComponent<Prpo>().ResetPoint();
            return;
        }

        foreach (var item in grids)
        {
            if (item.transform.childCount == 0)
            {
                GameObject game = Instantiate(prpoPre);
                game.transform.SetParent(item.transform);
                game.GetComponent<Image>().sprite = PrpoManager.instance.prpos[t_id].p_sprite;
                break;
            }
        }
        money.text = (int.Parse(money.text) - price).ToString();
        tager.GetComponent<Prpo>().ResetPoint();

    }

    /// <summary>
    /// 添加道具
    /// </summary>
    /// <param name="id"></param>
    public void AddPrpo(int id)
    {
        foreach (var item in grids)
        {
            if (item.transform.childCount == 0)
            {
                GameObject game = Instantiate(prpoPre);
                game.transform.SetParent(item.transform);
                game.GetComponent<Image>().sprite = PrpoManager.instance.prpos[id].p_sprite;
                break;
            }
        }
    }
    /// <summary>
    /// 合并
    /// </summary>
    /// <param name="tager"></param>
    private void Merge(Transform tager1, Transform tager2)
    {
        int quantity = int.Parse(tager1.GetComponentInChildren<Text>().text) + int.Parse(tager2.GetComponentInChildren<Text>().text);
        tager1.GetComponentInChildren<Text>().text = quantity.ToString();
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这个Prpo类也新增了代码:委托事件,Prpo这边触发后会,上面得Knapsack会接收到信息,做出对应得操作,最后的道具信息显示没我也会用委托事件来写

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class Prpo : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    Grid.GridType prpoType;
    /// <summary>
    /// 出售
    /// </summary>
    public static event KnapsackEvent onSell;
    /// <summary>
    /// 丢弃
    /// </summary>
    public static event KnapsackEvent onDiscard;
    /// <summary>
    /// 购买
    /// </summary>
    public static event KnapsackEvent onBuy;

    void Start()
    {
        m_image = GetComponent<Image>();

        prpoType = GetComponentInParent<Grid>().gridType;
    }
    /// <summary>
    /// 自身的Image组件
    /// </summary>
    Image m_image;
    /// <summary>
    /// 记录偏移量
    /// </summary>
    Vector3 offset;
    /// <summary>
    /// 记录父节点
    /// </summary>
    Transform parent;
    /// <summary>
    /// 是否在拖拽
    /// </summary>
    bool isDrag;

    /// <summary>
    /// IBeginDragHandler,开始拖拽
    /// </summary>
    /// <param name="eventData"></param>
    public void OnBeginDrag(PointerEventData eventData)
    {
        //计算鼠标位置和UI位置的偏移量
        offset = Input.mousePosition - transform.position;
        //记录下道具拖拽前的所属格子,在拖拽功能不满足时,复位在此节点
        parent = transform.GetComponentInParent<Grid>().transform;
        //将父物体设置为Canvas,这是UI在层级列表最下面,不会被别的UI挡住;
        transform.SetParent(PrpoManager.instance.m_canvas.transform);
        isDrag = true;
    }
    /// <summary>
    /// IDragHandler,拖拽中
    /// </summary>
    /// <param name="eventData"></param>
    public void OnDrag(PointerEventData eventData)
    {
        //拖拽中,UI位置等于鼠标位置加上偏移量
        transform.position = Input.mousePosition - offset;
        //将UI设置为可穿透,这样鼠标就不会被挡住,可以获得我们目标位置的信息
        m_image.raycastTarget = false;

    }
    /// <summary>
    /// IEndDragHandler,拖拽结束
    /// </summary>
    /// <param name="eventData"></param>
    public void OnEndDrag(PointerEventData eventData)
    {
        isDrag = false;
        m_image.raycastTarget = true;

        //目标位置信息获取
        GameObject tager = eventData.pointerEnter;
        //目标位置为空
        if (!tager)
        {
            //复位
            ResetPoint();
            return;
        }
        //目标位置既不是空位,也不是道具
        else if (!tager.GetComponent<Prpo>() && !tager.GetComponent<Grid>())
        {
            if (prpoType!=Grid.GridType.SHOP)
            {
                //Debug.Log(111+ tager.name);
                if (tager.name == "出售")
                {
                    onSell(gameObject);
                    return;
                }
                else if (tager.name == "丢弃")
                {
                    onDiscard(gameObject);
                }
            }
            //复位
            ResetPoint();
            return;
        }

        //目标点为道具
        else if (tager.GetComponent<Prpo>())
        {
            //属于同一界面的道具
            if (prpoType == tager.GetComponent<Prpo>().prpoType)
            {
                if (prpoType == Grid.GridType.KNAPSACK)
                {
                    //道具相同
                    if (tager.GetComponent<Image>().sprite == GetComponent<Image>().sprite)
                    {
                        Merge(tager.transform);
                    }
                    else
                    {
                        Interchange(tager.transform);
                    }
                }
                else
                {
                    ResetPoint();
                }
            }
            else
            {
                switch (prpoType)
                {
                    case Grid.GridType.KNAPSACK:
                        if (tager.GetComponent<Prpo>().prpoType == Grid.GridType.SHOP)
                        {
                            onSell(gameObject);
                            //出售
                        }
                        else if (tager.GetComponent<Prpo>().prpoType == Grid.GridType.PLAYER)
                        {
                            //判断是否可以装备
                        }
                        break;
                    case Grid.GridType.SHOP:
                        //购买
                        onBuy(gameObject);
                        break;
                    case Grid.GridType.PLAYER:
                        //脱下,并且排序到背包各自中
                        break;
                    default:
                        break;
                }
            }
        }

        //目标点为格子
        else if (tager.GetComponent<Grid>())
        {
            //属于同一界面的道具
            if (prpoType == tager.GetComponent<Grid>().gridType)
            {
                if (prpoType == Grid.GridType.KNAPSACK)
                {
                    if (tager.transform.childCount == 0)
                    {
                        transform.SetParent(tager.transform);
                        transform.localPosition = Vector3.zero;
                    }
                    //格子下本身有道具
                    else
                    {
                        tager = tager.transform.GetChild(0).gameObject;
                        if (tager.GetComponent<Image>().sprite == GetComponent<Image>().sprite)
                        {
                            Merge(tager.transform);
                        }
                        else
                        {
                            Interchange(tager.transform);
                        }
                    }
                }
                else
                {
                    ResetPoint();
                }
            }
            else
            {
                switch (prpoType)
                {
                    case Grid.GridType.KNAPSACK:

                        if (tager.GetComponent<Grid>().gridType == Grid.GridType.SHOP)
                        {
                            onSell(gameObject);
                            //出售
                        }
                        else if (tager.GetComponent<Grid>().gridType == Grid.GridType.PLAYER)
                        {
                            //判断是否可以装备
                        }
                        break;
                    case Grid.GridType.SHOP:
                        //购买
                        onBuy(gameObject);
                        break;
                    case Grid.GridType.PLAYER:
                        //脱下,并且排序到背包各自中
                        break;
                    default:
                        break;
                }
            }
        }

        else
        {
            ResetPoint();
        }
    }

    /// <summary>
    /// 复位,返回原格子下
    /// </summary>
    public void ResetPoint()
    {
        transform.SetParent(parent);

        transform.localPosition = Vector3.zero;

        transform.localScale = Vector3.one;
    }
    /// <summary>
    /// 交换位置
    /// </summary>
    private void Interchange(Transform tager)
    {
        transform.SetParent(tager.transform.parent);
        transform.localPosition = Vector3.zero;
        tager.transform.SetParent(parent);
        tager.transform.localPosition = Vector3.zero;
        parent = transform.parent;
    }
    /// <summary>
    /// 合并
    /// </summary>
    /// <param name="tager"></param>
    private void Merge(Transform tager)
    {
        int quantity = int.Parse(GetComponentInChildren<Text>().text) + int.Parse(tager.GetComponentInChildren<Text>().text);
        tager.GetComponentInChildren<Text>().text = quantity.ToString();
        Destroy(gameObject);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贪小心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值