【NGUI】扩展NGUI例子实现拖动交换位置功能
大家在学习NGUI的时候有接触过这个例子吧?
图1 Example 11 - Drag & Drop
这个例子已经很全面的实现了拖动物体和放下物体到某处(3D或2D),为了更深入的理解这个例子,我们现在来学习并扩展这个例子。
- 需求:有六张卡牌,拖动任意一张卡牌到相应的另一张卡牌位置上,可以自动进行两张卡牌的位置调换。
- 分析:通过这个例子,我们虽然可以拖出物体放置到另一个地方,但是不会和任何物体位置调换,所以我们要适当的扩展相应的代码。
- 思路:根据需求,首先我们需要有六张卡牌在Grid下,并且是按一定的编号顺序排列好的,存放在一个List中。然后拖动其中任意一张卡牌到任意位置,如果碰撞器没有Trigger到其他牌,则按原来的List排序顺序排序。反之Trigger到了其他牌,则交换他们的编号,重新排序List,就可以实现交换的效果了。
- 实现:
首先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.****.net/detail/yangyy753/8696945
Ricky Yang个人原创,版权所有。转载地址:http://blog.****.net/yangyy753/article/details/45698785