For the complete documentation index, see llms.txt. This page is also available as Markdown.

鼠标移动

实时响应玩家的鼠标移动,以实现拖拽手势、旋转物体或控制自定义摄像机。

你的场景可以在每一帧读取玩家原始的鼠标移动,并将其用于驱动实时交互:拖拽和滑动手势、在玩家拖动时旋转或滑动物体,或者像第一人称射击游戏那样控制自定义相机。

要执行此操作,请读取 screenDelta 的属性 PrimaryPointerInfo 组件上的 engine.RootEntity。此属性是一个 Vector2 ,用于报告鼠标自上一帧以来移动了多少像素。正 x 值表示鼠标向右移动,正 y 值表示它向下移动,与屏幕左上角为原点一致——与 UiTransform 和 UiCanvasInformation。当鼠标不移动的帧上,这两个值都为 0。

import { engine, PrimaryPointerInfo } from '@dcl/sdk/ecs'

engine.addSystem(() => {
	const delta = PrimaryPointerInfo.getOrNull(engine.RootEntity)?.screenDelta
	if (!delta) return
	console.log(`mouse moved: ${delta.x}, ${delta.y}`)
})

由于 screenDelta 只保存单帧的移动,因此务必在 系统中读取它,这样就不会有任何移动在帧与帧之间被漏掉。

光标锁定时的鼠标移动

screenDelta 与 PrimaryPointerInfo 在光标被 锁定: screenCoordinates 会固定在屏幕中心,而 worldRayDirection 始终报告屏幕中心的射线,但 screenDelta 会持续在每一帧报告原始的鼠标移动。这使得它成为光标锁定时读取鼠标移动的唯一方式,而这正是自定义相机或瞄准控制所需的。

拖动旋转物体

下面的示例允许玩家在按住指针按钮的同时横向拖动鼠标来旋转一个立方体:

同样的模式适用于任何拖拽交互:例如使用 delta.x 作为偏移量,沿轨道滑动实体,擦洗动画,或者通过检查较大的 delta 值来检测快速滑动。

鼠标视角相机控制

因为 screenDelta 在光标被锁定时仍然有效,所以你可以用它为 虚拟相机构建鼠标视角控制。为此,将鼠标移动累积到 yaw 和 pitch 角度中,然后在每一帧将它们应用到相机的旋转上。

在下面的示例中,玩家点击一个方块即可切换到一个可用鼠标控制的虚拟相机,并按下辅助按钮(F 或右键单击)返回默认相机。虚拟相机激活时,场景还会锁定光标,并通过一个 输入修饰器冻结角色,这样玩家在操控相机时就不会盲目走动。

关于此示例,有几点需要注意:

  • 系统将 delta.y 加到 pitch 上。鼠标向上移动时会报告一个负的 delta.y,这会降低 pitch 并使相机向上倾斜。如果你更喜欢反转的垂直控制,可以把这个符号取反。

  • pitch 被限制在 -85 到 85 度之间,因此相机永远不会向后翻转。

  • 这个 SENSITIVITY 常量表示每像素鼠标移动对应的旋转角度,可按需调整。

💡 提示:玩家可以随时按下 Esc 或右键单击来解锁光标,这会停止相机对鼠标的响应。一定要给玩家一个清晰的方式完全退出相机模式,例如上例中的辅助按钮。你也可以通过代码重新锁定光标,参见 锁定或解锁光标.

相关主题

要读取光标在屏幕上的绝对位置,而不是它的移动,请使用同一组件的 screenCoordinates 属性。参见 检查玩家的光标位置.

要找出光标下方的是哪个实体,将 worldRayDirection 属性与射线投射结合使用。参见 射线投射.

💡 提示:关于指针状态的工作示例,请参见 0,5-primary-cursor-info 测试场景,它会每一帧读取 PrimaryPointerInfo 并将其输入 worldRayDirection 到射线投射中; 31,20-pointer-lock-control,它通过写入 PointerLock.isPointerLocked来请求和释放光标捕获;以及 32,20-virtual-camera-mouse-look,它展示了 screenDelta 在锁定期间仍然报告移动,而 screenCoordinates 则在屏幕中心处冻结。

最后更新于