返回顶部
首页 > 资讯 > 精选 >Unity如何从UI中拖拽对象放置并拖动效果
  • 709
分享到

Unity如何从UI中拖拽对象放置并拖动效果

2023-06-15 06:06:13 709人浏览 安东尼
摘要

这篇文章主要介绍Unity如何从UI中拖拽对象放置并拖动效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!需求:点击UI,在场景中生成3D对象,对象跟随鼠标移动,放置后可再次拖拽对象,改变其位置。做了一个小Demo,

这篇文章主要介绍Unity如何从UI中拖拽对象放置并拖动效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

需求:点击UI,在场景中生成3D对象,对象跟随鼠标移动,放置后可再次拖拽对象,改变其位置。做了一个小Demo,如下图所示:

实现大致思路:

  • 射线碰撞检测

  • 对象空间坐标变换(世界坐标->屏幕坐标、屏幕坐标->世界坐标)

首先为要生成3D对象的UI添加一个鼠标监听事件,脚本如下:

SelectImage.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;public class SelectImage : MonoBehaviour,IPointerDownHandler{    //需要被实例化的预制    public GameObject inistatePrefab;    //实例化后的对象    private GameObject inistateObj;    // Use this for initialization    void Start () {        if (inistatePrefab==null)return;        //实例化预制        inistateObj=Instantiate(inistatePrefab) as GameObject;        inistateObj.SetActive(false);    }    //实现鼠标按下的接口    public void OnPointerDown(PointerEventData eventData)    {        inistateObj.SetActive(true);        //将当前需要被实例化的对象传递到管理器中        SelectObjManager.Instance.AttachNewObject(inistateObj);    }}

将脚本挂载到UI对象上。

创建一个对象放置管理器,用于处理拖动的放置的逻辑:

SelectObjManager.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public class SelectObjManager : MonoBehaviour {    private static SelectObjManager _instance;    public static SelectObjManager Instance {        get { return _instance; }    }    //物体z轴距摄像机的长度    public float _zDistance = 50f;    //对象的缩放系数    public float _scaleFactor=1.2f;    //地面层级    public LayerMask _groundLayerMask;    int touchID;    bool isDragging = false;    bool isTouchInput = false;    //是否是有效的放置(如果放置在地面上返回True,否则为False)    bool isPlaceSuccess = false;    //当前要被放置的对象    public GameObject currentPlaceObj = null;    //坐标在Y轴上的偏移量    public float _YOffset=0.5F;    void Awake () {        _instance = this;    }    void Update () {        if (currentPlaceObj == null) return;        if (CheckUserInput()){            MoveCurrentPlaceObj();        }else if (isDragging){            CheckIfPlaceSuccess();        }    }    /// <summary>    ///检测用户当前输入    /// </summary>    /// <returns></returns>    bool CheckUserInput () {        #if !UNITY_EDITOR&&(UNITY_Android||UNITY_iOS)        if (Input.touches.Length > 0) {            if (!isTouchInput) {                isTouchInput = true;                touchID = Input.touches[0].fingerId;                return true;            } else if (Input.GetTouch (touchID).phase == TouchPhase.Ended) {                isTouchInput = false;                return false;            } else {                return true;            }        }        return false;        #else        return Input.GetMouseButton (0);        #endif    }    /// <summary>    ///让当前对象跟随鼠标移动    /// </summary>    void MoveCurrentPlaceObj () {        isDragging = true;        Vector3 point;        Vector3 screenPosition;        #if !UNITY_EDITOR&&(UNITY_ANDROID||UNITY_IOS)        Touch touch = Input.GetTouch (touchID);        screenPosition = new Vector3 (touch.position.x, touch.position.y, 0);        #else        screenPosition = Input.mousePosition;        #endif        Ray ray = Camera.main.ScreenPointToRay (screenPosition);        RaycastHit hitInfo;        if (Physics.Raycast (ray, out hitInfo, 1000, _groundLayerMask)) {            point = hitInfo.point;            isPlaceSuccess = true;        } else {            point = ray.GetPoint (_zDistance);            isPlaceSuccess = false;        }        currentPlaceObj.transfORM.position = point+new Vector3(0,_YOffset,0);        currentPlaceObj.transform.localEulerAngles = new Vector3 (0, 60, 0);    }    /// <summary>    ///在指定位置化一个对象    /// </summary>    void CreatePlaceObj(){        GameObject obj=Instantiate(currentPlaceObj) as GameObject;        obj.transform.position=currentPlaceObj.transform.position;        obj.transform.localEulerAngles=currentPlaceObj.transform.localEulerAngles;        obj.transform.localScale*=_scaleFactor;        //改变这个对象的Layer为Drag,以便后续拖动检测        obj.layer=LayerMask.NameToLayer("Drag");    }    /// <summary>    ///检测是否放置成功    /// </summary>    void CheckIfPlaceSuccess(){        if (isPlaceSuccess){            CreatePlaceObj();        }        isDragging=false;        currentPlaceObj.SetActive(false);        currentPlaceObj=null;    }    /// <summary>    /// 将要创建的对象传递给当前对象管理器    /// </summary>    /// <param name="newObject"></param>    public void AttachNewObject(GameObject newObject){        if (currentPlaceObj){            currentPlaceObj.SetActive(false);        }        currentPlaceObj=newObject;    }}

脚本中都有详细注释,我就不多解释了。

创建一个脚本,用于处理放置成功后,再次改变位置的逻辑:

DragObject.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public class DraGobject : MonoBehaviour {    //只针对指定的层级进行拖动    public LayerMask _dragLayerMask;    //指定当前要拖动的对象    public Transform currentTransform;    //是否可以拖动当前对象    public bool isDrag = false;    //用于存储当前需要拖动的对象在屏幕空间中的坐标    Vector3 screenPos = Vector3.zero;    //当前需要拖动对象的坐标相对于鼠标在世界空间坐标中的偏移量    Vector3 offset = Vector3.zero;    void Update () {        if (Input.GetMouseButtonDown (0)) {            //将鼠标输入点转化为一条射线            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);            RaycastHit hitinfo;            //如果当前对象与指定的层级发生碰撞,表示当前对象可以被拖动            if (Physics.Raycast (ray, out hitinfo, 1000f, _dragLayerMask)) {                isDrag = true;                //将当前需要拖动的对象赋值为射线碰撞到的对象                currentTransform = hitinfo.transform;                //将当前对象的世界坐标转化为屏幕坐标                screenPos = Camera.main.WorldToScreenPoint (currentTransform.position);                //将鼠标的屏幕坐标转换为世界空间坐标,再与当前要拖动的对象计算两者的偏移量                offset = currentTransform.position - Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPos.z));            } else {                isDrag = false;            }        }        if (Input.GetMouseButton (0)) {            if (isDrag == true) {                var currentScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPos.z);                //鼠标的屏幕空间坐标转化为世界坐标,并加上偏移量                var currentPos = Camera.main.ScreenToWorldPoint (currentScreenPos) + offset;                currentTransform.position = currentPos;            }        }        if (Input.GetMouseButtonUp (0)) {            isDrag = false;            currentTransform = null;        }    }}

主要是一些坐标空间的变换和计算。

以上是“Unity如何从UI中拖拽对象放置并拖动效果”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Unity如何从UI中拖拽对象放置并拖动效果

本文链接: https://lsjlt.com/news/278510.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Unity如何从UI中拖拽对象放置并拖动效果
    这篇文章主要介绍Unity如何从UI中拖拽对象放置并拖动效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!需求:点击UI,在场景中生成3D对象,对象跟随鼠标移动,放置后可再次拖拽对象,改变其位置。做了一个小Demo,...
    99+
    2023-06-15
  • Unity 从UI中拖拽对象放置并拖动效果 附demo
    需求:点击UI,在场景中生成3D对象,对象跟随鼠标移动,放置后可再次拖拽对象,改变其位置。做了一个小Demo,如下图所示: 实现大致思路: 射线碰撞检测 对象空间...
    99+
    2024-04-02
  • Element-UI Table组件上如何添加列拖拽效果
    这篇文章将为大家详细讲解有关Element-UI Table组件上如何添加列拖拽效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Element-UI 的 Table 组...
    99+
    2024-04-02
  • 如何使用JavaScript实现一个拖拽缩放效果
    这篇文章主要介绍“如何使用JavaScript实现一个拖拽缩放效果”,在日常操作中,相信很多人在如何使用JavaScript实现一个拖拽缩放效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用JavaS...
    99+
    2023-06-30
  • JS如何实现模态框拖拽动态效果
    本篇内容主要讲解“JS如何实现模态框拖拽动态效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JS如何实现模态框拖拽动态效果”吧!在实现这个案例效果首先我们了解几个属性,offsetLeft.o...
    99+
    2023-07-02
  • jQuery中如何实现拖动效果
    这篇文章主要介绍了jQuery中如何实现拖动效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。jQuery实现拖动效果的实例代码,具体代码如...
    99+
    2024-04-02
  • HTML5中canvas如何实现移动端上传头像拖拽裁剪效果
    这篇文章将为大家详细讲解有关HTML5中canvas如何实现移动端上传头像拖拽裁剪效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 html部分: <!DOC...
    99+
    2024-04-02
  • HTML5中如何实现拖放效果无须借助javascript
    这篇文章给大家分享的是有关HTML5中如何实现拖放效果无须借助javascript的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 先看html核心代码: <div>...
    99+
    2024-04-02
  • vue中如何基于html5实现drag drap的拖放效果
    这篇文章将为大家详细讲解有关vue中如何基于html5实现drag drap的拖放效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 事情是这样的,右边有各种控...
    99+
    2024-04-02
  • 如何使用Vue实现一个简单的鼠标拖拽滚动效果插件
    这篇文章主要介绍了如何使用Vue实现一个简单的鼠标拖拽滚动效果插件,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 演示事例最近在做...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作