当前位置: 首页 > news >正文

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 framevoid 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);}}
}

挂载到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();}/// <summary>/// 生成背包内容/// </summary>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);});}}}

挂载到空物体上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class IEnumeratorManager : MonoBehaviour
{public static IEnumeratorManager instance;void Start(){instance = this;}
}

这个脚本 不需要挂载

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 背包拖出物体/// <summary>/// 物体从UI 拖出的事件/// </summary>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);}/// <summary>/// UI跟随鼠标/// </summary>/// <param name="eventData"></param>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();//鼠标进入UIpointerEnter.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();//鼠标离开UIpointerExit.callback.AddListener((v) =>{if (coroutine != null){IEnumeratorManager.instance.StopCoroutine(coroutine);}});eventr.triggers.Add(pointerEnter);eventr.triggers.Add(pointerExit);}/// <summary>/// 物体放回背包/// </summary>/// <param name="index"></param>/// <returns></returns>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
}

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

Demo上传了,可以下载,

http://www.lryc.cn/news/217429.html

相关文章:

  • win10pycharm和anaconda安装和环境配置教程
  • [C++ 中]:6.类和对象下(static成员 + explicit +友元函数 + 内部类 + 编译器优化)
  • ONES Design UI 组件库环境搭建
  • 支付宝AI布局: 新产品助力小程序智能化,未来持续投入加速创新
  • taro全局配置页面路由和tabBar页面跳转
  • 【k8s】pod进阶
  • 【设计模式】第18节:行为型模式之“迭代器模式”
  • 【数据结构】单链表OJ题
  • 智能工厂架构
  • 阿里云多款ECS产品全面升级 性能最多提升40%
  • 责任链模式(Chain of Responsibility)
  • 文件管理技巧:根据大小智能分类并移动至目标文件夹
  • 具有自主产权的SaaS门店收银系统全套源码输出
  • 论文阅读:One Embedder, Any Task: Instruction-Finetuned Text Embeddings
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • 软件测试---边界值分析(功能测试)
  • 使用pytorch处理自己的数据集
  • http进一步认识
  • grafana docker安装
  • 【Kubernetes】初识k8s--扫盲阶段
  • “01”滴答“摩尔斯电码”加密解密单个字符
  • P3817 小A的糖果
  • Yolov8目标识别与实例分割——算法原理详细解析
  • HandlerMethodArgumentResolver方法参数解析器支持多用户
  • 【Linux】 man命令使用
  • 同一个数据库服务器进行数据表间的数据迁移-MySQL
  • 适用于 Linux 的 WPF:Avalonia
  • 【教3妹学编程-算法题】数组中两个数的最大异或值
  • STM32-RTC实时时钟
  • 初学Flutter,实现底部导航切换