统一拖放世界位置
Unity drag and drop in world positions
我目前正在 Unity 中开发一款基本的纸牌游戏,但在弄清楚如何在我的纸牌上执行拖动时遇到了一些麻烦。我目前的布局如下:
我目前正在尝试使用 IDragHandler
界面来接收回调,每当在我的卡片对象上检测到拖动事件时。
我的最终目标是能够根据 touch/mouse 幻灯片的 x 轴将卡片滑动到 left/right。
我目前尝试使用传递给 OnDrag() IDragHandler 的 eventdata.delta 值来移动我的卡片,但据我所知,这个值以像素为单位,并且在使用 [= 转换为世界单位时53=]() 的结果为 0,0,0。同样,尝试跟踪拖动开始的位置并减去当前位置会导致值为 0,0,0。
我目前对如何使用世界单位拖动游戏对象有点不知所措,所以如果有人能给我一些指导,我将不胜感激。
谢谢
编辑:
^这就是为什么你不应该在深夜使用 Whosebug。
所以要添加一些额外的上下文:
- 卡片只是游戏对象,附有网格渲染器和嵌入的 canvas 以添加文本(可能不是添加文本的最佳方式,但它有效)
- 卡片都在一个 "hand" 对象下,该对象由一个用于接收事件的框 collider2d 和一个实现 IBeginDragHandler、IEndDragHandler 和 IDragHandler 的脚本组成
- 到目前为止,我已经尝试了两种不同的方法来计算拖动距离:
public void OnDrag(PointerEventData eventData)
{
Vector2 current = Camera.main.ScreenToWorldPoint(eventData.position);
Debug.Log("Current world position: "+current);
Vector3 delta = lastDragPoint - current;
// Store current value for next call to OnDrag
lastDragPoint = eventData.position;
// Now use the values in delta to move the cards
}
使用这种方法,我在调用 ScreenToWorldPoint
后总是得到 0,0,0 的值,所以我无法移动卡片
我尝试过的第二种方法是:
public void OnDrag(PointerEventData eventData)
{
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 1f);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0f);
Vector3 worldCenterPosition = Camera.main.ScreenToWorldPoint(screenCenter);
Vector3 worldTouchPosition = Camera.main.ScreenToWorldPoint(screenTouch);
Vector3 delta = worldTouchPosition - worldCenterPosition;
// Now use the values in delta to move the cards
}
使用这种方法我得到了更好的结果(卡片实际上移动了)但是它们没有正确地跟随鼠标。如果我拖动一张卡片,我将朝鼠标的方向移动,但是移动的距离明显小于鼠标移动的距离(即,当鼠标到达屏幕边缘时,卡片只移动了一个卡片宽度)
您可以使用 OnMouseDown 方法来检测玩家何时开始拖动卡片并根据鼠标位置更新其位置。当拖动结束时,调用 OnMouseUp 方法。
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseUp.html
因此,经过一番尝试和检查我从 ScreenToWorldPoint 调用中收到的各种值后,我终于找到了问题所在。
在我第二次尝试的方法的代码中,我发现我在 ScreenToWorldPoint 中使用了不正确的 Z 参数值。在做了一些研究后,我发现他应该是相机和(我猜)触摸表面之间的 Z 距离。
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, -Camera.main.transform.position.z);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0);
感谢所有花时间阅读我的问题的人。
我目前正在 Unity 中开发一款基本的纸牌游戏,但在弄清楚如何在我的纸牌上执行拖动时遇到了一些麻烦。我目前的布局如下:
我目前正在尝试使用 IDragHandler
界面来接收回调,每当在我的卡片对象上检测到拖动事件时。
我的最终目标是能够根据 touch/mouse 幻灯片的 x 轴将卡片滑动到 left/right。
我目前尝试使用传递给 OnDrag() IDragHandler 的 eventdata.delta 值来移动我的卡片,但据我所知,这个值以像素为单位,并且在使用 [= 转换为世界单位时53=]() 的结果为 0,0,0。同样,尝试跟踪拖动开始的位置并减去当前位置会导致值为 0,0,0。
我目前对如何使用世界单位拖动游戏对象有点不知所措,所以如果有人能给我一些指导,我将不胜感激。
谢谢
编辑:
^这就是为什么你不应该在深夜使用 Whosebug。
所以要添加一些额外的上下文:
- 卡片只是游戏对象,附有网格渲染器和嵌入的 canvas 以添加文本(可能不是添加文本的最佳方式,但它有效)
- 卡片都在一个 "hand" 对象下,该对象由一个用于接收事件的框 collider2d 和一个实现 IBeginDragHandler、IEndDragHandler 和 IDragHandler 的脚本组成
- 到目前为止,我已经尝试了两种不同的方法来计算拖动距离:
public void OnDrag(PointerEventData eventData)
{
Vector2 current = Camera.main.ScreenToWorldPoint(eventData.position);
Debug.Log("Current world position: "+current);
Vector3 delta = lastDragPoint - current;
// Store current value for next call to OnDrag
lastDragPoint = eventData.position;
// Now use the values in delta to move the cards
}
使用这种方法,我在调用 ScreenToWorldPoint
后总是得到 0,0,0 的值,所以我无法移动卡片
我尝试过的第二种方法是:
public void OnDrag(PointerEventData eventData)
{
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 1f);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0f);
Vector3 worldCenterPosition = Camera.main.ScreenToWorldPoint(screenCenter);
Vector3 worldTouchPosition = Camera.main.ScreenToWorldPoint(screenTouch);
Vector3 delta = worldTouchPosition - worldCenterPosition;
// Now use the values in delta to move the cards
}
使用这种方法我得到了更好的结果(卡片实际上移动了)但是它们没有正确地跟随鼠标。如果我拖动一张卡片,我将朝鼠标的方向移动,但是移动的距离明显小于鼠标移动的距离(即,当鼠标到达屏幕边缘时,卡片只移动了一个卡片宽度)
您可以使用 OnMouseDown 方法来检测玩家何时开始拖动卡片并根据鼠标位置更新其位置。当拖动结束时,调用 OnMouseUp 方法。
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseUp.html
因此,经过一番尝试和检查我从 ScreenToWorldPoint 调用中收到的各种值后,我终于找到了问题所在。 在我第二次尝试的方法的代码中,我发现我在 ScreenToWorldPoint 中使用了不正确的 Z 参数值。在做了一些研究后,我发现他应该是相机和(我猜)触摸表面之间的 Z 距离。
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, -Camera.main.transform.position.z);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0);
感谢所有花时间阅读我的问题的人。