1、基类部分
public abstract class BaseDrag : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler
{
[Header("是否精准拖拽!")]
public bool m_isPrecision = true;
//偏移量
[SerializeField]
protected Vector3 offset = Vector3.zero;
/// <summary>
/// 拖拽开始
/// </summary>
/// <param name="eventData"></param>
public abstract void OnBeginDrag(PointerEventData eventData);
/// <summary>
/// 拖拽中
/// </summary>
/// <param name="eventData"></param>
public abstract void OnDrag(PointerEventData eventData);
/// <summary>
/// 拖拽结束
/// </summary>
/// <param name="eventData"></param>
public abstract void OnEndDrag(PointerEventData eventData);
}
2.UI拖拽部分
public class UIDragSelf : BaseDrag
{
//存储当前拖拽图片的RectTransform组件
private RectTransform m_rt;
private void Start()
{
m_rt = gameObject.GetComponent<RectTransform>();
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (m_isPrecision)
{
//存储点击时的鼠标坐标
Vector3 tWorldPos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt.transform as RectTransform, eventData.position, eventData.pressEventCamera, out tWorldPos))
{
offset = transform.position - tWorldPos;//设置位置及偏移量
}
}
}
public override void OnDrag(PointerEventData eventData)
{
if (m_isPrecision)
{
Vector3 globalMousePos= Vector3.zero;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt, eventData.position, eventData.pressEventCamera, out globalMousePos))
{
//设置位置及偏移量
m_rt.position = globalMousePos + offset;
}
}
else
{
Vector3 globalMousePos=Vector3.zero;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt, eventData.position, eventData.pressEventCamera, out globalMousePos))
{
m_rt.position = globalMousePos;
}
}
}
public override void OnEndDrag(PointerEventData eventData)
{
}
}
3、模型物体拖拽部分
public class ModelDragSelf : BaseDrag
{
/// <summary>
/// 目标对象的屏幕坐标
/// </summary>
private Vector3 targetScreenPoint;
[SerializeField]
private bool isDrag = false;
public override void OnBeginDrag(PointerEventData eventData)
{
if (CheckGameObject())
{
var pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z));
offset = this.transform.position - pos;
}
}
public override void OnDrag(PointerEventData eventData)
{
if (isDrag)
{
//当前鼠标所在的屏幕坐标
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z);
//把当前鼠标的屏幕坐标转换成世界坐标
Vector3 curWorldPoint = Camera.main.ScreenToWorldPoint(curScreenPoint);
if (m_isPrecision)
{
this.transform.position = curWorldPoint + offset;
}
else
{
this.transform.position = curWorldPoint;
}
}
}
public override void OnEndDrag(PointerEventData eventData)
{
}
/// <summary>
/// 检查是否点击到cbue
/// </summary>
/// <returns></returns>
bool CheckGameObject()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, LayerMask.GetMask("Cube")))
{
isDrag = true; Debug.DrawLine(ray.origin, hitInfo.point);
//得到射线碰撞到的物体
targetScreenPoint = Camera.main.WorldToScreenPoint(this.transform.position);
return true;
}
return false;
}
}
注意:主相机要挂载物理射线检测组件