学习目标:入门编辑器并实现几个简单的工具
菜单编辑器
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)
{
//UIRoot
var uiRootObj = new GameObject("UIRoot");
var uirootScript = uiRootObj.AddComponent<UIRoot>();
uiRootObj.layer = LayerMask.NameToLayer("UI");
//Canvas
var canvas = new GameObject("Canvas");
canvas.transform.SetParent(uiRootObj.transform);
canvas.AddComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
// CanvasScaler
var canvasScaler = canvas.AddComponent<CanvasScaler>();
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(width, height);
canvas.AddComponent<GraphicRaycaster>();
canvas.layer = LayerMask.NameToLayer("UI");
// EventSystem
var eventSystem = new GameObject("EventSystem");
eventSystem.transform.SetParent(uiRootObj.transform);
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
eventSystem.layer = LayerMask.NameToLayer("UI");
// Bg
var bgObj = new GameObject("Bg");
bgObj.AddComponent<RectTransform>();
bgObj.transform.SetParent(canvas.transform);
bgObj.transform.localPosition = Vector3.zero;
uirootScript.Bg = bgObj.transform;
// Common
var commonObj = new GameObject("Common");
commonObj.AddComponent<RectTransform>();
commonObj.transform.SetParent(canvas.transform);
commonObj.transform.localPosition = Vector3.zero;
uirootScript.Common = commonObj.transform;
// PopUI
var popUp = new GameObject("PopUp");
popUp.AddComponent<RectTransform>();
popUp.transform.SetParent(canvas.transform);
popUp.transform.localPosition = Vector3.zero;
uirootScript.PopUp = popUp.transform;
// Forward
var 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();
// 制作 prefab
var 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博客