Unity中拖拽3D物体并放入到指定位置

一、脚本编写

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class DragTest : MonoBehaviour
{
    //3D目标
    public List<GameObject> listTargets = new List<GameObject>();
    //2D目标点
    public List<Image> listUITargets = new List<Image>();

    //操作模式
    bool isUI = false;

    public Button buttonUI;
    public Button buttonModel;

    //起始坐标
    Vector3 starPos;
    private void Start()
    {
        starPos = transform.localPosition;
        buttonUI.onClick.AddListener(()=>
        {
            isUI = true;
        });
        buttonModel.onClick.AddListener(() =>
        {
            isUI = false;
        });
    }

    public void OnMouseDrag()
    {
        Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPos.z);
        transform.position = Camera.main.ScreenToWorldPoint(mouseScreenPos);
        Debug.Log("OnMouseDrag");
    }

    public void OnMouseUp()
    {
        if (isUI==false)
        {
            //是否落位
            bool isTarget = false;
            foreach (GameObject item in listTargets)
            {
                if (GetOverGameObject(Camera.main.gameObject).Contains(item))
                {
                    isTarget = true;
                    transform.position = item.transform.position;
                    break;
                }
            }
            if (isTarget == false)
            {
                transform.position = starPos;
            }
        }
        else
        {
            foreach (Image item in listUITargets)
            {
                if (GetOverUI(GameObject.Find("Canvas")).Count>0)
                {
                    List<GameObject> listTemp = new List<GameObject>();
                    listTemp.AddRange(GetOverUI(GameObject.Find("Canvas")));
                    if (listTemp.Contains(item.gameObject))
                    {
                        //简单做一个变色效果,实际应用中可能会是改Image的sprite之类的操作
                        item.GetComponent<Image>().color = Color.green;
                        break;
                    }
                }
               
            }
            transform.position = starPos;
        }

        //有时候操作次数多了会出现不能拖拽的问题,暂时没去看是什么原因,将该对象关闭打开一次可暂时解决。
        gameObject.SetActive(false);
        gameObject.SetActive(true);
    }

    //获取光标停留的3D物体
    public List<GameObject> GetOverGameObject(GameObject raycaster)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = Input.mousePosition;
        PhysicsRaycaster pr = raycaster.GetComponent<PhysicsRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        pr.Raycast(pointerEventData, results);
        List<GameObject> listObjs = new List<GameObject>();
        if (results.Count != 0)
        {
            foreach (RaycastResult item in results)
            {
    
                listObjs.Add(item.gameObject);
            }
            //return listObjs;
        }
        return listObjs;
    }

    //获取光标停留的UI物体
    public List<GameObject> GetOverUI(GameObject canvas)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = Input.mousePosition;
        GraphicRaycaster gr = canvas.GetComponent<GraphicRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        gr.Raycast(pointerEventData, results);
        List<GameObject> listObjs = new List<GameObject>();
        if (results.Count != 0)
        {
            foreach (RaycastResult item in results)
            {
                listObjs.Add(item.gameObject);
            }
            //return listObjs;
        }
        return listObjs;
    }
}

二、编辑场景

1.新建一个cube作为我们用来拖拽的物体:

 2.给该cube添加我们刚刚编写的脚本:

3.场景中新建几个cube命名为Taget3D,摆在不同的位置并将这些新的cube传入到ListTartgets中: 

 

4.新建几个Image命名为TargetUI,放在不同的位置并传入到ListUITarget中 :

5.新建两个Button分别对应传入buttonUI和buttonModel:

6.在Main Camera上添加PhisicsRaycaster组件:

 

 三、运行调试

此时点击运行,点击”模型模式“Button,然后拖动我们的cube到左边的一排Target3D物体上去,效果如下:

然后我们点击”UI模式“Button,再去拖动我们的cube与右边的一排TargetUI对象进行交互,可以看到效果如下:

 至此,我们的拖拽功能就基本实现了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值