unity拖拽的三种实现方式

第一种

使用条件:
1.场景中要有EventSystem
2.脚本引用命名空间using UnityEngine.EventSystems;
3.脚本继承自MonoBehaviour
4.脚本要实现接口IBeginDragHandler,IDragHandler,IEndDragHandler(第三个接口不是必须的)
5.仅对UGUI有效,ui的image组件的RaycastTarget必须勾选上

using UnityEngine;
using UnityEngine.EventSystems;
public class Test : MonoBehaviour,IBeginDragHandler, IDragHandler,IEndDragHandler
{
     
    
    private Vector3 offset;
    public void OnBeginDrag(PointerEventData eventData)
    {
     
        //开始拖拽的时候记录偏移量
        Vector3 v3;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(GetComponent<RectTransform>(),
            eventData.position, eventData.enterEventCamera, out v3);
        offset = transform.position-v3;
        
    }

    public void OnDrag(PointerEventData eventData)
    {
     
        transform.position = Input.mousePosition+offset;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
     
        throw new System.NotImplementedException();
    }
}

第二种

使用条件:
1.可用于3d物体和worldspace模式的画布
2.被拖拽的物体必须挂上碰撞器,ui的碰撞器要尽量包裹住UI同时,碰撞器的size.z不要太“厚”

using UnityEngine;

public class Test1 : MonoBehaviour
{
     
    //偏移量
    private Vector3 offset = Vector3.zero;
    private float z;
    private void OnMouseDown()
    {
     
        z = Vector3.Dot(transform.position - Camera.main.transform.position, Camera.main.transform.forward);
        //也可以是z= Camera.main.WorldToScreenPoint(transform.position).z;
        //debug一下就知道这两个z是一样的
        //保持鼠标的屏幕坐标的z值与被拖拽物体的屏幕坐标的z保持一致
        Vector3 v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
        //得到鼠标点击位置与物体中心位置的差值
        offset = transform.position - Camera.main.ScreenToWorldPoint(v3);
    }
    private void OnMouseDrag()
    {
     
        //时刻保持鼠标的屏幕坐标的z值与被拖拽物体的屏幕坐标保持一致
        Vector3 v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
        //鼠标的屏幕坐标转换为世界坐标+偏移量=物体的位置
        transform.position = Camera.main.ScreenToWorldPoint(v3) + offset;
    }

}

第三种

使用条件
1.3d物体和worldspace模式的画布UI
2.必须有碰撞器

using UnityEngine;

public class Test2 : MonoBehaviour
{
     
    //1.3d物体和worldspace模式的画布UI
    //2.必须有碰撞器
    Vector3 offset;
    Vector3 hitpoint;
    RaycastHit hit;
    Ray ray;
    float z;
    private bool mIsDrag = false;
    private void Update()
    {
     
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Input.GetMouseButtonDown(0))
        {
     
            if (Physics.Raycast(ray,out hit))
            {
     
                mIsDrag = true;
                z = Vector3.Dot(hit.transform.position - Camera.main.transform.position,
                    Camera.main.transform.forward);
                //也可写z = Camera.main.WorldToScreenPoint(hit.transform.position).z,两者是一样的
                offset = hit.transform.position - Camera.main.ScreenToWorldPoint(new Vector3
                    (Input.mousePosition.x, Input.mousePosition.y,z));
            }
        }
        if (Input.GetMouseButton(0))
        {
     
            if (mIsDrag)
            {
     
                hit.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(
                    Input.mousePosition.x,Input.mousePosition.y, z))+offset;
            }
        }
        if (Input.GetMouseButtonUp(0))
        {
     
            mIsDrag = false;
        }
    }
}

你可能感兴趣的:(C#,Unity)