Unity UI和模型物体,自身拖拽(精准和非精准拖拽)

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;
    }
}

注意:主相机要挂载物理射线检测组件

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值