unity3d 拖动ui物体_unity ui拖拽生成物体 - CSDN
  • 当我们做一些农场游戏或者类似可编辑战场类游戏时经常会遇到从UI拖动物体3D场景里生成,要实现这种从UI上拖物体的效果其实挺简单,代码不复杂,主要是想法很重要,一个优秀的程序员不只是技术扎实,更重要的是要...

    当我们做一些农场游戏或者类似可编辑战场类游戏时经常会遇到从UI上拖动物体在3D场景里生成,要实现这种从UI上拖物体的效果其实挺简单,代码不复杂,主要是想法很重要,一个优秀的程序员不只是技术扎实,更重要的是要多思考,不思考的程序员只是一个码农。思维活跃的人总能想到更简单的办法去解决一些看似复杂的问题。本次实现从UI上向场景里拖物体的效果图如下:

    这里写图片描述
    具体的实现代码很简单,主要代码如下:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    using System;
    using Common;
    using UnityEngine.UI;
    
    public class DragCreat : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    {    
        public string sourcename;
        public string SubSystemName;
        public int SubSystemID;
        Text Name;
        GameObject go;
        public void OnBeginDrag(PointerEventData eventData)
        {
            MoseState.ChangeCameraState(MoseState.State.Bussing);
            AssetBundle bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/SubSystem/" + sourcename + ".assetbundle");
            go = Instantiate(bundle.LoadAsset(SubSystemName)) as GameObject;
            bundle.Unload(false);
        }
    
        public void OnDrag(PointerEventData eventData)
        {       
            if (go!=null)
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                Vector3 screenSpace;
                if (Physics.Raycast(ray, out hit))
                {
                    go.transform.position = hit.point;
                }
                else
                {
                    Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                    go.transform.position = pos;
                }
            }
        }
    
        public void OnEndDrag(PointerEventData eventData)
        {
            MoseState.ChangeCameraState(MoseState.State.Waite);
            IfDragging = false;
            go.AddComponent<DragManage>();              
        }
        // Use this for initialization
        void Start () {
            Name = transform.FindChild("Text").GetComponent<Text>();
        }   
    }

    这里有很些代码是没用的,这些是项目的一些片段,这里主要提供一个思路,当开始拖拽时我们生成要生成物体的实例,拖拽进行中时我们检测射线击中的场景中的点然后把这个点的坐标赋值给生成的物体,当射线没有击中场景时就把鼠标在worldspace中的坐标赋值给生成的物体。
    这是拖拽生成物体,当物体放置在场景中后我们想再次调整物体的位置,这时我们看用以下脚本实现:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    using System;
    using Common;
    using Unity;
    
    public class DragManage : MonoBehaviour
    {
        //鼠标经过时改变物体颜色  
        private Color mouseOverColor = Color.blue;//声明变量为蓝色  
        private Color originalColor;//声明变量来存储本来颜色  
        GameObject Propertygo;
        void Start()
        {
            Propertygo = GameObject.Find("Property");        
            originalColor =GetComponent<Renderer>().sharedMaterial.color;//开始时得到物体着色  
        }
    
        void OnMouseEnter()
        {
            MoseState.ChangeCameraState(MoseState.State.Bussing);
            GetComponent<Renderer>().material.color = mouseOverColor;//当鼠标滑过时改变物体颜色为蓝色  
        }
    
        void OnMouseExit()
        {
            GetComponent<Renderer>().material.color = originalColor;//当鼠标滑出时恢复物体本来颜色
            MoseState.ChangeCameraState(MoseState.State.Waite);
        }
        IEnumerator OnMouseDown()
        {     
            Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);//三维物体坐标转屏幕坐标  
            //将鼠标屏幕坐标转为三维坐标,再计算物体位置与鼠标之间的距离  
            var offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));       
            while (Input.GetMouseButton(0))
            {           
                Propertygo.GetComponent<GoProperty>().SetProperty();
                MoseState.ChangeCameraState(MoseState.State.Bussing);
                Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
                var curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
                transform.position = curPosition;
                StateVar.nowgameobject = this.gameObject;           
                yield return new WaitForFixedUpdate();
            }
        }
    }

    拖动到效果图如下:
    这里写图片描述
    以上就是从UI拖拽生成物体以及在场景中用鼠标拖动物体的实现方式,如果你们有更好的方法,大家可以交流!

    展开全文
  • 本实例通过UGUI实现背包的简单功能,物品的拖拽,交换,拖放位置处理,还有针对背包多页面的滑动翻页的处理。 具体的代码如下。 首先是UIItem类,这个背包内各种物体的类: using UnityEngine; using System....

    本实例通过UGUI实现背包的简单功能,物品的拖拽,交换,拖放位置处理,还有针对背包多页面的滑动翻页的处理。

    具体的代码如下。


    首先是UIItem类,这个背包内各种物体的类:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    public class UIItem : MonoBehaviour {
        public Text name;
        public Image image;
    
        public void Show(string name)
        {
            this.name.text = name;
        }
    
    }
    


    然后是拖拽事件类,出来鼠标拖拽UIItem类:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    public class DragEvent : MonoBehaviour,IBeginDragHandler ,IDragHandler ,IEndDragHandler ,IPointerDownHandler ,IPointerUpHandler {
    
        public RectTransform rectTransform;
        public RectTransform rectTransformSlot;
        public Transform draggedItemBox;
        private Vector2 pointerOffset;
        public CanvasGroup canvasGroup;
        public Transform grid;
    
        /// <summary>
        /// 开始拖拽!
        /// </summary>
        /// <param name="eventData"></param>
        public void OnBeginDrag(PointerEventData eventData)
        {
            SetDraggedPosition(eventData);
        }
        /// <summary>
        /// 设置拖拽开始和结束的位置
        /// </summary>
        /// <param name="eventData"></param>
        private void SetDraggedPosition(PointerEventData eventData)
        {
            if (rectTransform == null)
                return;
    
            if(eventData .button ==PointerEventData .InputButton .Left )
            {
                //把世界坐标转换为局部坐标
                rectTransform.SetAsLastSibling();
    
                transform.SetParent(draggedItemBox);
                Vector2 localPointerPosition;
                //画布是否接受射线
                canvasGroup.blocksRaycasts = false;
                if(RectTransformUtility .ScreenPointToLocalPointInRectangle (rectTransformSlot ,Input .mousePosition ,
                    eventData .pressEventCamera ,out localPointerPosition ))
                {
                    rectTransform.localPosition = localPointerPosition - pointerOffset;
                }
            } 
        }
    
        public void OnDrag(PointerEventData eventData)
        {
            SetDraggedPosition(eventData);
        }
    
        public void OnEndDrag(PointerEventData eventData)
        {
            SetDraggedPosition(eventData);
            canvasGroup.blocksRaycasts = true;
    
            if(eventData .pointerCurrentRaycast .gameObject .name =="skill")
            {
                transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform);
                transform.position = eventData.pointerCurrentRaycast.gameObject.transform.position;
            }
            else if(eventData .pointerCurrentRaycast .gameObject .name =="Text99")
            {
                this.transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform.parent.parent);
                transform.position = eventData.pointerCurrentRaycast.gameObject.transform.parent.parent.position;
                eventData.pointerCurrentRaycast.gameObject.transform.parent.SetParent(grid);
            }
            else
            {
                transform.SetParent(grid);
            }
        }
    
        public void OnPointerDown(PointerEventData eventData)
        {
            transform.localPosition = Vector3.one * 0.5f;
        }
    
        public void OnPointerUp(PointerEventData eventData)
        {
            transform.localPosition = Vector3.one;
        }
    }
    


    最后的对画布和Scroll的类处理:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    using UnityEngine.EventSystems;
    using System.Collections.Generic;
    using System;
    public class ScrollRectHelper : MonoBehaviour ,IBeginDragHandler ,IEndDragHandler {
        /// <summary>
        /// 滑动速度
        /// </summary>
        private float smooting = 2;
        /// <summary>
        /// 每页显示的数目
        /// </summary>
        private int pageCount = 16;
    
        private ScrollRect sRect;
        /// <summary>
        /// 总页数
        /// </summary>
        private float pageIndex;
        /// <summary>
        /// 是否拖拽结束
        /// </summary>
        private bool isDrag = false;
        /// <summary>
        /// 总页数索引比例
        /// </summary>
        private List<float> listPageValue = new List<float> { 0 };
        /// <summary>
        /// 滑动目标位置
        /// </summary>
        float targetPos = 0;
        /// <summary>
        /// 当前索引位置
        /// </summary>
        float nowIndex = 0;
    
        public GameObject UIItem;
    
        private int count;
        void Awake()
        {
            sRect = GetComponent<ScrollRect>();
            ListPageValueInit();
        }
    
    
        /// <summary>
        /// 初始化UIItem
        /// </summary>
        void Start()
        {
            for (int i = 0; i < count ; i++)
            {
                GameObject go = Instantiate(UIItem);
                go.name += +i;
                go.SetActive(true);
                go.transform.localPosition = UIItem.transform.localPosition;
                go.transform.parent = UIItem.transform.parent;
                go.GetComponent<UIItem>().Show("物品" + i);
            }
        }
        /// <summary>
        /// 每页比例
        /// </summary>
        private void ListPageValueInit()
        {
            pageIndex = (count / pageCount) - 1;
            if(count !=0)
            {
                for (int i = 1; i < pageIndex ; i++)
                {
                    listPageValue.Add((i / pageIndex));
                }
            }
        }
    
        void Update()
        {
            if(!isDrag )
            {
                sRect.horizontalNormalizedPosition = Mathf.Lerp(sRect.horizontalNormalizedPosition, targetPos, Time.deltaTime);
            }
        }
    
    
        /// <summary>
        /// 开始拖拽
        /// </summary>
        /// <param name="eventData"></param>
        public void OnBeginDrag(PointerEventData eventData)
        {
            isDrag = true;
        }
        /// <summary>
        /// 拖拽结束
        /// </summary>
        /// <param name="eventData"></param>
        public void OnEndDrag(PointerEventData eventData)
        {
            isDrag = false;
            //获取拖动的值
            float  tempPos = sRect.horizontalNormalizedPosition;
            var index = 0;
            //拖动的绝对值
            float offset = Mathf.Abs(listPageValue[index] - tempPos);
    
            for (int i = 0; i < listPageValue .Count ; i++)
            {
                float temp = Mathf.Abs(tempPos - listPageValue[i]);
                if(temp <offset )
                {
                    index = i;
                    offset = temp;
                }
            }
    
            targetPos = listPageValue[index];
            nowIndex = index;
        }
    
        #region 如果需要分页,此处为左右分页代码,现有功能不需要,所以注释掉了
        //public void BtnLeftGo()
        //{
        //    nowindex = Mathf.Clamp(nowindex - 1, 0, pageIndex);
        //    targetPos = listPageValue[Convert.ToInt32(nowindex)];
        //}
    
        //public void BtnRightGo()
        //{
        //    nowindex = Mathf.Clamp(nowindex + 1, 0, pageIndex);
        //    targetPos = listPageValue[Convert.ToInt32(nowindex)];
    
        //}
        #endregion
    }
    

    原文:点击打开链接

    展开全文
  • Unity 拖动UI物体(超级干货) 首先我们先创建一个C#脚本 名字就叫MyMove 代码如下 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using ...

    Unity 拖动UI物体(超级干货)

    首先我们先创建一个C#脚本 名字就叫MyMove
    代码如下

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    public class MyMove: MonoBehaviour
    {
    
        public  GameObject Canvas;
        GameObject InputObject;
        bool b;//鼠标是否在按下状态
        // Start is called before the first frame update
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
        	//当鼠标按下时 状态为按下状态 InputObject去获取鼠标点击的UI
            if (Input.GetMouseButtonDown(0))
            {
                b = true;
                InputObject = GetOverUI(Canvas);       
            }
    		//当鼠标抬起时 状态为抬起状态 InputObject等于null
            if (Input.GetMouseButtonUp(0))
            {
                b = false;
                InputObject = null;
            }
    		
    		
            if (InputObject != null && b==true)
            {
                if (InputObject.name == "Over")
                {
                    InputObject.transform.position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
                }
            }
        }
    
    
        /// <summary>
        /// 获取鼠标停留处UI
        /// </summary>
        /// <param name="canvas"></param>
        /// <returns></returns>
        public 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);
            if (results.Count != 0)
            {
                return results[0].gameObject;
            }
    
            return null;
        }
    
    
    
        /// <summary>
        /// 获取鼠标停留处物体,不仅适合UI还适合3D物体
        /// </summary>
        /// <param name="raycaster"></param>
        /// <returns></returns>
        public 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);
            if (results.Count != 0)
            {
                return results[0].gameObject;
            }
    
            return null;
        }
    }
    

    然后将上面的C#脚本挂载到我们的 Canvas 上面 (我这边的名字跟上面代码的名字不同,代码是一样的)
    在这里插入图片描述
    然后将我们的Canvas 拖到我们这边来 (我这边的名字跟上面代码的名字不同,代码是一样的)在这里插入图片描述

    然后我们在创建一个 image 取名叫Over 我再随便给他设置个颜色 将其挂载到 Canvas 节点下。
    在这里插入图片描述
    然后运行
    在这里插入图片描述

    在这里插入图片描述
    哈哈完成 ,想拖到哪里就拖到哪里 。

    在这里插入图片描述

    展开全文
  • s

    拖动3D物体

    (所有的坐标系都采用的主相机变换的)

    鼠标

    • 鼠标点击需要拖动的3D物体后,移动鼠标,3D物体会跟随,再次点击后放下
    using UnityEngine;
    public class Move3DObject : MonoBehaviour
    {
        private bool isClick = false;
        private Transform curTf = null;
        private Vector3 oriMousePos;
        private Vector3 oriObjectScreenPos;
    
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, 100))
                {
                    curTf = hit.transform;
                    oriObjectScreenPos=Camera.main.WorldToScreenPoint(curTf.position);
                    oriMousePos = Input.mousePosition;
                }
                isClick = !isClick;
            }
            if (isClick)
            {
                if (curTf != null)
                {
                    Vector3 curMousePos = Input.mousePosition;
                    Vector3 mouseOffset = curMousePos - oriMousePos;
                    Vector3 curObjectScreenPos = oriObjectScreenPos + mouseOffset;
                    Vector3 curObjectWorldPos = Camera.main.ScreenToWorldPoint(curObjectScreenPos);
                    curTf.position = curObjectWorldPos;
                }
            }
        }
    }
    

    思路:1.首先确定是使用那个相机进行坐标系转换
    2.使用Physics里面的射线方法判断是否点击到物体
    3.点击到,则记录鼠标的坐标(屏幕坐标系),记录物体transform ,将物体的坐标从世界坐标系转换成屏幕坐标系坐标(oriObjectScreenPos)
    4.每当鼠标移动都会有一个偏移量(mouseOffset),而这个偏移量也同样是需要移动物体在屏幕坐标系的偏移量
    5.物体的初始屏幕坐标(oriObjectScreenPos)再加上鼠标的偏移量(mouseOffset),就得到了移动后的物体的屏幕坐标(curObjectScreenPos),再由屏幕坐标转换成世界坐标相应的位置赋值给物体。

    • 扩展:通过以上方法还能实现:只是鼠标拖动状态时物体才跟随等等

    鼠标操作的几种情况:按下,抬起,单击,双击,按住,拖动


    拖动UI物体

    鼠标

    • 鼠标通过点击到的UI物体

    该脚本是挂在需要被移动的UI物体上的

    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class MoveUIObject:MonoBehaviour,IDragHandler
    {
    	private RectTransform rt;
    	private void Start()
    	{
    		rt=this.gameObject.GetCommponent<RectTransform>();
    	}
    	//IDragHandler接口实现
    	private void OnDrag(PointerEventData eventData)
    	{
    		Vector3 curUIPos;
    	    if(RectTransformUtility.ScreenPointToWorldPointInRectangle(rt,eventData.position,eventData.pressEventCamera,out curUIPos))
    		{
    			rt.position=curUIPos;
    		}
    	}
    }
    

    UI中需要注重使用RectRansformUtility的使用和UnityEngine.EventSystems.EventTrigger中的触屏阶段以及PointEventData中包含的属性


    注:出于环境原因,以上代码是无提示手打的,如有错误,还请指正。

    展开全文
  • Unity3D拖拽3D物体

    2018-04-22 22:08:04
    需求:如题 在做UI拖拽的时候用了IDragHandler接口,非常好用,但是这个接口是继承自IEventSystemHandler,而所有...所以想到了对于拖拽3D物体通常用的函数OnMouseDrag(),但是实际在我们的工程中使用的时候并...
  • Unity3D 拖动物体旋转

    2016-08-12 10:06:37
    将此脚本挂在一个物体上cube using UnityEngine; using System.Collections; public class CubeRotate : MonoBehaviour { /// /// 起始位置 /// Ve
  • using System.Collections; using System.Collections.Generic; using UnityEngine;... //用于 实现可以拖动物体移动 //先写一个方法 将屏幕坐标转换成世界装备 //或表达为 将屏幕空间转化为世界空间 V...
  • UnityUI拖拽生成3D物体与ScrollView 从UI拖拽物体本来时一个很简单的问题,为啥还要在此次特意记录一下呢,是因为今天和ScrollView一起使用的时候出了一点问题; 我有一个UI图片,开始写了一个脚本像这样(该脚本...
  • 一、拖拽overlay模式的Canvas下的ui元素 这种情形比较简单,直接上代码,代码挂在UI元素上即可。using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using System; public class UI...
  • 这篇博客实现一个小功能,通过鼠标拖动3D物体。我们知道,如果是拖动 UIUG 的控件的话,它是有接口可以使用的。但是3D物体就没有可直接使用的接口(或者说我没找到?),就需要我们自己写代码。既然如此,那我们就来...
  • 最近有一个拖拽ui到另外的目标ui上,给模型换颜色的需求,网上找了些方法,不是完全适用,自己加了些改动;直接上代码: using System.Collections; using System.Collections.Generic; using UnityEngine; using ...
  • //unity3d用鼠标拖动物体的一段代码 var mouseOverColor = Color.blue;//声明变量为蓝色 private var originalColor:Color;//声明变量来存储本来颜色 function Start() { originalColor = renderer....
  • Unity3d鼠标拖拽物体实现任意角度自旋转 主要涉及函数Input.GetAxis(“Mousex”) 可取得鼠标横向(x轴)移动增量Input.GetAxis(“Mousey”) 可取得鼠标竖向(y轴)移动增量通过勾股定理获取拖拽长度,长度越长旋转越...
  • 程序版本 :unity 5.5.0f3 3D物体在2D平面中移动旋转
  • 当我们拖动的时候,unity自动给挂在脚本的OnDrag函数推送事件。 拖拽UI 需要在inspector面板上添加eventsystem,并确定场景中有物体挂载GraphicRaycaster脚本。通常我们创建的canvas上就有此脚本。 代码如下: ...
  • Unity拖拽UI界面元素

    2019-04-26 10:27:09
    1.新建场景,在场景中创建一个UI的Panel。 2.创建脚本Drag.cs,将脚本附加到Panel上。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; ...
  • 下图为UI的层级结构,Anchors下的四个物体UI的四个角,注意物体的锚点要设置成对应的位置,而Communication的锚点要设置为stretch、stretch 具体代码如下: using System.Collections;...
  • unity3D 拖拽旋转3D物体

    2019-12-18 22:38:26
    Rotate3dObj在Update中调用,脚本挂在需要旋转的物体上即可 private float m_deltaX=0; private float m_deltaY=0; private void Rotate3dObj() { #if UNITY_EDITOR if (Input.GetMouseButton(0)) #else if(1...
  • Unity鼠标拖动物体UI

    2020-06-24 23:50:09
    鼠标拖动物体 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class Test : MonoBehaviour{ Vector3 screenSpace; Vector3 offset; ...
  • Unity3D点击UI图片生成模型预设物 目录 1、博客介绍 2、内容 (1)演示 (2)生成 (3)生成物体移动 3、推送 4、结语 1、博客介绍 翻出来了之前一个两年前Demo,顺手传上来了,通过点击按钮或者其他UI...
1 2 3 4 5 ... 20
收藏数 1,776
精华内容 710
关键字:

unity3d 拖动ui物体