2025-07-28 19:42:29 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Reflection;
|
2025-11-06 16:31:20 +08:00
|
|
|
using TMPro;
|
2025-07-28 19:42:29 +08:00
|
|
|
using TMPro.EditorUtilities;
|
|
|
|
|
using UnityEditor;
|
2025-12-01 16:44:19 +08:00
|
|
|
using UnityEditor.SceneManagement;
|
2025-11-11 17:14:00 +08:00
|
|
|
using UnityEditor.UI;
|
2025-07-28 19:42:29 +08:00
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
2025-12-01 16:44:19 +08:00
|
|
|
using Random = UnityEngine.Random;
|
2025-07-28 19:42:29 +08:00
|
|
|
|
|
|
|
|
|
2025-12-01 16:44:19 +08:00
|
|
|
public class UXCreateHelper : Editor
|
2025-07-28 19:42:29 +08:00
|
|
|
{
|
|
|
|
|
static object InvokeMethod(Type type, string methodName, object[] parameters = null)
|
|
|
|
|
{
|
|
|
|
|
if (parameters == null)
|
|
|
|
|
{
|
|
|
|
|
return type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Type[] types = new Type[parameters.Length];
|
|
|
|
|
for (int i = 0; i < parameters.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
types[i] = parameters[i].GetType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, types, null).Invoke(null, parameters);
|
|
|
|
|
}
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-07-28 19:42:29 +08:00
|
|
|
[MenuItem("GameObject/UI/UXImage")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXImage")]
|
|
|
|
|
#endif
|
2025-07-28 19:42:29 +08:00
|
|
|
public static void CreateUXImage(MenuCommand menuCommand)
|
|
|
|
|
{
|
|
|
|
|
Type MenuOptionsType = typeof(UnityEditor.UI.ImageEditor).Assembly.GetType("UnityEditor.UI.MenuOptions");
|
|
|
|
|
InvokeMethod(MenuOptionsType, "AddImage", new object[] { menuCommand });
|
|
|
|
|
GameObject obj = Selection.activeGameObject;
|
|
|
|
|
obj.name = "UXImage";
|
|
|
|
|
DestroyImmediate(obj.GetComponent<Image>());
|
|
|
|
|
var image = obj.AddComponent<UXImage>();
|
|
|
|
|
image.material = AssetDatabase.LoadAssetAtPath<Material>(UXGUIConfig.UIDefaultMatPath);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-12-19 20:26:22 +08:00
|
|
|
[MenuItem("GameObject/UI/UXToggle")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXToggle")]
|
|
|
|
|
#endif
|
2025-12-19 20:26:22 +08:00
|
|
|
public static void CreateUXToggle(MenuCommand menuCommand)
|
2025-12-09 15:08:41 +08:00
|
|
|
{
|
|
|
|
|
Type MenuOptionsType = typeof(UnityEditor.UI.SliderEditor).Assembly.GetType("UnityEditor.UI.MenuOptions");
|
2025-12-19 20:26:22 +08:00
|
|
|
InvokeMethod(MenuOptionsType, "AddToggle", new object[] { menuCommand });
|
2025-12-09 15:08:41 +08:00
|
|
|
GameObject obj = Selection.activeGameObject;
|
2025-12-19 20:26:22 +08:00
|
|
|
obj.name = "UXToggle";
|
|
|
|
|
DestroyImmediate(obj.GetComponent<Toggle>());
|
|
|
|
|
var uxToggle = obj.AddComponent<UXToggle>();
|
|
|
|
|
uxToggle.graphic = obj.transform.Find("Background/Checkmark").GetComponent<Graphic>();
|
|
|
|
|
uxToggle.targetGraphic = obj.transform.Find("Background").GetComponent<Graphic>();
|
2025-12-09 15:08:41 +08:00
|
|
|
}
|
|
|
|
|
|
2025-11-11 17:14:00 +08:00
|
|
|
#if TEXTMESHPRO_SUPPORT
|
2025-07-28 19:42:29 +08:00
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-07-28 19:42:29 +08:00
|
|
|
[MenuItem("GameObject/UI/UXTextMeshPro")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXTextMeshPro")]
|
|
|
|
|
#endif
|
2025-12-01 16:44:19 +08:00
|
|
|
public static void CreateUXTextMeshPro(MenuCommand menuCommand)
|
2025-07-28 19:42:29 +08:00
|
|
|
{
|
2025-11-11 17:14:00 +08:00
|
|
|
Type MenuOptionsType = typeof(ImageEditor).Assembly.GetType("UnityEditor.UI.MenuOptions");
|
2025-07-28 19:42:29 +08:00
|
|
|
InvokeMethod(MenuOptionsType, "AddText", new object[] { menuCommand });
|
|
|
|
|
GameObject obj = Selection.activeGameObject;
|
|
|
|
|
obj.name = "UXTextMeshPro";
|
|
|
|
|
DestroyImmediate(obj.GetComponent<Text>());
|
|
|
|
|
obj.AddComponent<UXTextMeshPro>();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-07-28 19:42:29 +08:00
|
|
|
[MenuItem("GameObject/UI/UXButton")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXButton")]
|
|
|
|
|
#endif
|
2025-07-28 19:42:29 +08:00
|
|
|
public static void CreateUXButton(MenuCommand menuCommand)
|
|
|
|
|
{
|
2025-11-11 17:14:00 +08:00
|
|
|
Type MenuOptionsType = typeof(TMPro_CreateObjectMenu).Assembly.GetType("TMPro.EditorUtilities.TMPro_CreateObjectMenu");
|
2025-07-28 19:42:29 +08:00
|
|
|
InvokeMethod(MenuOptionsType, "AddButton", new object[] { menuCommand });
|
|
|
|
|
GameObject obj = Selection.activeGameObject;
|
|
|
|
|
obj.name = "UXButton";
|
|
|
|
|
DestroyImmediate(obj.GetComponent<Button>());
|
|
|
|
|
obj.AddComponent<UXButton>();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-11-06 16:31:20 +08:00
|
|
|
[MenuItem("GameObject/UI/UXInput Field")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXInput Field")]
|
|
|
|
|
#endif
|
2025-11-06 16:31:20 +08:00
|
|
|
public static void CreateUXInputField(MenuCommand menuCommand)
|
|
|
|
|
{
|
2025-11-11 17:14:00 +08:00
|
|
|
Type MenuOptionsType = typeof(TMPro_CreateObjectMenu).Assembly.GetType("TMPro.EditorUtilities.TMPro_CreateObjectMenu");
|
2025-11-06 16:31:20 +08:00
|
|
|
InvokeMethod(MenuOptionsType, "AddTextMeshProInputField", new object[] { menuCommand });
|
|
|
|
|
GameObject obj = Selection.activeGameObject;
|
|
|
|
|
obj.name = "UXInputField";
|
|
|
|
|
TMP_InputField inputField = obj.GetComponent<TMP_InputField>();
|
|
|
|
|
TextMeshProUGUI oldTextField = inputField.placeholder.GetComponent<TextMeshProUGUI>();
|
|
|
|
|
GameObject placeholderGameObject = inputField.placeholder.gameObject;
|
|
|
|
|
float oldFontSize = oldTextField.fontSize;
|
|
|
|
|
Color oldColor = oldTextField.color;
|
|
|
|
|
string oldText = oldTextField.text;
|
|
|
|
|
DestroyImmediate(oldTextField);
|
|
|
|
|
TextMeshProUGUI newTextField = placeholderGameObject.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
newTextField.fontSize = oldFontSize;
|
|
|
|
|
newTextField.color = oldColor;
|
|
|
|
|
newTextField.text = oldText;
|
|
|
|
|
inputField.placeholder = newTextField;
|
|
|
|
|
}
|
2025-11-11 17:14:00 +08:00
|
|
|
#endif
|
2025-11-06 16:31:20 +08:00
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-07-28 19:42:29 +08:00
|
|
|
[MenuItem("GameObject/UI/UXScrollView")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXScrollView")]
|
|
|
|
|
#endif
|
2025-12-01 16:44:19 +08:00
|
|
|
public static void CreateUxRecyclerView()
|
2025-07-28 19:42:29 +08:00
|
|
|
{
|
|
|
|
|
GameObject selectionObject = Selection.activeGameObject;
|
2025-12-01 16:44:19 +08:00
|
|
|
Transform parent = selectionObject != null ? selectionObject.transform : PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot.transform;
|
2025-07-28 19:42:29 +08:00
|
|
|
const string prefabPath = "Packages/com.alicizax.unity.ui.extension/Editor/RecyclerView/Res/ScrollView.prefab";
|
|
|
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
2025-12-01 16:44:19 +08:00
|
|
|
GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, parent);
|
2025-07-28 19:42:29 +08:00
|
|
|
PrefabUtility.UnpackPrefabInstance(instance, PrefabUnpackMode.Completely, InteractionMode.UserAction);
|
2025-12-01 16:44:19 +08:00
|
|
|
instance.name = prefab.name + Random.Range(1, 1000);
|
2025-07-28 19:42:29 +08:00
|
|
|
Selection.activeGameObject = instance;
|
|
|
|
|
}
|
2025-08-01 19:32:36 +08:00
|
|
|
|
2026-04-09 16:45:34 +08:00
|
|
|
#if !UNITY_6000_3_OR_NEWER
|
2025-08-01 19:32:36 +08:00
|
|
|
[MenuItem("GameObject/UI/UXTemplateWindow")]
|
2026-04-09 16:44:43 +08:00
|
|
|
#else
|
|
|
|
|
[MenuItem("GameObject/UI (Canvas)/UXTemplateWindow")]
|
|
|
|
|
#endif
|
2025-08-01 19:32:36 +08:00
|
|
|
private static void CreateTemplateWindow()
|
|
|
|
|
{
|
|
|
|
|
GameObject selectionObject = Selection.activeGameObject;
|
|
|
|
|
if (selectionObject == null) return;
|
|
|
|
|
const string prefabPath = "Packages/com.alicizax.unity.ui.extension/Editor/Res/Template/UITemplateWindow.prefab";
|
|
|
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
|
|
|
|
GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, selectionObject.transform);
|
|
|
|
|
PrefabUtility.UnpackPrefabInstance(instance, PrefabUnpackMode.Completely, InteractionMode.UserAction);
|
|
|
|
|
Selection.activeGameObject = instance;
|
|
|
|
|
}
|
2025-07-28 19:42:29 +08:00
|
|
|
}
|