不使用射线实现
拖拽物体以及UGUI
主要函数为
拖拽UGUI主要函数
RectTransformUtility.ScreenPointToWorldPointInRectangle
拖拽具有碰撞体,物体的主要函数
Camera.main.ScreenToWorldPoint
第二个函数一般可以把 Input.mousePosition
当作参数传给 ScreenToWorldPoint(Input.mousePosition)
然后我们再把结果给我们想要拖动的物体 的 Position,如果摄像机的Projection 是 Orthographic
(正交)问题会少点,可摄像机模式是Perspective
(透视)就完全没法用了
Input.mousePosition
的Z
是重点 传给ScreenToWorldPoint
的时候z
需要是摄像机与物体所在平面的距离 是图中摄像机与黑色面的距离 紫色Cube是被拖拽物体 (黑色面是假象面)
求这个距离只需使用矢量投影
便可轻松求值 ("矢量投影"说明图片 在末尾)
image.png
UGUI拖拽代码 与拖拽有关的函数只有一个OnDrag()
using UnityEngine;using UnityEngine.EventSystems;using UnityEngine.UI;public class UGUIDrag : MonoBehaviour,IDragHandler { Image _image; RectTransform _rectTransform; private void Awake() { _image = GetComponent<Image>(); _rectTransform = GetComponent<RectTransform>(); } public void OnDrag(PointerEventData eventData) { Vector3 globalMousePos; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(_rectTransform, eventData.position, eventData.pressEventCamera, out globalMousePos)) { _rectTransform.position = globalMousePos; } } }
带有3D/2D碰撞体的物体拖拽
using UnityEngine;public class ScreenToWorldTest : MonoBehaviour { private Camera _currentCamera; private Transform _target; private void Awake() { _currentCamera = Camera.main; _target = transform; } private void OnMouseDrag() { //得到摄像机到物体的向量 Vector3 CO_Direction = _target.position - _currentCamera.transform.position; //得到摄像机与物体所在平面的距离 float cPlane = Vector3.Dot(CO_Direction, _currentCamera.transform.forward); _target.position = _currentCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, cPlane)); } }
矢量投影
作者:L罗夏
链接:https://www.jianshu.com/p/1b66f0b707bf