using System.Collections; using System.Collections.Generic; using System.IO; using DG.Tweening; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UIElements; using System.Reflection; using System; using System.Linq; public class AutoGenerate : EditorWindow { #region Component private VisualElement root; private Label titleText; private Label hintText; private Toggle testScene; //测试场景是否生成 private Toggle dynamicSprite; //动态文件夹是否生成 private Button generateBtn; private TextField nameInput; #endregion #region Path private string testScenePath; private string scriptPath; private string uiPrefabPath; private string uiStaticSpritePath; private string uidynamicSpritePath; private string uiTemplatePath; #endregion [MenuItem("Tools/Generate Editor Window")] public static void ShowExample() { AutoGenerate wnd = GetWindow(); wnd.titleContent = new GUIContent("Auto Generate UI Window"); } public void CreateGUI() { testScenePath = "Assets/Temp/TestUIPanelScenes"; scriptPath = "Assets/Runtime/UIPanels"; uiPrefabPath = "Assets/Resources/UI/UI_Panel"; uiStaticSpritePath = "Assets/ArtRes/UIStaticSprites"; uidynamicSpritePath = "Assets/Resources/DynamicSprites"; uiTemplatePath = Path.Combine("Assets", "Temp", "OnlyUITemplate", "CustomPanel.prefab"); // scenePath = "Assets/Test1"; // scriptPath = "Assets/Test2"; // prefabPath = "Assets/Test3"; // var visualTree = // AssetDatabase.LoadAssetAtPath( // "Assets/ThirdPart/UIToolKitFile/UDoc/UXml/AutoGenerateUI.uxml"); // rootElement = visualTree.CloneTree(); root = rootVisualElement; titleText = new Label("自动生成ui预制体,脚本,静态sprite文件夹,动态sprite文件夹(可选),测试场景(可选),"); hintText = new Label(""); testScene = new Toggle("创建测试场景?"); dynamicSprite = new Toggle("创建动态sprite文件夹?"); generateBtn = new Button(OnGenerateButtonClick); generateBtn.text = "自动生成按钮"; nameInput = new TextField("预制体名(也是脚本名)"); root.Add(titleText); root.Add(hintText); root.Add(testScene); root.Add(dynamicSprite); root.Add(nameInput); root.Add(generateBtn); // nameInput = rootElement.Q("NameInput"); } private void OnGenerateButtonClick() { CheckDirectoryAndCreat(); //检查五个路径文件夹是否都在,没有则创建 string tempName = nameInput.text; var sceneExist = DoesFileExist(testScenePath, tempName); var preExist = DoesFileExist(uiPrefabPath, tempName); var scriptExist = DoesFileExist(scriptPath, tempName); if (sceneExist || preExist || scriptExist) { ShowHint("三者中至少有一个同名文件已经存在,未添加任何文件"); return; } CreatPrefab(tempName); CreatCSFile(tempName); DirectoryDontExistAndCreat(uiStaticSpritePath + "/" + tempName); if (dynamicSprite.value) { DirectoryDontExistAndCreat(uidynamicSpritePath + "/" + tempName); } if (testScene.value) { CreateNewScene(testScenePath, tempName); } // TODO 绑定脚本的功能没实现AttachScriptToGameObject(tempName, generatePre); AssetDatabase.Refresh(); // EditorApplication.delayCall = () => // { // AssetDatabase.Refresh(); // AttachScriptToGameObject(tempName, generatePre); // PrefabUtility.SavePrefabAsset(generatePre); // AssetDatabase.Refresh(); // // EditorUtility.DisplayDialog("成功", "UI预制体,测试场景,UI脚本已经被创建 ", "OK"); // }; //AssetDatabase.Refresh(); //EditorUtility.DisplayDialog("成功创建", $" " + scenePath, "OK"); } //TODO private bool CheckLawfulString(string checkedString) { if (string.IsNullOrWhiteSpace(checkedString)) { ShowHint("输入文件名异常,未添加任何文件"); return false; } foreach (var strItem in checkedString) { if (strItem == '1') { return false; } } return true; } private void CheckDirectoryAndCreat() { DirectoryDontExistAndCreat(uiPrefabPath); DirectoryDontExistAndCreat(testScenePath); DirectoryDontExistAndCreat(scriptPath); DirectoryDontExistAndCreat(uidynamicSpritePath); DirectoryDontExistAndCreat(uiStaticSpritePath); } private void DirectoryDontExistAndCreat(string directoryPath) { if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } } private void CreatCSFile(string csFileName) { string scriptContent = GetScriptTemplate(csFileName); File.WriteAllText(Path.Combine(scriptPath, csFileName + ".cs"), scriptContent); } private void CreatPrefab(string preName) { //Selection.activeGameObject; GameObject selectedObjectRes = AssetDatabase.LoadAssetAtPath(uiTemplatePath); if (selectedObjectRes == null) { ShowHint("面板模版预制体不存在,未添加任何文件"); return; } GameObject selectedObject = (GameObject)PrefabUtility.InstantiatePrefab(selectedObjectRes); PrefabUtility.UnpackPrefabInstance(selectedObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); //完全解包&不提示 //解包属性会出问题? selectedObject.transform.localPosition = Vector3.zero; selectedObject.transform.localScale = Vector3.one; selectedObject.name = preName; var generatePre = PrefabUtility.SaveAsPrefabAsset(selectedObject, Path.Combine(uiPrefabPath, preName + ".prefab")); } private string GetScriptTemplate(string scriptName) { return $@" using UnityEngine; using QFramework.Core; namespace Project.UIPanel {{ public class {scriptName} : UIPanelBase {{ public void Init() {{ }} void Start() {{ }} }} }}"; } /// /// 提示文本 /// /// private void ShowHint(string mes) { hintText.text = mes; hintText.style.opacity = 1f; // 确保提示文本完全可见 DOVirtual.DelayedCall(2, () => { hintText.text = string.Empty; }); } /// /// 检查文件是否存在 /// /// /// /// private bool DoesFileExist(string path, string fileName) { string fullPath = path; string[] files = Directory.GetFiles(fullPath, "*.*", SearchOption.TopDirectoryOnly); //不递归 foreach (var file in files) { //无拓展名 if (Path.GetFileNameWithoutExtension(file) == fileName) { return true; } } return false; } /// /// 创建场景 /// /// /// private void CreateNewScene(string scenePath, string sceneName) { //TODO 将预制体添加到场景未实现 var newScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); // GameObject lightGameObject = new GameObject("Directional Light"); // Light lightComp = lightGameObject.AddComponent(); // lightComp.type = LightType.Directional; // lightComp.transform.rotation = Quaternion.Euler(50, -30, 0); // // GameObject ground = GameObject.CreatePrimitive(PrimitiveType.Plane); // ground.transform.position = Vector3.zero; // 加载预制体资源/// GameObject prefab = AssetDatabase.LoadAssetAtPath(Path.Combine("Assets", "Resources", "UI", "Base", "Canvas.prefab")); //GameObject pre = AssetDatabase.LoadAssetAtPath(prefabPath + "/sceneName.prefab"); if (prefab != null) { // 实例化预制体并添加到场景中 GameObject prefabInstance = (GameObject)PrefabUtility.InstantiatePrefab(prefab); // GameObject preInstance = (GameObject)PrefabUtility.InstantiatePrefab(pre); SceneManager.MoveGameObjectToScene(prefabInstance, newScene); // SceneManager.MoveGameObjectToScene(preInstance, newScene); // preInstance.transform.parent = prefabInstance.transform.Find("Mid"); // ((RectTransform)preInstance.transform).localPosition = Vector3.zero; // ((RectTransform)preInstance.transform).transform.localScale = Vector3.one; } else { Debug.LogError("预制体未找到,请检查路径是否正确!"); } EditorSceneManager.SaveScene(newScene, scenePath + "/" + sceneName + ".unity", true); } //暂时拿不到 private void AttachScriptToGameObject(string className, GameObject pre) { // 获取当前的Assembly var assembly = Assembly.Load("Assembly-CSharp"); // 使用反射获取新脚本的类型 Type scriptType = assembly.GetTypes().FirstOrDefault(t => t.Name == className); if (scriptType != null) { // 查找目标游戏对象(假设场景中有一个名为 "TargetObject" 的对象) if (pre != null) { // 添加脚本到对象上 pre.AddComponent(scriptType); ShowHint($"{className} script attached to {pre.name}"); } else { Debug.LogError("Target object not found in the scene."); } } else { Debug.LogError($"Script type {className} not found."); } } }