在XY平面拖拽
1.使用Camera.main.WorldToScreenPoint 获取到了物体的屏幕坐标的Z值,一般情况下我们觉得屏幕坐标只有XY,这里的Z是物体到摄像机的距离,在下一步使用屏幕坐标转换到世界坐标时传入就可以让物体在原来的Z轴上保持移动。
2.鼠标点中物体的时候计算出一个偏移量,这样就可以保证我们不会在点下去的时候让物体的中心点与点击位置重合而是在点物体的任意位置都可以自然的拖动。
完整代码
public class ObjectDragger : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 offset;
void OnMouseDown()
{
screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
transform.position = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
}
}
在XZ平面拖拽
完整代码
public Camera mainCamera;
public Vector3 offset;
private void OnMouseDown()
{
offset = transform.position - GetPoint();
}
private void OnMouseDrag()
{
transform.position = GetPoint()+offset;
}
private Vector3 GetPoint()
{
var dis = (mainCamera.transform.position - transform.position).magnitude;
var mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, dis);
var pos = mainCamera.ScreenToWorldPoint(mousePosition);
Vector3 fwd = mainCamera.transform.forward;
float k = (1 - pos.y) / fwd.y;
pos += fwd * k;
return pos;
}
比起XY拖拽稍有瑕疵,如果想自行控制拖拽物体的高度,需要做以下修改
去掉offset,将1变为变量height,height的值为最后拖拽时的物体y值
需要注意,当相机角度为(0,0,0)时,参数fwd的y值为0,这时会出现除零操作
public Camera mainCamera;
public float height=2;
private void OnMouseDrag()
{
transform.position = GetPoint();
}
private Vector3 GetPoint()
{
var dis = (mainCamera.transform.position - transform.position).magnitude;
var mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, dis);
var pos = mainCamera.ScreenToWorldPoint(mousePosition);
Vector3 fwd = mainCamera.transform.forward;
float k = (height - pos.y) / fwd.y;
pos += fwd * k;
return pos;
}