【NGUI】扩展NGUI例子实现拖动交换位置功能

3 篇文章 0 订阅

大家在学习NGUI的时候有接触过这个例子吧?

 

图1 Example 11 - Drag & Drop

这个例子已经很全面的实现了拖动物体和放下物体到某处(3D或2D),为了更深入的理解这个例子,我们现在来学习并扩展这个例子。

  1. 需求:有六张卡牌,拖动任意一张卡牌到相应的另一张卡牌位置上,可以自动进行两张卡牌的位置调换。
  2. 分析:通过这个例子,我们虽然可以拖出物体放置到另一个地方,但是不会和任何物体位置调换,所以我们要适当的扩展相应的代码。
  3. 思路:根据需求,首先我们需要有六张卡牌在Grid下,并且是按一定的编号顺序排列好的,存放在一个List中。然后拖动其中任意一张卡牌到任意位置,如果碰撞器没有Trigger到其他牌,则按原来的List排序顺序排序。反之Trigger到了其他牌,则交换他们的编号,重新排序List,就可以实现交换的效果了。
  4. 实现:

首先Copy一份UIGrid.cs的代码,重命名为XUIGrid.cs,我们自定义三个参数,分别为:

    public int maxNum = 6;  //最大数量
    public int maxPerLine = 3;  //每行最大数量
    [HideInInspector]
    public string dragName; //当前拖动的排序名称
    [HideInInspector]
    public string replaceName;  //需要替换的排序名称
    protected List<int> listData = new List<int>();    //排序数据

在Init()方法中初始化listData的数据:

    protected virtual void Init()
    {
        //排序编号
        if (!mInitDone)
        {
            for (int i = 0; i < maxNum; i++)
            {
                listData.Add(i);
            }
            mInitDone = true;
        }
    }

新增一个可以处理交换位置的Sort方法,供每次重新排序时调用,即GetChildList()方法:

    protected void Sort(List<Transform> list)
    {
        if (!string.IsNullOrEmpty(dragName) && !string.IsNullOrEmpty(replaceName))
        {
            int dragNo = listData.IndexOf(int.Parse(dragName));    //根据当前排序名字获取服务器数据存储List中的位置
            int replaceNo = listData.IndexOf(int.Parse(replaceName));
            //替换List位置
            Transform tempList = list[replaceNo];
            list[replaceNo] = list[dragNo];
            list[dragNo] = tempList;
        }
    }

交换完成后我们还要保证listData中存储最新的排序方式,不然下次再交换会导致交换不正确。在ResetPosition()方法的末尾加上如下代码:

    if (list.Count > 0 && t != null)
    {
        SavePos(list);
    }

SavePos()方法:

    void SavePos(List<Transform> list)
    {
        listData.Clear();
        for (int i = 0; i < list.Count; i++)
        {
            listData.Add(int.Parse(list[i].name));
        }
    }

这里我们的XUIGrid已经实现得差不多了,现在我们修改一下UIDragDropItem.cs,我们也Copy一份出来,重命名为XUIDragDropItem.cs

首先,我们要获取当前拖动的卡牌编号,即在OnDragDropStart()方法中给XUIGrid的dragName赋值:

        mGrid = NGUITools.FindInParents<XUIGrid>(mParent);
        if (mGrid != null)
        {
            mGrid.dragName = mTrans.name;
        }

然后,在OnDragDropRelease()中调用XUIGrid的repositionNow=true

        mGrid = NGUITools.FindInParents<XUIGrid>(mParent);
        if (mGrid != null) mGrid.repositionNow = true;

最后,就是OnTriggerEnter方法的处理,把当前卡牌和目标卡牌编号传递给XUIGrid。

    void OnTriggerEnter(Collider other)
    {
        mGrid = NGUITools.FindInParents<XUIGrid>(mTrans.parent);
        if (mGrid != null)
        {
            mGrid.dragName = gameObject.name;
            mGrid.replaceName = other.name;
        }
    }

下面来看看测试效果~

 

 

 

本例子实例项目下载地址:http://download.csdn.net/detail/yangyy753/8696945


Ricky Yang个人原创,版权所有,转载请注明,谢谢。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ricky_yyy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值