赞
踩
初步学习Unity EditorWindow 的扩展
新建UIRoot类
- using UnityEngine;
- public class UIRoot : MonoBehaviour
- {
- public Transform bg;
- public Transform common;
- public Transform uiPop;
- public Transform forward;
- [SerializeField]
- private Canvas mRootCanvas;
- }
生成Canvas 等。。
- using System.IO;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- public class CreateUIRootPanel : EditorWindow
- {
- static CreateUIRootPanel window;
- [MenuItem("编辑器扩展/1.SetUp(UIRoot)", true)]
- static bool ValidateUIRoot()
- {
- return !GameObject.Find("UIRoot");
- }
-
- [MenuItem("编辑器扩展/1.SetUp(UIRoot)", false)]
- static void MenuItem()
- {
- window = GetWindow<CreateUIRootPanel>();
- window.Show();
- }
- private string mWidth = "720";
- private string mHeight = "1280";
- private void OnGUI()
- {
- GUILayout.BeginHorizontal();
- //var width = GUILayout.TextField("width", GUILayout.Width(50));
- mWidth = GUILayout.TextField(mWidth, GUILayout.Width(50));
- GUILayout.Label("X", GUILayout.Width(15));
- mHeight = GUILayout.TextField(mHeight, GUILayout.Width(55));
-
- GUILayout.EndHorizontal();
- if (GUILayout.Button("Build"))
- {
- Debug.Log("build");
- SetUP(float.Parse(mWidth), float.Parse(mHeight));
- // window.Close();
- }
- }
- public static void SetUP(float width, float height)
- {
- Debug.Log("编辑器扩展");
- // GameObject go = Resources.Load<GameObject>("UIroot");
- // GameObject.Instantiate(go);
- var UIRootObj = new GameObject("UIRoot");
- UIRootObj.layer = LayerMask.NameToLayer("UI");
-
- UIRoot UIScript = UIRootObj.AddComponent<UIRoot>();
-
- var canvas = new GameObject("Canvas");
-
- canvas.transform.SetParent(UIRootObj.transform);
- canvas.layer = LayerMask.NameToLayer("UI");
- canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
- //canvas.AddComponent<CanvasGroup>();
- //CanvasScaler
- CanvasScaler canvasScaler = canvas.AddComponent<CanvasScaler>();
-
- canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
- canvasScaler.referenceResolution = new Vector2(width, height);
- canvas.AddComponent<GraphicRaycaster>();
-
- //EventSystem
- var eventSystem = new GameObject("EventSystem");
-
- eventSystem.layer = LayerMask.NameToLayer("UI");
- eventSystem.transform.SetParent(UIRootObj.transform);
- eventSystem.AddComponent<EventSystem>();
- eventSystem.AddComponent<StandaloneInputModule>();
-
- //BG
- var bgObj = new GameObject("Bg");
- bgObj.AddComponent<RectTransform>();
- bgObj.transform.SetParent(canvas.transform);
- bgObj.transform.localPosition = Vector3.zero;
- UIScript.bg = bgObj.transform;
- //Common
- var commonObj = new GameObject("Common");
- commonObj.AddComponent<RectTransform>();
- commonObj.transform.SetParent(canvas.transform);
- commonObj.transform.localPosition = Vector3.zero;
- UIScript.common = commonObj.transform;
- //PopUI
- var popUI = new GameObject("PopUI");
- popUI.AddComponent<RectTransform>();
- popUI.transform.SetParent(canvas.transform);
- popUI.transform.localPosition = Vector3.zero;
- UIScript.uiPop = popUI.transform;
- //ForwardObj
- var forwardObj = new GameObject("Forward");
- forwardObj.AddComponent<RectTransform>();
- forwardObj.transform.SetParent(canvas.transform);
- forwardObj.transform.localPosition = Vector3.zero;
- UIScript.forward = forwardObj.transform;
-
- ///序列化脚本 添加 UIRoot中的Private的值
- var uirootScriptSerializedObj = new SerializedObject(UIScript);
- uirootScriptSerializedObj.FindProperty("mRootCanvas").objectReferenceValue = canvas.GetComponent<Canvas>();
- uirootScriptSerializedObj.ApplyModifiedProperties();
-
-
-
- var saveFolder = Application.dataPath + "/Resources";
- if (!Directory.Exists(saveFolder))
- {
- Directory.CreateDirectory(saveFolder);
- }
- var saveFilePath = saveFolder + "/UIRoot.Prefab";
- // PrefabUtility.CreatePrefab(saveFilePath, UIRootObj);
- bool IsLoad = false;
- PrefabUtility.SaveAsPrefabAsset(UIRootObj, saveFilePath, out IsLoad);
- Debug.Log(string.Format(" 保存预知体[{0}]", IsLoad ? "成功" : "失败"));
- }
- }
案例1最终效果
主要的生成代码脚本 CreateComponentCode 在Editor文件夹下
- using System;
- using System.Linq;
- using System.IO;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- using UnityEditor.Callbacks;
- using EditorExtension;
- public class CreateComponentCode : EditorWindow
- {
- [MenuItem("编辑器扩展/2.Build 配合 GameObject的@EdtiorExtemsion-CreateCode使用 %#T", false, 2 )]
- public static void OpenMenu()
- {
- GetWindow<CreateComponentCode>().Show();
- }
- [MenuItem("GameObject/@(Alt+A)EdtiorExtemsion-Add View %A", false, 0)]
- public static void AddView()
- {
- GameObject currentGameObject = Selection.gameObjects.First();
- if (currentGameObject == null)
- {
- Debug.LogError("请选择Gameobject");
- return;
- }
- var view = currentGameObject.GetComponent<CodeGenderateInfo>();
- if (!view)
- {
- currentGameObject.AddComponent<CodeGenderateInfo>();
- }
-
- }
- [MenuItem("GameObject/@(Alt+B)EdtiorExtemsion-Bind %B", false, 0)]
- public static void Bind()
- {
- GameObject currentGameObject = Selection.gameObjects.First();
- if (currentGameObject == null)
- {
- Debug.LogError("请选择Gameobject");
- return;
- }
- var view = currentGameObject.GetComponent<UIMark>();
- if (!view)
- {
- currentGameObject.AddComponent<UIMark>();
- }
-
- }
- private void OnGUI()
- {
- GUILayout.BeginHorizontal();
- GUILayout.Label("NameSpace");
- NamespaceSettingsData.Namespace = GUILayout.TextField(NamespaceSettingsData.Namespace);
- GUILayout.EndHorizontal();
- }
-
-
- static List<UIMarkInfo> uIMarkInfos = new List<UIMarkInfo>();
-
- [MenuItem("GameObject/@(Alt+C)EdtiorExtemsion-CreateCode %C", true, 0)]
- static bool ValidateCreateCode()
- {
- Debug.Log("Create Code");
- GameObject currentGameObject = Selection.gameObjects.First();
- if (currentGameObject == null)
- {
- Debug.LogError("请选择Gameobject");
- return false;
- }
- return currentGameObject.GetComponent<ViewMark>();
-
- }
-
- [MenuItem("GameObject/@EdtiorExtemsion-CreateCode", false, 0)]
- static void CreateCode()
- {
- Debug.Log("Create Code");
- GameObject currentGameObject = Selection.gameObjects.First();
- if (currentGameObject == null)
- {
- Debug.LogError("请选择Gameobject");
- return;
- }
- var mName = currentGameObject.name;
-
- var scriptsFolder = Application.dataPath + "/Scripts";
- var generateInfo = currentGameObject.GetComponent<CodeGenderateInfo>();
- if (generateInfo != null)
- {
- scriptsFolder = generateInfo.ScriptsFolder;
- }
- if (!Directory.Exists(scriptsFolder))
- {
- Directory.CreateDirectory(scriptsFolder);
- }
-
- uIMarkInfos.Clear();
- //搜索所有绑定
- SearchBinds("", currentGameObject.transform, uIMarkInfos);
-
-
- ComponentTemplate.Write(mName, scriptsFolder);
- ComponentDesignerTemplate.Write(mName, scriptsFolder, uIMarkInfos);
-
-
- EditorPrefs.SetString("Load", mName);
- //刷新目录
- AssetDatabase.Refresh();
- }
- static void SearchBinds(string basePath, Transform transform, List<UIMarkInfo> uIMarks)
- {
- var uiMark = transform.GetComponent<UIMark>();
- var isRoot = string.IsNullOrEmpty(basePath);
- if (uiMark && !isRoot)
- {
- uIMarks.Add(new UIMarkInfo() { FindPath = basePath, Name = transform.name, ComponentName = uiMark.ComponentName });
- }
- foreach (Transform childTrans in transform)
- {
- SearchBinds(isRoot ? childTrans.name : basePath + "/" + childTrans.name, childTrans, uIMarks);
- }
- }
- //系统的事件 DidReloadScripts 编译完成以后就会调用
- //将此属性添加到方法中,以便在重新加载脚本后获得通知。
- //DidReloadScript有一个提供订单索引的选项。这允许您更改调用回调的顺序。(Builtin回调的值始终为0)。
- [DidReloadScripts]
- static void AddComponent2GameObject()
- {
- Debug.Log("DidReloadScripts" + System.DateTime.Now);
- string generateClassGame = EditorPrefs.GetString("Load");
-
- Debug.Log(generateClassGame);
- if (string.IsNullOrWhiteSpace(generateClassGame))
- {
- Debug.Log("不进行操作");
- EditorPrefs.DeleteKey("Load");
- }
- else
- {
- Debug.Log("继续操作");
- // 1.获取当前项目中所有的 assembly (可以理解为 代码编译好的 dll)
- var assemblies = AppDomain.CurrentDomain.GetAssemblies();
- // 2.获取编辑器环境(dll)
- var defaultAssetBly = assemblies.First(assembly => assembly.GetName().Name == "Assembly-CSharp");
- //添加Namespace
- var typeName = NamespaceSettingsData.Namespace + "." + generateClassGame;
- Debug.Log(typeName);
- Type type = defaultAssetBly.GetType(typeName);
- Debug.Log(type);
- if (type == null)
- {
- Debug.Log("编译失败~");
- return;
- }
- var currentGameObject = GameObject.Find(generateClassGame);
- var scriptComponent = currentGameObject.GetComponent(type);
- if (!scriptComponent)
- {
- scriptComponent = currentGameObject.AddComponent(type);
- }
- var serialiedScript = new SerializedObject(scriptComponent);
- uIMarkInfos.Clear();
- //搜索所有绑定
- SearchBinds("", currentGameObject.transform, uIMarkInfos);
- foreach (UIMarkInfo markInfo in uIMarkInfos)
- {
- // var name=
- var name =markInfo.Name;
- serialiedScript.FindProperty(name).objectReferenceValue = currentGameObject.transform.Find(markInfo.FindPath).gameObject;
- Debug.Log(markInfo.FindPath);
- }
- var codeGenerateInfo = currentGameObject.GetComponent<CodeGenderateInfo>();
- if (codeGenerateInfo != null)
- {
- serialiedScript.FindProperty("ScriptsFolder").stringValue = codeGenerateInfo.ScriptsFolder;
-
- var generatePrefab = codeGenerateInfo.GeneratePrefab;
- var prefabForder = codeGenerateInfo.PrefabFolder;
- serialiedScript.FindProperty("PrefabFolder").stringValue = prefabForder;
- serialiedScript.FindProperty("GeneratePrefab").boolValue = generatePrefab;
- var fullPrefabFolder = prefabForder.Replace("Assets", Application.dataPath);
- serialiedScript.ApplyModifiedPropertiesWithoutUndo();
- if (codeGenerateInfo.GetType() == type)
- {
- }
- else
- {
- DestroyImmediate(codeGenerateInfo);
- }
- if (generatePrefab)
- {
- if (!Directory.Exists(fullPrefabFolder))
- {
- Directory.CreateDirectory(fullPrefabFolder);
- }
- // bool isFinish = false; //两种方法都可以
- // PrefabUtility.SaveAsPrefabAsset(currentGameObject, fullPrefabFolder + "/" + currentGameObject.name + ".Prefab", out isFinish);
- // Debug.LogFormat("保存预制体【{0}】", isFinish ? "成功" : "失败");
- PrefabUtility.SaveAsPrefabAssetAndConnect(currentGameObject, fullPrefabFolder + "/" + currentGameObject.name + ".prefab", InteractionMode.AutomatedAction);
- }
- }
- else
- {
- serialiedScript.FindProperty("ScriptsFolder").stringValue = "Assets/Scripts";
- serialiedScript.ApplyModifiedPropertiesWithoutUndo();
- }
- AssetDatabase.Refresh();
-
- EditorPrefs.DeleteKey("Load");
- }
- }
- }
- public class ComponentDesignerTemplate
- {
- public static void Write(string name, string scriptsFolder, List<UIMarkInfo> uIMarkInfos)
- {
- var scriptFile = string.Format("{0}/{1}.Designer.cs", scriptsFolder, name);
-
- // if (File.Exists(scriptFile))
- // {
- // File.Delete(scriptFile);
- // }
-
- StreamWriter writer = File.CreateText(scriptFile);
- writer.WriteLine("\tusing UnityEngine;");
- writer.WriteLine();
- writer.WriteLine("\t//1.请在菜单编辑器扩展/NamespaceSetting 设置命名空间");
- writer.WriteLine("\t//2.命名空间更改后 生成代码后 需要吧逻辑代码文件(非Designer)的命名空间手动更改");
- writer.WriteLine($"\tnamespace {NamespaceSettingsData.Namespace}");
- writer.WriteLine("\t{");
- writer.WriteLine($"\t\tpublic partial class {name} ");
- writer.WriteLine("\t\t{");
- foreach (UIMarkInfo uiMarkInfo in uIMarkInfos)
- {
- writer.WriteLine($"\t\tpublic {uiMarkInfo.ComponentName} { uiMarkInfo.Name};");
- }
- writer.WriteLine();
- writer.WriteLine("\t\t}");
- writer.WriteLine("\t}");
- writer.Close();
- }
- }
- public class ComponentTemplate
- {
- public static void Write(string name, string scriptsFolder)
- {
- var scriptFile = string.Format("{0}/{1}.cs", scriptsFolder, name);
- if (File.Exists(scriptFile))
- {
- return;
- }
- StreamWriter writer = File.CreateText(scriptFile);
- //保证每次生成的东西都不一样 就会执行编译操作
- writer.WriteLine($"//Generate ID:{Guid.NewGuid().ToString()}");
- writer.WriteLine("\tusing UnityEngine;");
- writer.WriteLine("\tusing EditorExtension;");
- writer.WriteLine();
- writer.WriteLine("\t//1.请在菜单编辑器扩展/NamespaceSetting 设置命名空间");
- writer.WriteLine("\t//2.命名空间更改后 生成代码后 需要吧逻辑代码文件(非Designer)的命名空间手动更改");
- writer.WriteLine($"\tnamespace {NamespaceSettingsData.Namespace} ");
- writer.WriteLine("\t{");
- writer.WriteLine($"\t\tpublic partial class {name} : CodeGenderateInfo");
- writer.WriteLine("\t\t{");
- writer.WriteLine("\t\tvoid Start()");
- writer.WriteLine("\t\t{");
- writer.WriteLine("\t\t//Code here");
- writer.WriteLine("\t\t}");
- writer.WriteLine("\t\t}");
- writer.WriteLine();
- writer.WriteLine("\t}");
- writer.Close();
- }
- }
- public class UIMarkInfo
- {
- public string FindPath;
- public string ComponentName;
- public string Name;
-
- }
-
- public class NamespaceSettingsData
- {
- private readonly static string NAMESPACE_KEY = Application.productName + "@NAMESPACE";
- public static string Namespace
- {
- get
- {
- var retNamespace = EditorPrefs.GetString(NAMESPACE_KEY, "DefaultNamespace");
- return string.IsNullOrEmpty(retNamespace) ? "DefaultNamespace" : retNamespace;
- }
- set { EditorPrefs.SetString(NAMESPACE_KEY, value); }
- }
- public static bool IsDefaultNamespace => Namespace == "DefaultNamespace";
- }
UIMark脚本 标记
- using UnityEngine;
- [AddComponentMenu("EditorExension/Mark")]
- public class UIMark : MonoBehaviour
- {
- public enum GetComponentType
- {
-
- Transform,
- MeshRenderer,
- RectTransform,
- Rigibody,
- BoxCollider,
- MeshCollider,
-
-
- }
- public GetComponentType componentType = GetComponentType.Transform;
-
- public string ComponentName
- {
-
- get
- {
- // if (GetComponent<MeshRenderer>())
- // {
- // return "MeshRenderer";
- // }
-
- return componentType.ToString();
- }
- }
- }
ViewMark Gameobject必须挂载 ViewMark才能进行生成脚本
- using UnityEngine;
- public class ViewMark : MonoBehaviour
- {
- }
生成脚本的配置脚本 脚本路径 生成prefab 生成brefab的路径
- using UnityEngine;
- namespace EditorExtension
- {
- [ExecuteInEditMode]
- public class CodeGenderateInfo : MonoBehaviour
- {
- [HideInInspector]
- public string ScriptsFolder;
- [HideInInspector]
-
- public string PrefabFolder;
- [HideInInspector]
-
- public bool GeneratePrefab = false;
- private void Awake()
- {
- ScriptsFolder = "Assets/Scripts";
- PrefabFolder = "Assets/Prefabs";
- }
- }
- }
修改挂载代码的脚本样式 依然放在Editor下
-
- using UnityEditor;
- using UnityEngine;
-
- namespace EditorExtension
- {
- [CustomEditor(typeof(CodeGenderateInfo), editorForChildClasses: true)]
- public class CodeGenerateInfoInspector : Editor
- {
-
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- var codeGenerateInfo = target as CodeGenderateInfo;
- GUILayout.BeginVertical("box");
- GUILayout.Label("代码生成部分", new GUIStyle()
- {
- fontSize = 20,
- fontStyle = FontStyle.Bold
- });
- GUILayout.BeginHorizontal();
- GUILayout.Label("Scripts Generate Folder : ", GUILayout.Width(150));
- codeGenerateInfo.ScriptsFolder = GUILayout.TextField(codeGenerateInfo.ScriptsFolder);
- GUILayout.EndHorizontal();
-
- GUILayout.BeginHorizontal();
- GUILayout.Label("GeneratePrefab :", GUILayout.Width(150));
- codeGenerateInfo.GeneratePrefab = GUILayout.Toggle(codeGenerateInfo.GeneratePrefab, "Generete Perfab");
- GUILayout.EndHorizontal();
- if (codeGenerateInfo.GeneratePrefab)
- {
- GUILayout.BeginHorizontal();
- GUILayout.Label("Prefab Generate Folder : ", GUILayout.Width(150));
- codeGenerateInfo.PrefabFolder = GUILayout.TextField(codeGenerateInfo.PrefabFolder);
- GUILayout.EndHorizontal();
- }
-
- GUILayout.EndVertical();
-
- }
- }
- }
案例2最终效果如下:
- using UnityEditor;
- using UnityEngine;
- public class ReopenProject
- {
- [MenuItem("编辑器扩展/3.(Alt+R)ReopenProject &R", false, 3)]
- static void DOReopenProject()
- {
- EditorApplication.OpenProject(Application.dataPath.Replace("Assets", string.Empty));
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。