当前位置: 首页 > article >正文

麦田物语学习笔记:创建DragItem实现物品的拖拽跟随显示

基本流程

1.代码思路

        (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)

2.代码实现

        在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);
}

最终效果

        实现拖拽;松开后消失;被选中物品高亮,相关控制台输出看上面的思路

补充知识点

1.IBeginDragHandler,IDragHandler,IEndDragHandler这三个接口

 IBeginDragHandler 接口

  • 概述
    • IBeginDragHandler是在 Unity 的新输入系统(Input System)中用于处理拖动操作开始阶段的接口。当用户开始拖动一个对象(例如,通过鼠标按下并开始移动,或者在触摸屏幕后开始移动手指)时,实现了这个接口的脚本中的相关方法会被调用。
  • 方法和作用
    • 它主要包含OnBeginDrag方法。这个方法接收一个DragEventArgs类型的参数。例如,在一个简单的 Unity 场景中,如果你有一个可拖动的 UI 元素,当用户开始拖动这个元素时,OnBeginDrag方法可以用来记录拖动开始的位置、获取被拖动对象的初始状态等操作。
  • 应用场景
    • 适用于需要在拖动开始时进行初始化操作的情况。比如在一个纸牌游戏中,当玩家开始拖动一张纸牌,你可以在OnBeginDrag方法中记录纸牌的原始位置,设置一些标记来表示这张纸牌正在被拖动,防止其他操作(如自动整理纸牌)的干扰等。

 IDragHandler 接口

  • 概述
    • IDragHandler接口用于处理拖动操作的持续过程。在用户开始拖动(IBeginDragHandlerOnBeginDrag方法被调用后)并且手指或者鼠标还在移动的过程中,这个接口中的方法会不断被调用。
  • 方法和作用
    • 它包含OnDrag方法,同样接收PointerEventData类型的参数。在这个方法中,可以根据拖动过程中的位置变化来更新被拖动对象的位置。
  • 应用场景
    • 广泛应用于各种拖动交互场景。比如在一个绘图应用中,当用户拖动画笔工具时,通过OnDrag方法可以在屏幕上绘制线条,线条的路径根据OnDrag方法中获取的拖动位置来确定;在一个文件管理应用中,拖动文件图标在文件夹之间移动时,OnDrag方法可以用来更新文件图标的位置显示,直到拖动操作结束。

 IEndDragHandler 接口

  • 概述
    • IEndDragHandler接口用于处理拖动操作的结束阶段。当用户松开鼠标按钮或者抬起手指,结束拖动操作时,这个接口中的方法会被调用。
  • 方法和作用
    • 主要的方法是OnEndDrag,参数也是PointerEventData类型。在这个方法中,可以进行拖动结束后的清理工作,比如将被拖动对象放置到合适的位置、检查是否放置到了有效的目标区域等
  • 应用场景
    • 例如在一个拼图游戏中,当玩家拖动拼图块到正确的位置并松开时,OnEndDrag方法可以检查拼图块是否放置正确,如果正确则将拼图块固定在该位置,否则将其返回原来的位置;在一个拖放文件到回收站的场景中,OnEndDrag方法可以判断文件图标是否被拖放到回收站图标区域内,如果是则执行删除文件的操作,否则不做任何操作。

 

2.Image组件

详情看这篇文章 

        这里主要用到其中的Raycast Target,在勾选的情况下会阻止鼠标的射线判断,所以要去掉勾选

 

3.关于 eventData.pointerCurrentRaycast.gameObject 的一些说明   

(1)工作原理
  • pointerCurrentRaycast:这是 Unity 的 PointerEventData 提供的一个属性,用于获取当前指针(如鼠标或触摸)射线检测到的结果。
  • 射线检测的范围
    • 该射线检测是基于 UI 系统的,因此它只会检测当前场景中 UI 元素(如 Canvas 下的 ButtonImage 等)。
    • 如果指针指向的是非 UI 的游戏对象(如 3D 场景中的物体),则 pointerCurrentRaycast 不会检测到这些对象。
(2) 检测是否仅限于当前场景的 GameObject
  • 仅限于当前场景的 UI 元素

    • 该检测只会对当前场景中 UI 系统 下的 GameObject 生效。
    • 如果当前场景中有多个 Canvas,且这些 Canvas 都启用了射线检测(Raycast Target),则这些 Canvas 下的 UI 元素都会被检测到。
    • 如果指针指向的是非 UI 的游戏对象(如 3D 模型),则不会被检测到。
  • 跨场景检测

    • 如果当前场景中有多个场景叠加(例如通过 DontDestroyOnLoad 保留的场景),且这些场景中有 UI 元素,则这些 UI 元素也会被检测到。
    • 但如果指针指向的是其他场景中的非 UI 对象,则不会被检测到。

 

 4.Raycast Target详解

  1. 定义
    • 在 Unity 中,Raycast Target是一个与 UI(用户界面)元素相关的重要属性。它主要用于图形射线投射。简单来说,当你有一个射线(例如鼠标点击产生的射线或者通过代码发射的射线)时,Unity 会检查哪些对象具有Raycast Target属性被启用,以确定射线是否 “击中” 了这些对象。
  2. 工作原理
    • 当你在屏幕上进行交互操作(如点击鼠标)时,Unity 会从摄像机向屏幕上的点击位置发射一条射线。这条射线会遍历场景中的所有具有Raycast Target属性的对象。如果射线与一个带有Raycast Target属性且该属性被启用的 UI 元素相交,那么这个 UI 元素就会接收到相关的事件消息,例如OnPointerClickOnPointerDown等。
    • 以一个简单的游戏界面为例,假设有一个按钮和一个文本框。如果按钮的Raycast Target属性被启用,而文本框的被禁用。当你点击按钮所在的位置时,按钮会响应点击事件,因为射线可以 “击中” 它;而点击文本框所在位置时,由于其Raycast Target被禁用,它不会响应点击事件。
  3. 应用场景
    • 按钮交互:对于 UI 按钮,Raycast Target属性通常是启用的。这样,当玩家点击按钮时,按钮能够接收点击事件并执行相应的操作,如打开一个菜单、触发一段动画或者执行一个游戏逻辑功能。
    • 选择 UI 元素:在制作游戏菜单或者库存系统时,通过射线投射来确定玩家选择了哪个 UI 元素。例如,在一个装备选择界面中,每个装备图标都有Raycast Target属性,玩家可以通过鼠标点击(射线投射)来选择装备。
  4. 性能考虑
    • 过多地启用Raycast Target属性可能会影响性能。因为每一次射线投射都需要检查所有启用了该属性的对象。在一个复杂的 UI 场景中,如果有大量不必要的 UI 元素都开启了Raycast Target,会增加射线投射的计算量。所以,在实际开发中,对于那些不需要响应射线投射事件的 UI 元素,应该将Raycast Target属性关闭,以提高性能。例如,对于只是用于显示信息的静态文本标签,通常可以禁用Raycast Target,因为它们不需要响应点击等交互事件。

http://www.kler.cn/a/488314.html

相关文章:

  • Lua语言中常用的字符串操作函数
  • Vue 环境配置与项目创建指南
  • tdengine数据库使用java连接
  • VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署
  • Huawei Cloud EulerOS上安装sshpass
  • Flutter:打包apk,安卓版本更新(二)
  • 【Flutter】使用ScrollController配合EasyRefresh实现列表预加载:在还未滑动到底部时加载下一页数据
  • 图像传感器的视觉演变与创新
  • Unity自定义编辑器:基于枚举类型动态显示属性
  • sql 函数
  • 联邦大语言模型典型系统: FATE - LLM、FedLLM、FederatedScope - LLM、PrimiHub
  • 【Flink】flink或java异常日志输出不完整问题解决
  • 10步打造完美ASP.NET、Web API和控制台应用程序文件夹结构
  • C语言:构造类型(共用体/联合体,枚举)
  • Apache AGE:基于PostgreSQL的图数据库深度解析
  • Python--正则表达式
  • HarmonyOS开发:粒子动画应用实战
  • pytest 常用插件
  • Redis数据库笔记——Redis快的原因
  • Java(day7)
  • HTTP 与 HTTPS 网络传输
  • Linux -- 初步了解 TCP 编程
  • ubuntu 20.04 安装 5.4 内核
  • CClinkIEfield Basic转Modbus TCP网关模块连接三菱FX5U PLC
  • 关于物联网的基础知识(四)——国内有代表性的物联网平台都有哪些?
  • xml-dota-yolo数据集格式转换