使用场景

顶部菜单栏添加菜单项

[MenuItem("项目工具/菜单项1")]
public static void Test1()
{
    
}

[MenuItem("项目工具/菜单项2")]
public static void Test2()
{
    
}

[MenuItem("项目工具/菜单项3")]
public static void Test3()
{
    
}

当方法的priority参数之间相差10个级别以上时就会显示一个间隔线

[MenuItem("项目工具/菜单项1",false,1)]
public static void Test1()
{
    
}

[MenuItem("项目工具/菜单项2",false,12)]
public static void Test2()
{
    
}

[MenuItem("项目工具/菜单项3",false,23)]
public static void Test3()
{
    
}

Hierarchy窗口右键菜单项

[MenuItem("GameObject/Create SB",false,100)]
static void Speak()
{
    Debug.Log("Hello World!");
}

Project窗口右键菜单项

[MenuItem("Assets/我的工具")]
public static void Test4()
{
    Debug.Log(("Hello World!"));
}

自定义编辑器窗口界面

using UnityEditor;
using UnityEngine;

public class EditorTool:EditorWindow
{
    [MenuItem("我的工具/EditorGUIWindow")]
    public static void OpenEGL()
    {
        //可改变大小的窗口
        var window = EditorWindow.GetWindow<EditorTool>();
        
        //设置窗口最小尺寸
        window.minSize = new Vector2(500, 500);
        //设置窗口最大尺寸
        window.maxSize = new Vector2(800, 800);
        //设置窗口标题
        window.titleContent = new GUIContent("我的窗口");
        //打开窗口
        window.Show();  
    }

    //窗口启动时,会调用此方法
    private void OnEnable()
    {
        //OnEnable()方法是一个比较重要的方法,可在这里进行相关数据的初始化
    }
   
    //实时绘制UI
    private void OnGUI()
    {
        //OnGUI()方法则是实时的进行控件绘制,窗口控件绘制也就在这里进行代码编写
    }

    //界面隐藏时触发
    private void OnDisable()
    {
        
    }
    
    //界面销毁时触发
    private void OnDestroy()
    {
        
    }
}

挂载脚本组件扩展

 代码例子

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MapComponent : MonoBehaviour
{
    public string comId;      //组件ID

    public string comName;    //组件名称

    public bool isBlock;      //是否阻挡

    public Sprite comSprite;  //组件图片

    public  ComponentType comType;
    
   

    public string Word;
    
    // 宝箱	
    public string dropId;
    

    // 提灯	


    // 陶罐	


    // 石柱	


    // 枯木柱	


    // 按压机关	
    public bool isActive;       //是否激活

    // 烛台	
    public float continueTime;  //激活持续时间

    public GameObject nextCom;  //关联的下级组件

    

    // 拉杆机关	
    public bool isPull;             //拉杆开关

    // 门	
    public bool isOpen;             //是否打开或关闭

    public string triggerCondition; //触发条件

    // 弹力机关	
    

    // 收集奖励机关	
    public string matchPropId;    //需要的道具ID

    public int matchPropCount; //需要的道具数量·1
    // 锁	


    // 出生点	


    // 终点	


    // NPC	
    public string talkId; //对话ID
    public string taskId; //任务ID

    // 怪物	



}
using UnityEditor;
using UnityEngine;

public enum ComponentType
{
    宝箱,	
    提灯,	
    陶罐,	
    石柱,	
    枯木柱,	
    按压机关,	
    烛台,	
    拉杆机关,	
    门,
    弹力机关,	
    收集奖励机关,	
    锁,	
    出生点,	
    终点,	
    Npc,	
    怪物,	
}

[CustomEditor(typeof(MapComponent))]
public class ComponentExtesion : Editor
{
    private MapComponent mc;
    
    private void OnEnable()
    {//获取当前编辑自定义Inspector的对象
        mc = (MapComponent)target;
    }
    
    //执行这一个函数来自定义检视面板
    public override void OnInspectorGUI()
    {
        mc.comId = EditorGUILayout.TextField("组件ID", mc.comId);
        mc.comName = EditorGUILayout.TextField("组件名字", mc.comName);

        mc.comSprite = EditorGUILayout.ObjectField(mc.comSprite, typeof(Sprite), false)as Sprite;

        mc.comType = (ComponentType)EditorGUILayout.EnumPopup("枚举选择", mc.comType);
        
        switch (mc.comType)
        {
            case ComponentType.宝箱:
                mc.dropId = EditorGUILayout.TextField("掉落ID", mc.dropId);
                mc.matchPropId = EditorGUILayout.TextField("需要的道具ID", mc.matchPropId);
                break;
            case ComponentType.提灯:
                break;
            case ComponentType.陶罐:
                break;
            case ComponentType.石柱:
                break;
            case ComponentType.枯木柱:
                break;
            case ComponentType.按压机关:
                mc.isActive = EditorGUILayout.Toggle("是否激活", mc.isActive);
                mc.nextCom = EditorGUILayout.ObjectField("关联的下级组件",mc.nextCom,typeof(GameObject),false)as GameObject;
                break;
            case ComponentType.烛台:
                mc.isActive = EditorGUILayout.Toggle("是否激活", mc.isActive);
                mc.continueTime = EditorGUILayout.FloatField("激活持续时间", mc.continueTime);
                mc.nextCom = EditorGUILayout.ObjectField("关联的下级组件",mc.nextCom,typeof(GameObject),false)as GameObject;
                break;
            case ComponentType.拉杆机关:
                mc.isPull = EditorGUILayout.Toggle("是否开启", mc.isPull);
                mc.nextCom = EditorGUILayout.ObjectField("关联的下级组件",mc.nextCom,typeof(GameObject),false)as GameObject;
                break;
            case ComponentType.门:
                mc.isOpen = EditorGUILayout.Toggle("是否开启", mc.isOpen);
                mc.continueTime = EditorGUILayout.FloatField("激活持续时间", mc.continueTime);
                mc.triggerCondition = EditorGUILayout.TextField("触发条件", mc.triggerCondition);
                break;
            case ComponentType.弹力机关:
                break;
            case ComponentType.收集奖励机关:
                mc.matchPropId = EditorGUILayout.TextField("需要的道具ID", mc.matchPropId);
                mc.matchPropCount = EditorGUILayout.IntField("需要的道具数量", mc.matchPropCount);
                
                break;
            case ComponentType.锁:
                mc.matchPropId = EditorGUILayout.TextField("需要的道具ID", mc.matchPropId);
                mc.matchPropCount = EditorGUILayout.IntField("需要的道具数量", mc.matchPropCount);
                break;
            case ComponentType.出生点:
                break;
            case ComponentType.终点:
                break;
            case ComponentType.Npc:
                mc.talkId = EditorGUILayout.TextField("对话ID", mc.talkId);
                mc.taskId = EditorGUILayout.TextField("任务ID", mc.taskId);
                break;
            case ComponentType.怪物:
                break;
        }
    }
}

相关API

GUILayout

GUILayout系统可以在场景中使用,也可以在编辑器中使用。

普通按钮

(Button)

 private void OnGUI()
 {
     if (GUILayout.Button("开始游戏"))
     {
         Debug.Log("开始游戏");
     }
 }

修改按钮字体大小

GUIStyle exportButtonStyle = new GUIStyle(GUI.skin.button);
exportButtonStyle.fontSize = 20;
if (GUILayout.Button("开始压缩",exportButtonStyle,GUILayout.Height(40)))
{
}

选择按钮

(SelectionGrid)

private int index; //定义多按钮选择的index
//定义多按钮的名称
private string[] buttonNames = new string[] { "First", "Second", "Third","Forth" }; 

private void OnGUI()
 {
     index = GUILayout.SelectionGrid(index, buttonNames, 2);
 }

工具栏

(Toolbar)

int toolbarInt = 0;
string[] toolbarStrings = {"Toolbar1", "Toolbar2", "Toolbar3"};

void OnGUI()
{
    toolbarInt = GUILayout.Toolbar(toolbarInt, toolbarStrings);
}

开关

(Toggle)

private bool toggleValue;

void OnGUI()
{
    toggleValue = GUILayout.Toggle(toggleValue, "This is a toggle");
}

文本标签

(Label)

GUILayout.Label("我是一个标签");

文本输入框

(TextField、TextArea)

private string singleText = "单行文本";
private string areaText = "多行文本";

void OnGUI()
{
    //Textfield 不支持多行编辑,回车之后没反应。
    singleText = GUILayout.TextField(singleText);
    //TextArea 支持多行编辑,就是回车之后文本也能换行。
    areaText = GUILayout.TextArea(areaText); 
}

密码文本

(PasswordField)

string passwordToEdit = "";

void OnGUI()
{
   passwordToEdit = GUILayout.PasswordField(passwordToEdit, '*', 10);
}

滑动条

(HorizontalSlider、VerticalSlider)

private float hSbarValue;
private float vSbarValue;

void OnGUI()
{
    hSbarValue = GUILayout.HorizontalSlider(hSbarValue, 0, 100, GUILayout.Width(200));
    vSbarValue = GUILayout.VerticalSlider(vSbarValue, 0, 200,GUILayout.Height(200));
}

滚动条

(ScrollBar)

private float horizontalValue = 0; //滑动条数值
private float verticalValue = 0; //滑动条数值
private float blockSize = 10; //滑动块大小
private float leftValue = 0; //最左侧/最上侧数值
private float rightValue = 100; //最右侧/最下侧数值

void OnGUI()
{
   horizontalValue = 
       GUILayout.HorizontalScrollbar
       (horizontalValue, blockSize, leftValue, rightValue, GUILayout.Width(300));
   verticalValue = 
       GUILayout.VerticalScrollbar
       (verticalValue, blockSize, leftValue, rightValue, GUILayout.Height(100));
}

方形区域

(Box)

void OnGUI()
{
   GUILayout.Box("Box Area", GUILayout.Width(200), GUILayout.Height(200));
}

滑动视图

(ScrollView)

GUILayout.BeginScrollView,GUILayout.EndScrollView

//定义滑动窗口当前滑动值,如果不使用这个vector2,滑动窗口将无法滑动
private Vector2 scrollViewRoot; 

void OnGUI()
{
    //由于区域是400x400,有3个高度为200的button,3*200>400,视图内容会越界,滑动窗口才有意义。
    GUILayout.BeginArea(new Rect(0, 0, 400, 400)); //定义可视化区域
    scrollViewRoot = GUILayout.BeginScrollView(scrollViewRoot); //定义滑动视图
    GUILayout.Button("Buttons", GUILayout.Height(200)); //定义组件1,高度200
    GUILayout.Button("Buttons", GUILayout.Height(200)); //定义组件2,高度200
    GUILayout.Button("Buttons", GUILayout.Height(200)); //定义组件3,高度200
    GUILayout.EndScrollView(); //结束滑动窗口
    GUILayout.EndArea();// 结束区域定义
}

空白间隔

(Space、FlexibleSpace)

GUILayout.Space(float pixels)

GUILayout.FlexibleSpace()

水平/垂直布局

(Horizontal/Vertical)

GUILayout.BeginHorizontal

GUILayout.EndHorizontal

GUILayout.BeginVertical

GUILayout.EndVertical

//值得注意的是,布局方法一般需要成对使用:定义开始/结束,否则会在布局上出现奇怪的bug

GUILayout.BeginHorizontal(); //开始水平布局
GUILayout.Button("Horizontal Button No.1"); //组件1
GUILayout.Button("Horizontal Button No.2"); //组件2
GUILayout.EndHorizontal(); //结束水平布局

GUILayout.BeginVertical();//开始垂直布局
GUILayout.Button("Veritical Button No.1"); //组件1
GUILayout.Button("Veritical Button No.2"); //组件2
GUILayout.EndVertical(); //结束垂直布局

控件属性

(GUILayoutOption)

GUILayout.Width(float width) // 设置控件的宽度

GUILayout.Height(float height) // 设置控件的高度

GUILayout.MinWidth(float width) // 设置控件的最小宽度

GUILayout.MinHeight(float height) // 设置控件的最小高度

GUILayout.MaxWidth(float width)// 设置控件的最大宽度

GUILayout.MaxHeight(float width) // 设置控件的最大高度

GUILayout.ExpandHeight(bool expand) // 是否允许自动扩展高度

GUILayout.ExpandWidth(bool expand) // 是否允许自动扩展宽度

EditorGUILayout

EditorGUILayout系统不可以在场景中使用,只能在编辑器中使用。

按下触发按钮

 if (EditorGUILayout.DropdownButton(new GUIContent(m_itemString), FocusType.Keyboard))
    {
      var alls = new string[4] { "A", "B", "C", "D" };
      GenericMenu _menu = new GenericMenu();
      foreach (var item in alls)
      {
        if (string.IsNullOrEmpty(item))
        {
          continue;
        }
        //添加菜单
        _menu.AddItem(new GUIContent(item), m_itemString.Equals(item), OnValueSelected, item);
      }
      _menu.ShowAsContext();//显示菜单
    }

对象域

(ObjectField)

private GameObject m_objectValue; //定义Object
//第一个参数: 目标Object
//第二个参数: Object的类型
//第三个参数: 是否允许赋值场景对象(一般是赋值Project中的Asset资源对象)
//最后需要一个【as】进行类型转换
m_objectValue = 
    EditorGUILayout.ObjectField(m_objectValue, typeof(GameObject), true) as GameObject;

目标类型也可以是其他类型,比如Material、Texture等等

  
  public Texture tex;

tex = (Texture)EditorGUILayout.ObjectField("启动背景图/视频封面", tex, typeof(Texture2D), false);

整数域

(IntField)

private int m_intValue; //定义修改内容;

m_intValue = EditorGUILayout.IntField("整型输入框", m_intValue); //Title + Value

鼠标悬停显示提示字段

var totalMemoryFieldDesc = new GUIContent("最大内存(MB)", "预留的初始内存值,评估游戏最大内存峰值进行设置,消除内存自动增长带来的峰值尖刺。");
memorySize = EditorGUILayout.IntField(totalMemoryFieldDesc, memorySize);

浮点数域

private float m_floatValue;

void OnGUI(){
    m_floatValue = EditorGUILayout.FloatField("Float 输入:", m_floatValue);
}

字符串域

private string m_textValue;

void OnGUI(){
    m_textValue = EditorGUILayout.TextField("Text输入:", m_textValue);
}

向量域

private Vector2 m_vec2;
private Vector3 m_vec3;
private Vector4 m_vec4;
private Bounds m_bounds;
private BoundsInt m_boundsInt;

void OnGUI(){
    //二维向量
    m_vec2 = EditorGUILayout.Vector2Field("Vec2输入: ", m_vec2);
    //三维向量
    m_vec3 = EditorGUILayout.Vector3Field("Vec3输入: ", m_vec3);
    //四维向量
    m_vec4 = EditorGUILayout.Vector4Field("Vec4输入: ", m_vec4);
    //创建用于输入 Bounds 的 Center 和 Extents 字段。
    m_bounds = EditorGUILayout.BoundsField("Bounds输入: ", m_bounds);
    //创建用于输入 BoundsInt 的 Position 和 Size 字段。
    m_boundsInt = EditorGUILayout.BoundsIntField("Bounds输入: ", m_boundsInt);
}

标签文本域

(LabelField)

EditorGUILayout.LabelField("文本标题", "文本内容");

标签/层级选择域

TagField/LayerField

private int m_layer;
private string m_tag;

//和Inspector面板的数据同步
void OnGUI(){
    m_layer = EditorGUILayout.LayerField("层级选择", m_layer);
    m_tag = EditorGUILayout.TagField("标签选择", m_tag);
}

颜色域

(ColorField)

private Color m_color;
private GUIContent colorTitle = new GUIContent("颜色选择");

void OnGUI(){
    //第一个参数: GUIContent,通常拿来作为Title
    //第二个参数: Color,目标修改数据
    //第三个参数: bool ,是否显示拾色器
    //第四个参数: bool ,是否显示透明度通道
    //第五个参数: bool ,是否支持HDR。
    m_color = EditorGUILayout.ColorField(colorTitle, m_color, true, true, true);
}

动画曲线域

(CurveField)

private AnimationCurve m_curve = AnimationCurve.Linear(0, 0, 1, 1);

void OnGUI(){
    m_curve = EditorGUILayout.CurveField("动画曲线:", m_curve);
}

单选枚举

(EnumPopup)

private enum TutorialEnum
{
    One,
    Two,
    Three
}
private TutorialEnum m_enum;

void OnGUI(){
    m_enum = (TutorialEnum)EditorGUILayout.EnumPopup("枚举选择", m_enum);
}

单选整数枚举

多选枚举

(EnumFlagsField)

private enum TutorialEnum
{
    One,
    Two,
    Three
}
private TutorialEnum m_enum;


void OnGUI(){
    m_enum = (TutorialEnum)EditorGUILayout.EnumPopup("枚举选择", m_enum);
}

折叠

Foldout

private bool foldOut;

void OnGUI(){
    foldOut = EditorGUILayout.Foldout(foldOut, "折叠栏");
    if (foldOut) //只有foldout为true时,才会显示下方内容,相当于“折叠”了。
    {
        EditorGUILayout.LabelField("这是折叠标签内容");
        GUIContent colorTitle = new GUIContent("颜色选择");
        m_color = EditorGUILayout.ColorField(colorTitle, m_color, true, true, true);
        m_curve = EditorGUILayout.CurveField("动画曲线:", m_curve);
        m_enum = (TutorialEnum)EditorGUILayout.EnumPopup("枚举选择", m_enum);
    }
}

折叠组

FoldoutGroup

private bool foldOut;

void OnGUI(){
     foldOut = EditorGUILayout.BeginFoldoutHeaderGroup(foldOut, "折叠栏组");
    if (foldOut) //只有foldout为true时,才会显示下方内容,相当于“折叠”了。
    {
        EditorGUILayout.LabelField("这是折叠标签内容");
        GUIContent colorTitle = new GUIContent("颜色选择");
        m_color = EditorGUILayout.ColorField(colorTitle, m_color, true, true, true);
        m_curve = EditorGUILayout.CurveField("动画曲线:", m_curve);
        m_enum = (TutorialEnum)EditorGUILayout.EnumPopup("枚举选择", m_enum);
    }
    EditorGUILayout.EndFoldoutHeaderGroup(); //只不过这种折叠需要成对使用,不然会有BUG
}

这个组件和Foldout类似只是这个点击触发的范围为一个矩形条,而Foldout只是一个小点

开关

(Toggle、ToggleLeft)

private bool toggle;
private bool toggle1;

void OnGUI(){
        toggle = EditorGUILayout.Toggle("我是一个开关", toggle);
        toggle1 = EditorGUILayout.ToggleLeft("我也是一个开关", toggle1);
}

开关组

(ToggleGroup)

private bool toggle2;

void OnGUI(){
    toggle2 = EditorGUILayout.BeginToggleGroup("开关组", toggle2);
    EditorGUILayout.LabelField("------Input Field------");
    m_inputText = EditorGUILayout.TextField("输入内容:", m_inputText);
    toggle = EditorGUILayout.Toggle("我是一个开关", toggle);
    toggle1 = EditorGUILayout.ToggleLeft("我也是一个开关", toggle1);
    EditorGUILayout.EndToggleGroup();
}

当此开关组为false时,组内所有GUI组件不可选取/修改

滑动条

(Slider、IntSlider)

private float m_sliderValue;
private int m_sliderIntValue;

void OnGUI(){
    
    //第一个参数: string label 控件名称标签  
    //第二个参数: float value 滑动当前值  
    //第三个参数: float leftValue 滑动最小值   
    //第四个参数: float rightValue 滑动最大值
    m_sliderValue = EditorGUILayout.Slider("float滑动条", m_sliderValue, 0, 10);
    
    m_sliderIntValue = EditorGUILayout.IntSlider("整数值滑动条", m_sliderIntValue, 0, 10);
}

双滑块滑动条

MinMaxSlider

private float m_leftValue;
private float m_rightValue;

void OnGUI(){
   EditorGUILayout.MinMaxSlider
       ("双块滑动条", ref m_leftValue, ref m_rightValue, 0.25f, 10.25f);
   EditorGUILayout.FloatField("滑动左值:", m_leftValue);
   EditorGUILayout.FloatField("滑动右值:", m_rightValue);
}

帮助框

(HelpBox)

EditorGUILayout.HelpBox("一般提示,你应该这样做...", MessageType.Info);
EditorGUILayout.HelpBox("警告提示,你可能需要这样做...", MessageType.Warning);
EditorGUILayout.HelpBox("错误提示,你不能这样做...", MessageType.Error);

间隔

(Space、FlexibleSpace)

EditorGUILayout.LabelField("----上面的Label----");
EditorGUILayout.Space(10); //进行10个单位的间隔
EditorGUILayout.LabelField("----下面的Label----");

EditorGUILayout.BeginHorizontal(); //开始水平布局
GUILayout.Button("1号button", GUILayout.Width(200)); //固定button长度: 200
// 自动填充间隔,如果窗口宽600px,那这种写法就是:
//【左button:200px】【自动间隔:200px】【右button :200px】
GUILayout.FlexibleSpace(); 
GUILayout.Button("2号button", GUILayout.Width(200));//固定button长度: 200
EditorGUILayout.EndHorizontal(); //结束水平布局

GUIStyle

private GUIStyle defaultStyle = new GUIStyle(); //定义 GUIStyle

private void OnGUI()
{
    defaultStyle.fontSize = 10; //字体大小: 10
    defaultStyle.fontStyle = FontStyle.Normal; //字体样式:normal

    defaultStyle.alignment = TextAnchor.MiddleCenter; //字体对齐方式: 居中对齐
    defaultStyle.normal.textColor = Color.red; //字体颜色: 红色
    //绘制GUI组件,使用 defaultStyle
    EditorGUILayout.LabelField("这是红色字体", defaultStyle); 

    defaultStyle.alignment = TextAnchor.MiddleLeft; //字体对齐方式: 水平靠左,垂直居中
    defaultStyle.normal.textColor = Color.yellow; //字体颜色:黄色
    defaultStyle.fontSize = 20; //字体大小: 20
    EditorGUILayout.LabelField("这是黄色字体", defaultStyle); //绘制GUI组件

    defaultStyle.normal.textColor = Color.green; //字体颜色: 绿色
    defaultStyle.fontSize = 12; //字体大小 : 12
    defaultStyle.fontStyle = FontStyle.Bold;  //字体样式: Bold(加粗)
    EditorGUILayout.SelectableLabel("这是绿色字体", defaultStyle); //绘制GUI
}

调整按钮文本字体大小和颜色

GUIStyle delBtnStyle = new GUIStyle(GUI.skin.button);
delBtnStyle.normal.textColor = Color.red;
delBtnStyle.fontSize = 14;

unity脚本内置样式

Unity中的GUIStyle详解 - 简书

unity脚本内置样式 - 简书

using UnityEngine;
using UnityEditor;

public class GUIStyleViewer : EditorWindow
{
    Vector2 scrollPosition = new Vector2(0, 0);
    string search = "";
    GUIStyle textStyle;
    private static GUIStyleViewer window;
    [MenuItem("Tool/GUIStyleViewer1", false, 10)]

    private static void OpenStyleViewer()
    {
        window = GetWindow<GUIStyleViewer>(false, "内置GUIStyle");
    }

    void OnGUI()
    {
        if (textStyle == null)
        {
            textStyle = new GUIStyle("HeaderLabel");
            textStyle.fontSize = 25;
        }
        GUILayout.BeginHorizontal("HelpBox");
        GUILayout.Label("结果如下:", textStyle);
        GUILayout.FlexibleSpace();
        GUILayout.Label("Search:");
        search = EditorGUILayout.TextField(search);
        GUILayout.EndHorizontal();
        GUILayout.BeginHorizontal("PopupCurveSwatchBackground");
        GUILayout.Label("样式展示", textStyle, GUILayout.Width(300));
        GUILayout.Label("名字", textStyle, GUILayout.Width(300));
        GUILayout.EndHorizontal();
        scrollPosition = GUILayout.BeginScrollView(scrollPosition);

        foreach (var style in GUI.skin.customStyles)
        {
            if (style.name.ToLower().Contains(search.ToLower()))
            {
                GUILayout.Space(15);
                GUILayout.BeginHorizontal("PopupCurveSwatchBackground");
                if (GUILayout.Button(style.name, style, GUILayout.Width(300)))
                {
                    EditorGUIUtility.systemCopyBuffer = style.name;
                    Debug.LogError(style.name);
                }
                EditorGUILayout.SelectableLabel(style.name, GUILayout.Width(300));
                GUILayout.EndHorizontal();
            }
        }
        GUILayout.EndScrollView();
    }
}

GUI颜色

GUI.color = Color.red;
GUILayout.Button("红色Button");
GUI.color = Color.green;
EditorGUILayout.LabelField("绿色Label");
GUI.color = Color.yellow;
EditorGUILayout.IntField("黄色Int Field", 20);

禁用组件

float jumpHeight = 0f;

EditorGUI.BeginDisabledGroup(true);
jumpHeight = EditorGUILayout.FloatField("Jump Height", jumpHeight);
EditorGUI.EndDisabledGroup();

显示通知消息

ShowNotification(new GUIContent("消息内容"))

搜索栏样式

targetName = EditorGUILayout.TextField(targetName,new GUIStyle("SearchTextField"),GUILayout.Width(300));

AssetDatabase

资源刷新

AssetDatabase.Refresh();

查找资源

1、通过资源名称查找

AssetDatabase.FindAssets("资源名称");

2、通过资源标签查找

AssetDatabase.FindAssets("l:资源标签");

AssetDatabase.FindAssets("l:cube abc"); 查找名称有abc关键字,并且资源标签为cube的资源

3、通过资源类型查找

AssetDatabase.FindAssets("t:资源类型");

AssetDatabase.FindAssets("t:texture2D btn"); 查找类型为texture2D,并且资源名称有关键字btn

4、为了优化性能,可以添加搜索路径数组,缩小搜索范围

string[] path = {"Assets/Resources", "Packages"};

strList = AssetDatabase.FindAssets("t:texture2D btn", path);

5、从项目中找到指定的资产,返回的是GUID字符串数组。需要通过

AssetDatabase.GUIDToAssetPath转为路径字符串

string[] guids2 = AssetDatabase.FindAssets("t:prefab", new[] {"Assets/Res/Prefabs"});
foreach (string guid2 in guids2)
{
   Debug.Log(AssetDatabase.GUIDToAssetPath(guid2));
   GameObject t = AssetDatabase.LoadAssetAtPath<GameObject>(guid2);
}

加载资源引用

var atlasAsset = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(assetPath);

Texture2D t = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/Textures/texture.jpg", typeof(Texture2D));

获取引用路径

AssetDatabase.GetAssetPath(Object obj)

返回资源所在的路径字符串

重命名资源

AssetDatabase.RenameAsset

例子:批量重命名选中的资源

using UnityEditor;

public class NameTool
{
    [MenuItem("Assets/常用/命名工具",false,1)]
    public static void SetPngName()
    {
        var list = Selection.assetGUIDs;
        for (var i = 0; i < list.Length - 1; i++)
        {
            var guid = list[i];
            var path = AssetDatabase.GUIDToAssetPath(guid);
            AssetDatabase.RenameAsset(path, "frame_" + (i + 1));
        } 
        AssetDatabase.Refresh();
    }
}

打开查看资源

例如:预制体、图片等

AssetDatabase.OpenAsset

特性标签

间距

可在 Inspector 中添加一些间距,数字越大,间隔越大

[Space(30)]
public string myName;
[Space(50)]
public int age;

标题

在 Inspector 中的某些字段上方添加标题。

[Header("物品信息")]
public string objName;
public float objWeight;

鼠标悬停提示

鼠标移到该字段就会显示该提示

[Header("物品信息")]
[Tooltip("物品的名称")]
public string objName;
[Tooltip("物品的重量")]
public float objWeight;

滑动条范围

限制数值变量的取值范围并以滑动条显示在Inspector面板上。

[Range(0,100)]
public int HP;

多行文本

用于在多行文本区域中显示字符串值的属性

[MultilineAttribute]
public string description;

[TextAreaAttribute]

该属性可以把string在Inspector上的编辑区变成一个TextArea

[TextAreaAttribute]
public string myMenu;

[TextAreaAttribute(1,5)]
public string myMenu;

组件依赖

[RequireComponent(typeof(ClassName))]

属性自动将所需的组件添加为依赖项。

[RequireComponent(typeof(Rigidbody))]

作用:可以避免给一个物体重复添加组件,或者漏加组件

颜色域

[ColorUsage(hdr,showAlpha)]

hdr

如果设置为 true,则将 Color 处理为 HDR 颜色。

showAlpha

如果为 false,则 ColorField 中会隐藏 alpha 栏,并且拾色器中不显示 alpha 值。

用于为颜色配置 ColorField 和拾色器的使用情况。

 [ColorUsage(true,true)]    
 public Color colorpicker;

隐藏字段

将不会在Inspector面板中显示该字段

[HideInInspector]
public int aaa = 5;

系统窗口显示

消息提示框

public static bool DisplayDialog (string title, string message, string ok, string cancel= "");

用于在编辑器中显示消息框

 if (EditorUtility.DisplayDialog("测试1", "我是测试1,你确定要测试我吗?", "测试", "取消"))
 {
	 Debug.Log("我是测试1");
 }

public static int DisplayDialogComplex (string title, string message, string ok, string cancel, string alt);

int 返回所选按钮的 ID。ID 为 0、1 或 2,分别对应于 cancel、cancel 和 alt 按钮。

显示含有三个按钮的模态对话框

title

对话框名称。

message

对话框的用途。

ok

所选的对话框功能。

cancel

关闭对话框,不执行任何操作。

alt

选择备选的对话框用途。

[MenuItem("我的工具/3 Selection", false, 37)]
    static void Test1()
    {
        int option = EditorUtility.DisplayDialogComplex("三选框",
            "请从三个选项中选择!",
            "选项0",
            "选项1",
            "选项2");

        switch (option)
        {
            case 0:
                Debug.Log("0000");
                break;
            case 1:
                Debug.Log("1111");
                break;
            case 2:
                Debug.Log("2222");
                break;

            default:
                Debug.LogError("Unrecognized option.");
                break;
        }
    }

文件夹目录

1、显示“打开文件”对话框并返回所选的路径名称,但是只能选择单个文件

public static string OpenFilePanel (string title, string directory, string extension);

[MenuItem("项目工具/OpenFile",false,1)]
static void OpenFile()
{
    string path = EditorUtility.OpenFilePanel("打开文件", "", "xlsx");
    if (path.Length != 0)
    {
        Debug.Log(path);
    }
}

2、显示“打开文件夹”对话框并返回所选的路径名称。

public static string OpenFolderPanel (string title, string folder, string defaultName);

[MenuItem("项目工具/OpenFolder",false,1)]
static void OpenFolder()
{
    string path = EditorUtility.OpenFolderPanel("打开文件夹", "", "");
    if (path.Length != 0)
    {
        Debug.Log(path);
    }
}

3、显示“保存文件”对话框并返回所选的路径名称。

public static string SaveFilePanel (string title, string directory, string defaultName, string extension);

 [MenuItem("项目工具/SaveFile",false,1)]
 static void SaveFile()
 {
     Texture2D texture = Selection.activeObject as Texture2D;
     if (texture == null)
     {
         EditorUtility.DisplayDialog(
             "Select Texture",
             "You Must Select a Texture first!",
             "Ok");
         return;
     }

     var path = EditorUtility.SaveFilePanel(
         "Save texture as PNG",
         "",
         texture.name + ".png",
         "png");

     if (path.Length != 0)
     {
         Debug.Log(path);
         var pngData = texture.EncodeToPNG();
         if (pngData != null)
             File.WriteAllBytes(path, pngData);
     }
 }

4、显示“保存文件夹”对话框并返回所选的路径名称

public static string SaveFolderPanel (string title, string folder, string defaultName);

  [MenuItem("Example/Save Textures To Folder")]
    static void Apply()
    {
        Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.Unfiltered);
        if (textures.Length == 0)
        {
            EditorUtility.DisplayDialog("Select Textures", "You must select at least one texture first!", "OK");
            return;
        }

        string path = EditorUtility.SaveFolderPanel("Save textures to folder", "", "");
        if (path.Length != 0)
        {
            foreach (Texture2D texture in textures)
            {
                Texture2D processedTex = texture;

                byte[] pngData = processedTex.EncodeToPNG();
                if (pngData != null)
                    File.WriteAllBytes(path + "/" + texture.name + ".png", pngData);
                else
                    Debug.Log("Could not convert " + texture.name + " to png. Skipping saving texture.");
            }

            // Just in case we are saving to the asset folder, tell Unity to scan for modified or new assets
            AssetDatabase.Refresh();
        }
    }

打开系统文件夹

System.Diagnostics.Process.Start("E:\\Game\\原神\\Genshin Impact Game");

显示进度条

private void OnGUI()
{
    if (GUILayout.Button("点击"))
    {
        for (int i = 0; i < 10; i++)
        {
            EditorUtility.DisplayProgressBar("测试进度条", "处理中......", (float)i/(float)10);
            Thread.Sleep((int)1000.0f);
        }
        EditorUtility.ClearProgressBar();
    }
}

 

其他常用API

Selection

count

返回选中对象的数量

activeGameObject

返回选中的游戏对象

activeObject

返回选中的对象

activeTransform

返回选中的Transform

transforms

返回选中对象的Transform数组

assetGUIDs

返回所选资源的 GUID

gameObjects

返回选中对象的GameObject数组

objects

返回选中的object数组

PrefabUtility

保存预制体 

//保存预制体
GameObject pre = PrefabUtility.SaveAsPrefabAsset(go,$"Assets/Editor/MapEditor/Maps/{go.name}.prefab");
AssetDatabase.OpenAsset(pre);

EditorSceneManager

保存当前场景

//保存当前场景
var nowScene = EditorSceneManager.GetActiveScene();
EditorSceneManager.SaveScene(nowScene);

EditorApplication

打开Animation窗口

EditorApplication.ExecuteMenuItem("Window/Animation/Animation");

AssetPreview

预制体创建预览图

 // 预制体创建预览图
 previewImg = AssetPreview.GetAssetPreview(obj);
 EditorGUILayout.ObjectField(" ",previewImg, typeof(Texture2D), false);
Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐