(1)在SlotUI中使用拖拽接口IBeginDragHandler,IDragHandler,IEndDragHandler
(2)开始拖拽的时候,在屏幕上生成物体,拖拽期间物体显示为当前被拖拽的物体的图标,停止拖拽时图标消失
(3)基于以上,所以我们要获得这个图标的控制,则要去InventoryUI里获得
(4)在停止拖拽的时候检测该位置所对应的GameObject,值得注意的是,这个检测只检测UI元素;之后在代码实现后只能检测到所处格子的TMP,控制台会如下打印.
Amount (UnityEngine.GameObject)
这时就是没有检测到Slot_Bag的对象,原因是因为预制体Slot_Bag的三个子对象都没有解除对鼠标射线检测的限制(Raycast Target),取消后就能正常检测了,输出如下
Slot_Bag (3) (UnityEngine.GameObject)
在InventoryUI中添加变量
[Header("拖拽图片")]
public Image dragItem;
在SlotUI中添加拖拽相关接口
public class SlotUI : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
实现接口
public void OnBeginDrag(PointerEventData eventData)
{
//先判断这个格子能不能被拖拽
if (itemAmount == 0) return;
inventoryUI.dragItem.enabled = true;
inventoryUI.dragItem.sprite = slotImage.sprite;
//防止图片分辨率不一,导致畸变
inventoryUI.dragItem.SetNativeSize();
//提示拖拽的是哪一个
isSelected = true;
inventoryUI.UpdateSlotHightlight(slotIndex);
}
public void OnDrag(PointerEventData eventData)
{
inventoryUI.dragItem.transform.position = Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData)
{
inventoryUI.dragItem.enabled = false;
Debug.Log(eventData.pointerCurrentRaycast.gameObject);
}
实现拖拽;松开后消失;被选中物品高亮,相关控制台输出看上面的思路
IBeginDragHandler 接口
IBeginDragHandler
是在 Unity 的新输入系统(Input System)中用于处理拖动操作开始阶段的接口。当用户开始拖动一个对象(例如,通过鼠标按下并开始移动,或者在触摸屏幕后开始移动手指)时,实现了这个接口的脚本中的相关方法会被调用。OnBeginDrag
方法。这个方法接收一个DragEventArgs
类型的参数。例如,在一个简单的 Unity 场景中,如果你有一个可拖动的 UI 元素,当用户开始拖动这个元素时,OnBeginDrag
方法可以用来记录拖动开始的位置、获取被拖动对象的初始状态等操作。OnBeginDrag
方法中记录纸牌的原始位置,设置一些标记来表示这张纸牌正在被拖动,防止其他操作(如自动整理纸牌)的干扰等。IDragHandler 接口
IDragHandler
接口用于处理拖动操作的持续过程。在用户开始拖动(IBeginDragHandler
的OnBeginDrag
方法被调用后)并且手指或者鼠标还在移动的过程中,这个接口中的方法会不断被调用。OnDrag
方法,同样接收PointerEventData
类型的参数。在这个方法中,可以根据拖动过程中的位置变化来更新被拖动对象的位置。OnDrag
方法可以在屏幕上绘制线条,线条的路径根据OnDrag
方法中获取的拖动位置来确定;在一个文件管理应用中,拖动文件图标在文件夹之间移动时,OnDrag
方法可以用来更新文件图标的位置显示,直到拖动操作结束。IEndDragHandler 接口
IEndDragHandler
接口用于处理拖动操作的结束阶段。当用户松开鼠标按钮或者抬起手指,结束拖动操作时,这个接口中的方法会被调用。OnEndDrag
,参数也是PointerEventData
类型。在这个方法中,可以进行拖动结束后的清理工作,比如将被拖动对象放置到合适的位置、检查是否放置到了有效的目标区域等OnEndDrag
方法可以检查拼图块是否放置正确,如果正确则将拼图块固定在该位置,否则将其返回原来的位置;在一个拖放文件到回收站的场景中,OnEndDrag
方法可以判断文件图标是否被拖放到回收站图标区域内,如果是则执行删除文件的操作,否则不做任何操作。
详情看这篇文章
这里主要用到其中的Raycast Target,在勾选的情况下会阻止鼠标的射线判断,所以要去掉勾选
eventData.pointerCurrentRaycast.gameObject 的一些说明
pointerCurrentRaycast
:这是 Unity 的 PointerEventData
提供的一个属性,用于获取当前指针(如鼠标或触摸)射线检测到的结果。Canvas
下的 Button
、Image
等)。pointerCurrentRaycast
不会检测到这些对象。仅限于当前场景的 UI 元素:
GameObject
生效。Canvas
,且这些 Canvas
都启用了射线检测(Raycast Target
),则这些 Canvas
下的 UI 元素都会被检测到。跨场景检测:
DontDestroyOnLoad
保留的场景),且这些场景中有 UI 元素,则这些 UI 元素也会被检测到。
Raycast Target
是一个与 UI(用户界面)元素相关的重要属性。它主要用于图形射线投射。简单来说,当你有一个射线(例如鼠标点击产生的射线或者通过代码发射的射线)时,Unity 会检查哪些对象具有Raycast Target
属性被启用,以确定射线是否 “击中” 了这些对象。Raycast Target
属性的对象。如果射线与一个带有Raycast Target
属性且该属性被启用的 UI 元素相交,那么这个 UI 元素就会接收到相关的事件消息,例如OnPointerClick
、OnPointerDown
等。Raycast Target
属性被启用,而文本框的被禁用。当你点击按钮所在的位置时,按钮会响应点击事件,因为射线可以 “击中” 它;而点击文本框所在位置时,由于其Raycast Target
被禁用,它不会响应点击事件。Raycast Target
属性通常是启用的。这样,当玩家点击按钮时,按钮能够接收点击事件并执行相应的操作,如打开一个菜单、触发一段动画或者执行一个游戏逻辑功能。Raycast Target
属性,玩家可以通过鼠标点击(射线投射)来选择装备。Raycast Target
属性可能会影响性能。因为每一次射线投射都需要检查所有启用了该属性的对象。在一个复杂的 UI 场景中,如果有大量不必要的 UI 元素都开启了Raycast Target
,会增加射线投射的计算量。所以,在实际开发中,对于那些不需要响应射线投射事件的 UI 元素,应该将Raycast Target
属性关闭,以提高性能。例如,对于只是用于显示信息的静态文本标签,通常可以禁用Raycast Target
,因为它们不需要响应点击等交互事件。