学习目标:入门编辑器并实现几个简单的工具
菜单编辑器
MenuItem
[MenuItem("编辑器拓展/MenuItem")]static void MenuItem(){Debug.Log("这是编辑器拓展");}
}
案例 1:在场景中的 GameObject 设置
- 1. @设置面板
- 2. @直接创建 GameObject 结构
- 3. @生成的 GameObject 结构进行赋值
- 4. @制作成 Prefab
当场景中没有UIRoot物体时方法可用,有了之后方法不启用
当第二个参数是true时表示是一个验证函数,用来验证这个功能是否启用
[MenuItem("编辑器拓展/SetupUIRoot", true)]static bool ValidateUIRoot(){var gameObject = GameObject.Find("UIRoot");return !gameObject;}[MenuItem("编辑器拓展/SetupUIRoot", false)]static void SetupUIRoot(){Debug.Log("这是编辑器拓展");var uiRootObj = new GameObject("UIRoot");var canvas = new GameObject("Canvas");canvas.transform.SetParent(uiRootObj.transform);canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;canvas.AddComponent<CanvasScaler>();canvas.AddComponent<GraphicRaycaster>();var eventSystem = new GameObject("EventSystem");eventSystem.transform.SetParent(uiRootObj.transform);eventSystem.AddComponent<EventSystem>();eventSystem.AddComponent<StandaloneInputModule>();}
第3个参数:优先级,主要影响菜单出现的先后顺序,不填默认是1000. 值越小,出现在越上层的位置。当一个菜单的优先级 - 它上一个菜单的优先级 >= 11,菜单之间还能看到分界线
快捷键 :可以为MenuItem可以添加快捷键。ctrl,shift,alt 都有对应的字符,比如表示shift键的字符是#。那么快捷键shift + q,可以写成 #q。
//注意:路径和快捷键之间有个空格[MenuItem("Learn/Log #q",false)]public static void Log(){Debug.Log(1);}
如果你想直接按一个键就触发,不想多按ctrl/shift/alt,那么可以用 ‘_’来表示。比如你想按F1就触发,那么可以写成 _F1
在Hierarchy层级窗口增加右键菜单
MenuItem还可以增加到右键菜单里面。其实用法和上面差不多,但有两个要求。
- MenuItem(“GameObject/xxxx”,false,0)命名时,名字必须以GameObject/开头
在Assets资源窗口增加右键菜单
- [MenuItem(“Assets/自定义菜单_Assets”)] 命名时,以Assets/开头 优先级可以不填
[MenuItem("Assets/自定义菜单_Assets")]public static void CustomMenu_Assets(){}
创建一个窗口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.IO;public class CreateUIRootWindow : EditorWindow
{[MenuItem("编辑器拓展/SetupUIRoot", true)]static bool ValidateUIRoot(){var gameObject = GameObject.Find("UIRoot");return !gameObject;}private string mWidth = "720";private string mHeight = "1280";private void OnGUI(){GUILayout.BeginHorizontal();GUILayout.Label("width:", GUILayout.Width(45));mWidth = GUILayout.TextField(mWidth);GUILayout.Label("x", GUILayout.Width(10));GUILayout.Label("height", GUILayout.Width(50));mHeight = GUILayout.TextField(mHeight);GUILayout.EndHorizontal();if(GUILayout.Button("Setup")){var width = float.Parse(mWidth);var height = float.Parse(mHeight);Setup(width, height);Close();}}[MenuItem("编辑器拓展/SetupUIRoot", false)]static void SetupUIRoot(){var window = GetWindow<CreateUIRootWindow>();window.Show();}static void Setup(float width,float height){//UIRootvar uiRootObj = new GameObject("UIRoot");var uirootScript = uiRootObj.AddComponent<UIRoot>();uiRootObj.layer = LayerMask.NameToLayer("UI");//Canvasvar canvas = new GameObject("Canvas");canvas.transform.SetParent(uiRootObj.transform);canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;// CanvasScalervar canvasScaler = canvas.AddComponent<CanvasScaler>();canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;canvasScaler.referenceResolution = new Vector2(width, height);canvas.AddComponent<GraphicRaycaster>();canvas.layer = LayerMask.NameToLayer("UI");// EventSystemvar eventSystem = new GameObject("EventSystem");eventSystem.transform.SetParent(uiRootObj.transform);eventSystem.AddComponent<EventSystem>();eventSystem.AddComponent<StandaloneInputModule>();eventSystem.layer = LayerMask.NameToLayer("UI");// Bgvar bgObj = new GameObject("Bg");bgObj.AddComponent<RectTransform>();bgObj.transform.SetParent(canvas.transform);bgObj.transform.localPosition = Vector3.zero;uirootScript.Bg = bgObj.transform;// Commonvar commonObj = new GameObject("Common");commonObj.AddComponent<RectTransform>();commonObj.transform.SetParent(canvas.transform);commonObj.transform.localPosition = Vector3.zero;uirootScript.Common = commonObj.transform;// PopUIvar popUp = new GameObject("PopUp");popUp.AddComponent<RectTransform>();popUp.transform.SetParent(canvas.transform);popUp.transform.localPosition = Vector3.zero;uirootScript.PopUp = popUp.transform;// Forwardvar forwardObj = new GameObject("Forward");forwardObj.AddComponent<RectTransform>();forwardObj.transform.SetParent(canvas.transform);forwardObj.transform.localPosition = Vector3.zero;uirootScript.Forward = forwardObj.transform;var uirootScriptSerializedObj = new SerializedObject(uirootScript);uirootScriptSerializedObj.FindProperty("mRootCanvas").objectReferenceValue = canvas.GetComponent<Canvas>();uirootScriptSerializedObj.ApplyModifiedPropertiesWithoutUndo();// 制作 prefabvar savedFolder = Application.dataPath + "/Resources";if (!Directory.Exists(savedFolder)){Directory.CreateDirectory(savedFolder);}var savedFilePath = savedFolder + "/UIRoot.prefab";PrefabUtility.SaveAsPrefabAssetAndConnect(uiRootObj, savedFilePath, InteractionMode.AutomatedAction);}
}
效果:
自动生成代码
案例2 : 根据GameObject结构生成代码工具
- 在 Hierarchy上生成菜单
- 生成脚本
- 添加标记
- 搜索并生成脚本
学习课程链接:siki学院课程,直接贴链接会被识别成广告
Unity编辑器拓展(一)-MenuItem的使用_unity menuitem-CSDN博客