我很难用简单的数学来旋转/旋转一个轮子,使用拖拽。
在画布中有一个径向布局(Unity ),它已经可以通过设置一个名为StartAngle的属性来旋转,该属性的范围为0-360。在这个径向有项目,所以StartAngle是为第一个项目,并将所有的子元素周围的布局半径。
我想实现拖放的项目,以便您可以拖动一个孩子和径向将相应旋转(无限)。
现在,我的出发点是:
public void OnDrag(PointerEventData eventData)
{
var delta = eventData.delta.x * Time.deltaTime;
var newAngle = radialLayout.StartAngle + delta;
if (newAngle >= 360)
newAngle = newAngle - 360;
else if (newAngle < 0)
newAngle = Mathf.Abs(360 - newAngle);
radialLayout.StartAngle = newAngle;
}它有点工作,但感觉不太平稳。这是针对移动/触摸的,所以我希望同时考虑拖动操作的X和Y增量。显然,在我的例子中没有考虑yδ,我不知道如何正确地将它合并。用户可能会在任何一个轴上做直线拖放,或者他/她也可能做类似于圆形拖动的运动。
那么,我如何将鼠标移动映射到从0到360的旋转角度,以使它感觉良好?
编辑:谢谢你的帮助,我现在就这样做了:
public void OnDrag(PointerEventData eventData)
{
// Note the "Head-Minus-Tale rule for Vector subtraction, see http://www.maths.usyd.edu.au/u/MOW/vectors/vectors-3/v-3-7.html
// vSourceToDestination = vDestination - vSource;
// First, we draw a vector from the center point of the radial to the point where we started dragging
var from = dragStartPoint - (Vector2)radialLayout.transform.position;
// Next, we draw a vector from the center point of the radial to the point we are currently dragging on
var to = eventData.position - (Vector2)radialLayout.transform.position;
// Now, we calculate the angle between these two:
var dragAngle = Vector2.SignedAngle(from, to);
// Lerping makes movement fast at the beginning slow at the end
var lerpedAngle = Mathf.Round(Mathf.LerpAngle(radialLayout.StartAngle, dragAngle, 0.5f));
radialLayout.StartAngle = lerpedAngle;
}发布于 2020-01-09 17:26:45
我不知道你所有的代码和类型,但我会有一个主意。我现在不能测试这个,也不能保证它能像这样工作,但我希望这个想法能弄清楚。
我可能宁愿用这样的方法
// This is the vector from the center of the object to the mouse/touch position
// (in screen pixel space)
var touchDirection = eventData.position - Camera.main.WorldToScreenPoint(transform.position);
// angle between the Up (Y) axis and this touchDirection
// for the angle the length of the up vector doesn't matter so there is
// no need to convert it to pixel space
var targetAngle = Vector2.SignedAngle(Vector2.up, touchDirection);
// since the returned angle might be negative wrap it to get values 0-360
if(targetAngle < 0) targetAngle += 360;
// Now either simply use Lerp
// this would simply interpolate each frame to the middle of both values
// the result is a fast movement at the beginning and a very slow at the end
radialLayout.StartAngle = Mathf.Lerp(radialLayout.StartAngle, targetAngle, 0.5f);
// or maybe use a fixed speed like 30°/second
var difference = targetAngle - radialLayout.StartAngle;
radialLayout.StartAngle += Mathf.Sign(difference) * Mathf.Min(30f * Time.deltaTime, Mathf.Abs(difference));输入智能手机,但我希望这个想法能弄清楚
https://stackoverflow.com/questions/59668026
复制相似问题