• unity 从UI上拖出3D物体,(2D转3D)


    效果展示:

    2D转3D视频

    在这里插入图片描述

    UI结构
    在这里插入图片描述
    UI组件挂载

    UI结构

    这个脚本挂载到 3D物体身上

    using DG.Tweening;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class DragGame : MonoBehaviour
    {
        [HideInInspector]
        public bool isDrag;
    
    
    
       
        public int z=8;
        void Start()
        {
          
    
        }
    
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
    
        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));
            isDrag = true;
            while (Input.GetMouseButton(0))
            {
                
                Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
                var curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
                transform.position = curPosition;
                yield return new WaitForFixedUpdate();
            }
        }
        IEnumerator OnMouseUp()
        {
            isDrag = false;
    
            Whereabouts();
    
            yield return 0;
        }
    
        private void OnTriggerEnter(Collider other)
        {
            //物体拖出后  碰到其他物体的逻辑
           
        }
        public void Whereabouts()
        {
            RaycastHit hit;
            //参数:当前物体,世界空间的方向,碰撞信息,最大距离
            if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.down), out hit, Mathf.Infinity))
            {
                transform.DOMove(new Vector3(hit.point.x, hit.point.y + (transform.localScale.y / 2), hit.point.z), 0.5f);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    挂载到UI上面

    using DG.Tweening;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class KnapsackPanel : MonoBehaviour
    {
        List<GameObject> scrollList = new List<GameObject>();//容量列表
        List<Toggle> toggles = new List<Toggle>();//背包类型列表
        GameObject to, sv, im;
    
        GameObject toggle;
        GameObject scrollView;
        Toggle Switch;
        public void Start()
        {
            toggle = transform.Find("GameObject/ToggleGroup/Toggle").gameObject;
            scrollView = transform.Find("GameObject/ScrollGroup/Scroll View").gameObject;
            Switch = transform.Find("GameObject/BG/Switch").GetComponent<Toggle>();
            RectTransform tf = transform.Find("GameObject").GetComponent<RectTransform>();
            Switch.onValueChanged.AddListener((arg) =>
            {
                if (arg)
                {
                    tf.transform.DOLocalMoveX(tf.transform.localPosition.x - tf.rect.width, 1f);
                }
                else
                {
                    tf.transform.DOLocalMoveX(tf.transform.localPosition.x + tf.rect.width, 1f);
                }
            });
    
            CreateKnapsack();
    
    
        }
      
        /// 
        /// 生成背包内容
        /// 
        public void CreateKnapsack()
        {
               Toggle[] tog = transform.Find("GameObject/ToggleGroup").GetComponentsInChildren<Toggle>();
            for (int i = 0; i < tog.Length; i++)
            {
                toggles.Add(tog[i]);
            }
               
              ScrollRect[] scrollbars= transform.Find("GameObject/ScrollGroup").GetComponentsInChildren<ScrollRect>(true);
            for (int i = 0; i < scrollbars.Length; i++)
            {
                scrollList.Add(scrollbars[i].gameObject);
              
                Transform content = scrollbars[i].transform.Find("Viewport/Content");
               
                for (int j = 0; j < content.childCount; j++)
                {
                    int t = j;
                   
                    GameObject game = Resources.Load<GameObject>(content.GetChild(t).name);//需要拖拽出的3D物体
               
                    DragGameCommand drag = new DragGameCommand(content.GetChild(t).gameObject, game, j, () => { Switch.isOn = true; });
                    //dragGames.Add(drag);
                }
            }
          
               
            
    
            //类型切换事件绑定
            for (int i = 0; i < toggles.Count; i++)
            {
                
                int t = i;
                toggles[i].onValueChanged.RemoveAllListeners();
                toggles[i].onValueChanged.AddListener((arg) =>
                {
                    scrollList[t].SetActive(arg);
    
                });
            }
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    挂载到空物体上

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class IEnumeratorManager : MonoBehaviour
    {
        public static IEnumeratorManager instance;
        void Start()
        {
            instance = this;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这个脚本 不需要挂载

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    public class DragGameCommand 
    {
        public GameObject instance;//UI图标
        public GameObject dragGame;//拖拽的物体
        GameObject game;//要创建的物体
    
        public GameObject scrollView;//对应的背包分类界面(拖回物体到UI的范围)
        public int z;//物体的Z轴距离
        int index;//在背包里排列的索引
        Action dragEnd;
        public DragGameCommand(GameObject image, GameObject _game, int _index, Action _dragEnd)
        {
            instance = image;
            game = _game;
            scrollView = image.transform.parent.parent.parent.gameObject;
            AddListener();
            z = 8;
            int index = _index;
            dragEnd = _dragEnd;
            AddEvent(scrollView.transform);
        }
        #region 背包拖出物体
        /// 
        /// 物体从UI 拖出的事件
        /// 
        private void AddListener()
        {
          //给Image 动态添加 拖拽 事件
            EventTrigger eventTrigger = instance.gameObject.AddComponent<EventTrigger>();
    
            EventTrigger.Entry beginDrag = new EventTrigger.Entry();
            beginDrag.eventID = EventTriggerType.BeginDrag;
            beginDrag.callback.AddListener((v) =>
            {
                Debug.Log("开始拖拽");
                Image dragImage = instance.GetComponent<Image>();
                dragImage.raycastTarget = false;//UI置灰
                dragImage.color = new Color(1, 1, 1, 0.5f);
                string name = game.name;
                dragGame = GameObject.Instantiate(game);//创建3D物体
                DragGame dg = dragGame.GetComponent<DragGame>();
                dg.z = z;
                dragGame.name = name;
                ObjFollowMouse(dragGame);//让物体跟随鼠标
    
            });
    
    
            EventTrigger.Entry drag = new EventTrigger.Entry();
            drag.eventID = EventTriggerType.Drag;
            drag.callback.AddListener((v) =>
            {
              
                ObjFollowMouse(dragGame);//让物体跟随鼠标
            });
    
            EventTrigger.Entry endDrag = new EventTrigger.Entry();
            endDrag.eventID = EventTriggerType.EndDrag;
            endDrag.callback.AddListener((v) => {
                dragEnd?.Invoke();
                dragGame.GetComponent<DragGame>().Whereabouts();//下落
            });
    
    
            eventTrigger.triggers.Add(beginDrag);
            eventTrigger.triggers.Add(drag);
            eventTrigger.triggers.Add(endDrag);
    
        }
        /// 
        /// UI跟随鼠标
        /// 
        /// 
        private void ObjFollowMouse(GameObject gameObject)
        {
    
            gameObject.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, z));
        }
        #endregion
    
        #region 物体放回背包
        Coroutine coroutine;
        //绑定背包界面鼠标移入和移出事件
        public void AddEvent(Transform viewport)
        {
        
            EventTrigger eventr = viewport.gameObject.AddComponent<EventTrigger>();//给拖入范围UI,添加 鼠标进入和鼠标离开事件
            EventTrigger.Entry pointerEnter = new EventTrigger.Entry();
            pointerEnter.eventID = EventTriggerType.PointerEnter;
            pointerEnter.callback.RemoveAllListeners();
            //鼠标进入UI
            pointerEnter.callback.AddListener((v) =>
            {
                if (dragGame != null)//已经拖出来的物体
                {
    
                    DragGame dragGame1 = dragGame.GetComponent<DragGame>();
                    if (dragGame1.isDrag)//物体正在拖拽中
                    {
                        coroutine =IEnumeratorManager.instance. StartCoroutine(OnMouse(index));//放回背包事件
    
                    }
                }
    
            });
            EventTrigger.Entry pointerExit = new EventTrigger.Entry();
            pointerExit.eventID = EventTriggerType.PointerExit;
            pointerExit.callback.RemoveAllListeners();
            //鼠标离开UI
            pointerExit.callback.AddListener((v) =>
            {
                if (coroutine != null)
                {
                    IEnumeratorManager.instance.StopCoroutine(coroutine);
    
                }
            });
    
    
    
            eventr.triggers.Add(pointerEnter);
            eventr.triggers.Add(pointerExit);
        }
    
        /// 
        /// 物体放回背包
        /// 
        /// 
        /// 
        IEnumerator OnMouse(int index)
        {
    
            DragGame game = dragGame.GetComponent<DragGame>();
            Image image = instance.GetComponent<Image>();
            while (true)
            {
    
                if (!game.isDrag && scrollView.activeInHierarchy)//物体结束拖拽 并且在对应的背包类型容量处于显示状态、
                {
                    GameObject.DestroyImmediate(game.gameObject);
                    image.raycastTarget = true;
                    image.color = new Color(1, 1, 1, 1);
                    dragGame = null;
                    IEnumeratorManager.instance. StopCoroutine(coroutine);
                }
                yield return 0;
            }
        }
      
        #endregion
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160

    可以根据自己需求去修改,比如 动态生成背包里的类型和元素,

    Demo上传了,可以下载,

  • 相关阅读:
    VR全景展览——开启全新视界的虚拟展览体验
    谷歌前员工:一流开发工具经验在手却不能用?
    06_Node.js服务器开发
    自动化测试的生命周期是什么?
    链表相关的一些问题
    Flutter --- 配置多个Flutter SDK
    三、Dockerfile自定义镜像
    ubuntu下切换默认python版本
    CP&FT测试介绍
    代码随想录算法训练营第1天|二分查找|移除元素
  • 原文地址:https://blog.csdn.net/o_ojjj/article/details/134202454