赞
踩
没有专门处理UI界面岗位的情况下, 开发者需要自己拼合界面,但是Unity默认的UI创建方式有些不太舒服,需要先Create再选中UI最后才能选中自己想要的UI生成出来,而且创建列表内容较多,没办法直接一眼找到,所以做了一个自定义的UI拖拽,先上示例。
//视频上传维护中。。
核心思路:
1.创建一个单独编辑器面板
2.可自定义配置UI资源,包括自定义的UI界面
3.可通过拖拽的方式生成对应UI
技术点梳理:
1.EditorWindow,用于制作单独编辑器面板
2.DragAndDrop,用于实现核心拖拽功能
API分析:
相关API可以在Unity官方文档中查看,这里只是我的个人理解。
DragAndDrop.StartDrag:
开始拖动操作,在启动拖动之后才有相关的拖拽数据产生,EventType才会触发DragUpdated等与拖拽相关的事件。
DragAndDrop.GetGenericData:
DragAndDrop.SetGenericData:
用于对拖拽数据的赋值和获取。
DragAndDrop.PrepareStartDrag:
清空拖拽数据以及拖拽对象,用于数据初始化。
DragAndDrop.AcceptDrag:
接受拖动操作,相当于一个触发器。
DragAndDrop.visualMode
Unity原生的用于修改拖拽时的鼠标样式。
脚本中并没有写有关于生成的逻辑,只有对数据的储存,操作以及DragAndDrop的逻辑,这是因为在Drag的底层调用了Unity原生的生成逻辑,也就是DragAndDropVisualMode.Copy,猜想这部分的逻辑和对预制体拖拽的逻辑是一套的,目前没有查到相关的信息,大佬可留言指教。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- using UnityEngine.EventSystems;
- using System.Linq;
-
- public class UITool : EditorWindow
- {
- class Item
- {
- public GameObject prefab;
- public Texture tex;
- }
-
-
- [MenuItem("Tools/UITool")]
- public static void OpenUITool()
- {
- UITool tool = EditorWindow.GetWindow<UITool>(false,"UITool",true);
- tool.autoRepaintOnSceneChange = true;
- tool.Show();
- }
-
- private Dictionary<string, Item> creatItemDic = new Dictionary<string, Item>();
- private List<Item> creatItemLst = new List<Item>();
- private void OnEnable()
- {
- creatItemDic.Clear();
- creatItemLst.Clear();
- object[] uiPrefabs = Resources.LoadAll("UIPrefab");
- string prefabName = string.Empty;
- for (int i = 0; i < uiPrefabs.Length; i++)
- {
- Item item = new Item();
- item.prefab = uiPrefabs[i] as GameObject;
- prefabName = item.prefab.name;
- Texture tex = Resources.Load<Texture>("UITexture/" + prefabName);
- if (tex == null)
- {
- tex = Resources.Load<Texture>("Unity");
- }
- item.tex = tex;
- creatItemDic.Add(prefabName+i, item);
- creatItemLst.Add(item);
- }
- //可增加自定义路径
- ; }
-
-
- private Vector2 mPos = Vector2.zero;
- private int cellSize = 65;
- const int cellPaddingX = 10;
- const int cellPaddingY = 15;
- Event curEvent;
- EventType eventType;
- int curIndex = -1;
-
- int spacingX = 0;
- int spacingY = 0;
-
- private void OnGUI()
- {
- RefreshGridPos();
-
- curEvent = Event.current;
- eventType = curEvent.type;
- curIndex = GetCellUnderMouse(spacingX, spacingY);
-
-
- switch (eventType)
- {
- case EventType.MouseDown:
- if (curIndex < creatItemLst.Count)
- {
- Item item = creatItemLst[curIndex];
- DraggedObject = item.prefab;
- Debug.Log(curIndex);
- }
- else
- {
- DraggedObject = null;
- Debug.Log("越界");
- }
- break;
- case EventType.MouseDrag:
- if (isDragObjectInOur)
- DragAndDrop.StartDrag("UITool");
- curEvent.Use();
- break;
- case EventType.DragUpdated:
- UpdateVisual();
- curEvent.Use();
- break;
- default:
- break;
- }
-
- }
-
-
-
- void RefreshGridPos()
- {
- GUILayout.BeginVertical();
- mPos = EditorGUILayout.BeginScrollView(mPos);
- Color normal = new Color(1f, 1f, 1f, 0.5f);
-
- Rect texRect;
- Rect labelRect;
- int x = cellPaddingX, y = cellPaddingY;
- int width = Screen.width - cellPaddingX;
- spacingX = cellSize + cellPaddingX;
- spacingY = cellSize + cellPaddingY;
-
- int offsetCellSize = cellSize - 10;
- var labelStyle = EditorStyles.label;
- labelStyle.alignment = TextAnchor.LowerCenter;
- labelStyle.fontStyle = FontStyle.Bold;
- labelStyle.wordWrap = true;
- foreach (var item in creatItemDic)
- {
- texRect = new Rect(x ,y, offsetCellSize, offsetCellSize);
- Rect inner = texRect;
- inner.xMin -= 8f;
- inner.xMax += 8f;
- GUI.DrawTexture(texRect, item.Value.tex);
- inner.y += 14.5f;
- GUI.Label(inner, item.Value.prefab.name, labelStyle);
-
- GUI.backgroundColor = Color.black;
- x += spacingX;
-
- if (x + spacingX > width)
- {
- y += spacingY;
- x = cellPaddingX;
- }
- }
- GUILayout.Space(y + spacingY);
- EditorGUILayout.EndScrollView();
-
-
- GUILayout.EndHorizontal();
-
- }
-
-
-
- int GetCellUnderMouse(int spacingX, int spacingY)
- {
- Vector2 pos = Event.current.mousePosition + mPos;
- int x = cellPaddingX, y = cellPaddingY;
- if (pos.y < y) return -1;
-
- float width = Screen.width - cellPaddingX + mPos.x;
- float height = Screen.height - cellPaddingY + mPos.y;
- int index = 0;
-
- for (; ; ++index)
- {
- Rect rect = new Rect(x, y, spacingX, spacingY);
- if (rect.Contains(pos)) break;
-
- x += spacingX;
-
- if (x + spacingX > width)
- {
- if (pos.x > x) return -1;
- y += spacingY;
- x = cellPaddingX;
- if (y + spacingY > height) return -1;
- }
- }
- return index;
- }
-
-
- bool isDragObjectInOur
- {
- get
- {
- object obj = DragAndDrop.GetGenericData("UITool");
- if (obj == null) return false;
- return (bool)obj;
- }
- set
- {
- DragAndDrop.SetGenericData("UITool", value);
- }
- }
-
- GameObject draggedObject;
- GameObject DraggedObject
- {
- get
- {
- return draggedObject;
- }
- set { draggedObject = value;
- if (draggedObject != null)
- {
- DragAndDrop.PrepareStartDrag();
- DragAndDrop.objectReferences = new Object[] { draggedObject };
- isDragObjectInOur = true;
- }
- else
- {
- DragAndDrop.AcceptDrag();
- }
- }
- }
-
- void UpdateVisual()
- {
- if (DraggedObject == null) DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
- else if (isDragObjectInOur) DragAndDrop.visualMode = DragAndDropVisualMode.Move;
- else DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
- }
- }
Github上有个不错的插件:https://github.com/liuhaopen/UGUI-Editor
Over!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。