背包系统我们知道,大致上就是很多个格子,最基础的功能是,我们可以把格子1的东西拖动到格子2中,这次来讲一下这个最基础的功能实现的原理。
首先在场景中放入两个image,调成了红色和蓝色便于区分。
我们要实现什么效果呢:
按住方块,就可以拖动方块到任意位置。松手,方块的位置就不动了。
首先做一点基础设置
点击Canvas
修改一下Canvas Scaler。
点击镜头窗口,设置画面的比例和Canvas中设置成一致。
这些设置,在本次示范中不是那么重要,但是在项目中,很重要!
这些东西如果不统一设置,在对UI进行操作的时候就会时有时无的出现奇怪的BUG。
新创建一个脚本,挂在Canvas上
这里canvas相当于一个看不见的背包,在这个背包下放入了两个image。
上代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
GameObject go;
public void OnBeginDrag(PointerEventData eventData)
{
go = eventData.pointerCurrentRaycast.gameObject;
Debug.Log("开始拖动");
}
public void OnDrag(PointerEventData eventData)
{
if (go != null)
{
go.transform.position = Input.mousePosition;
Debug.Log(" 拖动 ");
}
}
public void OnEndDrag(PointerEventData eventData)
{
go = null;
Debug.Log(" 结束拖动 ");
}
}
解读一下代码
1.引用UnityEngine.EventSystems 目的是继承 IBeginDragHandler, IDragHandler, IEndDragHandler三个接口。这三个接口的大致意思就是,在开始拖动时,在拖动中,在结束拖动时,做什么事情。
2.eventData.pointerCurrentRaycast.gameObject; 获取拖动的对象,即光标当前所对着的gameobject
可以不勾选image中的raycast target,使此方法获取不到这个image。
即如果说你只想一个物品有拖动功能,另一个物品没有,那么你可以修改raycast target的值,也可以将脚本只挂在想要拖动的物品上。
3.这段代码大致的逻辑是
创建一个对象go
OnBeginDrag获取要拖动的对象赋值给go
OnDrag使go的坐标与光标坐标一致
OnEndDrag,拖动结束,将go清空
有的同学一眼看出:这实现拖动需要这么多逻辑吗,只取OnDrag那一小段不行吗?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript : MonoBehaviour, IDragHandler
{
public void OnDrag(PointerEventData eventData)
{
eventData.pointerCurrentRaycast.gameObject.transform.position = Input.mousePosition;
Debug.Log(" 拖动 ");
}
}
这样的话。确实也可以实现拖动的效果,但是如果鼠标滑动的稍稍快一点,就会报空指针异常。
因为你鼠标没有松手,此时还在OnDrag的方法中,但是一帧的时间光标从图片上直接划到了图片外,此时eventdata获取不到图片,就会报错了。