前言
之前知道Unity编辑器是可以拓展的,做项目也没怎么用过编辑器拓展。但是不代表以后用不到,所以这边文章就记录下Unity编辑器拓展的学习过程吧!会一直持续更新!!!
编辑器拓展是需要引入命名空间 using UnityEditor;
且把关于编辑器拓展的脚本放到Plugins
文件夹下面。
项目下载地址
添加菜单项
-我们添加一个菜单项,并且点击这个菜单项可以绘制一个面板。
using UnityEditor;
public class ChangeObjName : EditorWindow
{
private static ChangeObjName instance;
[MenuItem("DrawWindow/ChangeName")]//添加菜单项
static void ChangeName()
{
instance = EditorWindow.GetWindow<ChangeObjName>();
instance.Show();//点击ChangeName可以绘制面板
}
}
看下面的gif可以看到菜单栏多一个DrawWindow菜单,点击子菜单就会弹出我们绘制的窗口,此时这个窗口中什么内容都没有,下面我们准备向这个窗口中添加内容
下面准备做在Hierarchy
面板中选中一个物体,通过我们绘制的窗口来改变选中的物体的名字。
- 通过绘制的窗口,添加功能改变选中的物体的名字
using UnityEngine;
using UnityEditor;
public class ChangeObjName : EditorWindow
{
private static ChangeObjName instance;
[MenuItem("DrawWindow/ChangeName")]
static void ChangeName()
{
instance = EditorWindow.GetWindow<ChangeObjName>();
instance.Show();
}
static string newName;
private void OnGUI()
{
newName = EditorGUILayout.TextField("修改的名字", newName);//绘制输入框
if (GUILayout.Button("改名字", GUILayout.Height(25)))//绘制button
{
if (newName != null)
Fun_ChangeName(newName);
}
}
/// <summary>
/// 改变物体名字方法
/// </summary>
/// <param name="newName"></param>
static void Fun_ChangeName(string newName)
{
Object[] selection = (Object[])Selection.objects;//选中的物体
if (selection.Length == 0) return;
foreach (Object item in selection)
{
GameObject temp = (GameObject)item;
temp.name = newName;
}
AssetDatabase.Refresh();//刷新面板
}
/// <summary>
/// 当界面发生改变时重绘
/// </summary>
private void OnInspectorUpdate()
{
Repaint();
}
}
下面的gif:我创建了一个cube,当我选中之后,通过绘制的窗口来改变cube的名字。
自定义Inspector面板
把下面这个脚本对象在Inspector面板自定义显示
using UnityEngine;
public class Player : MonoBehaviour
{
public int ID;
new public string name;
public int hp;
public float blue;
public float damage;
public string describe;
public string weapon1, weapon2;
public float height, age, weight;
}
下面这个gif是自定义之后的效果图
自定义Inspector面板的脚本
// ========================================================
// 描述:
// 作者:MeKey
// 创建时间:2019-05-21 17:27:06
// 版 本:1.0
// ========================================================
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Player))]
public class PlayerInspector : Editor
{
Player player;
bool isShow = false;//折叠标志位
private void OnEnable()
{
player = (Player)target;
}
/// <summary>
/// 重写面板
/// </summary>
public override void OnInspectorGUI()
{
EditorGUILayout.BeginVertical();//设置为垂直布局
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
EditorGUILayout.LabelField(target.ToString() + " : 脚本组件信息:");
player.ID = EditorGUILayout.IntField("Player ID :", player.ID);
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
player.name = EditorGUILayout.TextField("玩家名字:", player.name);
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
player.hp = EditorGUILayout.IntField("玩家血量:", player.hp);
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
player.damage = EditorGUILayout.Slider("玩家伤害", player.damage, 0, 30);
//根据伤害值的大小设置显示的类型和提示语
if (player.damage < 10)
{
EditorGUILayout.HelpBox("伤害太低了吧!!", MessageType.Error);
}
else if (player.damage > 15)
{
EditorGUILayout.HelpBox("伤害有点高啊!!", MessageType.Warning);
}
else
{
EditorGUILayout.HelpBox("伤害适中!!", MessageType.Info);
}
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
EditorGUILayout.LabelField("脚本描述");//创建一个标题
player.describe = EditorGUILayout.TextArea(player.describe,GUILayout.MinHeight(50));//创建文本区域
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
//用滑动条设置 玩家的初始蓝量
player.blue = EditorGUILayout.Slider("玩家蓝量", player.blue, 0, 100);
if (player.blue < 20)
{
GUI.color = Color.red;
EditorGUILayout.HelpBox("蓝量太低了!!", MessageType.Error);
}
else if (player.blue > 80)
{
GUI.color = Color.green;
EditorGUILayout.HelpBox("蓝量很好!!", MessageType.Info);
}
else
{
GUI.color = Color.grey;
EditorGUILayout.HelpBox("蓝量正常!!", MessageType.Warning);
}
Rect progressRect = GUILayoutUtility.GetRect(50, 25);
EditorGUI.ProgressBar(progressRect, player.blue / 100f, "blue");
GUI.color = Color.white;
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
isShow = EditorGUILayout.Foldout(isShow, "weapon");//
if (isShow)
{
player.weapon1 = EditorGUILayout.TextField("第一种武器", player.weapon1);
player.weapon2 = EditorGUILayout.TextField("第er种武器", player.weapon2);
}
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
if (GUILayout.Button("删除此组件", GUILayout.Height(25)))
{
Debug.Log("删除组件 ");
DestroyImmediate(this.player);
}
EditorGUILayout.Space();//空行
EditorGUILayout.Space();//空行
EditorGUILayout.LabelField("玩家个人信息");
EditorGUILayout.BeginHorizontal();//绘制水平布局
EditorGUILayout.LabelField("身高", GUILayout.MaxWidth(35));
player.height= EditorGUILayout.FloatField(player.height);
EditorGUILayout.LabelField("年龄",GUILayout.MaxWidth (35));
player.age = EditorGUILayout.FloatField( player.age );
EditorGUILayout.LabelField("体重", GUILayout.MaxWidth(35));
player.weight = EditorGUILayout.FloatField( player.weight );
EditorGUILayout.EndHorizontal();//结束水平绘制和BeginHorizontal()对应
EditorGUILayout.EndVertical();//结束垂直绘制和BeginVertical()对应
}
}
添加右键菜单
- 在Project面板添加右键菜单.
// ========================================================
// 描述:Project 面板 添加右键菜单
// 作者:MeKey
// 创建时间:2019-05-21 22:54:30
// 版 本:1.0
// ========================================================
using System.IO;
using UnityEditor;
using UnityEngine;
public class AddContextMenu : Editor//此处继承MonoBehaviour也行
{
[MenuItem("Assets/创建文件夹", false, 5)]
static void CreateDic()
{
CreateFile("Resources");
CreateFile("StreamingAssets");
CreateFile("MeKey");
CreateFile("Prefabs");
}
[MenuItem("Assets/创建Prefabs文件夹",false,5)]
static void CreatePrefabs()
{
CreateFile("Prefabs");
}
[MenuItem("Assets/创建Resouces文件夹",false,0)]
static void CreateResources()
{
CreateFile("Resources");
}
[MenuItem("Assets/创建StreamingAssets文件夹")]
static void CreateStreamingAssets()
{
CreateFile("StreamingAssets");
}
[MenuItem("Assets/创建Plugins文件夹")]
static void CreatePlugins()
{
CreateFile("Plugins");
}
[MenuItem("Assets/创建MeKey文件夹")]
static void CreateMeKey()
{
CreateFile("MeKey");
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="fileName"></param>
static void CreateFile(string fileName)
{
string path = Application.dataPath + "/";
Directory.CreateDirectory(path + fileName);
AssetDatabase.Refresh();
}
}
下面Gif效果展示