自定义检视面板的使用:
先是定义一个脚本文件,我们来修饰它的检视面板:
[HelpURL("http://www.baidu.com")] public class Atr : MonoBehaviour { public int id; public string Name; [Multiline(5)] public string BackStory; public float health; public float damage; public float weaponDamagel, weaponDamage2; public string shoeName; public int shoeSize; public string shoeType; [Space(100)] [Range(-2,5)] public int time; void Start () { health = 50; } }
然后在根目录的Editor文件夹下定义一个用来修饰上面脚本检视面板的类文件:
using UnityEngine; using System.Collections; using UnityEditor; [CustomEditor(typeof(Atr))] //需要继承自editor,并且引入UnityEditor程序集 public class LearnInspector : Editor { private Atr atr; private bool showWeapons; void OnEnable() { //获取当前自定义的Inspector对象 atr = (Atr) target; } //执行该函数来自定义检视面板 public override void OnInspectorGUI() { //不写默认是垂直布局 EditorGUILayout.BeginVertical(); //空格 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Base Info"); atr.id = EditorGUILayout.IntField("Atr ID", atr.id); atr.Name = EditorGUILayout.TextField("Atr Name", atr.Name); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Back Story"); atr.BackStory = EditorGUILayout.TextArea(atr.BackStory, GUILayout.MinHeight(100)); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); atr.health = EditorGUILayout.Slider("Health", atr.health, 0, 100); if (atr.health < 20) { GUI.color = Color.red; } else if (atr.health>80) { GUI.color = Color.green; } else { GUI.color = Color.grey; } Rect progressRect = GUILayoutUtility.GetRect(50, 50); EditorGUI.ProgressBar(progressRect,atr.health/100.0f,"Health"); GUI.color = Color.white; EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); atr.damage = EditorGUILayout.Slider("Damage", atr.damage, 0, 20); if(atr.damage<10) { EditorGUILayout.HelpBox("伤害过低",MessageType.Error); } else if (atr.damage > 15) { EditorGUILayout.HelpBox("伤害过高",MessageType.Warning); } else { EditorGUILayout.HelpBox("伤害适中",MessageType.Info); } EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Shoe"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name", GUILayout.MaxWidth(50)); atr.shoeName = EditorGUILayout.TextField(atr.shoeName); EditorGUILayout.LabelField("Size", GUILayout.MaxWidth(50)); atr.shoeSize = EditorGUILayout.IntField(atr.shoeSize); EditorGUILayout.LabelField("Type", GUILayout.MaxWidth(50)); atr.shoeType = EditorGUILayout.TextField(atr.shoeType); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } } //绘制字段用到的方法 //EditorGUILayout.LabelField()标签字段 //EditorGUILayout.IntField() 整数字段 //EditorGUILayout.FloatField() 浮点数字段 //EditorGUILayout.TextField() 文本字段 //EditorGUILayout.Vector2Field() 二维向量字段 //EditorGUILayout.Vector3Field() 三维向量字段 //EditorGUILayout.Vector4Field() 四维向量字段
可以看出该修饰类和效果图对应的关系。我们可以方便的定义检视面板来协助游戏的开发调试,让它直观的显示出帮助消息。
更多的信息可以查看帮助文档:http://www.ceeger.com/Script/Editor/Editor.html
自定义窗口:
1 using System; 2 using UnityEngine; 3 using System.Collections; 4 using System.IO; 5 using UnityEditor; 6 using UnityEditor.SceneManagement; 7 8 public class MyFirstWindow : EditorWindow 9 { 10 11 public Texture TxTexture; 12 string bugReporterName = ""; 13 string description = ""; 14 GameObject buggyGameObject; 15 16 MyFirstWindow() 17 { 18 this.titleContent=new GUIContent("Bug Rt"); 19 } 20 21 22 [MenuItem("Tool/Bug Reporter")] 23 static void showWindow() 24 { 25 EditorWindow.GetWindow(typeof (MyFirstWindow)); 26 } 27 28 //绘制窗口界面 29 void OnGUI() 30 { 31 GUILayout.BeginVertical(); 32 33 GUILayout.Space(10); 34 GUI.skin.label.fontSize = 24; 35 GUI.skin.label.alignment = TextAnchor.MiddleCenter; 36 GUILayout.Label("Bug Report"); 37 38 GUILayout.Space(10); 39 bugReporterName = EditorGUILayout.TextField("Bug Name", bugReporterName); 40 41 GUILayout.Space(10); 42 GUI.skin.label.fontSize = 12; 43 GUI.skin.label.alignment = TextAnchor.UpperLeft; 44 GUILayout.Label("Currently Scene:"+EditorSceneManager.GetActiveScene().name); 45 46 GUILayout.Space(10); 47 GUILayout.Label("Time:"+System.DateTime.Now); 48 49 50 GUILayout.Space(10); 51 buggyGameObject = 52 (GameObject) EditorGUILayout.ObjectField("Buggy Go", buggyGameObject, typeof (GameObject), true); 53 54 GUILayout.Space(10); 55 GUILayout.BeginHorizontal(); 56 GUILayout.Label("Description", GUILayout.MaxWidth(80)); 57 description = EditorGUILayout.TextArea(description, GUILayout.MaxHeight(75)); 58 GUILayout.EndHorizontal(); 59 60 EditorGUILayout.Space(); 61 62 if (GUILayout.Button("Save Bug")) 63 { 64 SaveBug(); 65 66 } 67 68 if (GUILayout.Button("Save Bug With Screenshoot")) 69 { 70 SaveBugWithScreeshot(); 71 } 72 73 EditorGUILayout.EndVertical();//布局开始和结束相对应,缺少时可能出现窗口中的元素无法自适应的情况 74 } 75 76 private void SaveBugWithScreeshot() 77 { 78 Writer(); 79 Application.CaptureScreenshot("Assets/BugReports/" + bugReporterName + "/" + bugReporterName + ".png"); 80 } 81 82 private void SaveBug() 83 { 84 Writer(); 85 } 86 87 //IO类,用来写入保存信息 88 void Writer() 89 { 90 Directory.CreateDirectory("Assets/BugReports/" + bugReporterName); 91 StreamWriter sw = new StreamWriter("Assets/BugReports/" + bugReporterName + "/" + bugReporterName + ".txt"); 92 sw.WriteLine(bugReporterName); 93 sw.WriteLine(DateTime.Now.ToString()); 94 sw.WriteLine(EditorSceneManager.GetActiveScene().name); 95 sw.WriteLine(description); 96 sw.Close(); 97 } 98 }
自定义菜单项:
1 using UnityEditor; 2 using UnityEngine; 3 using System.Collections; 4 5 /// <summary> 6 /// 工具类改名 7 /// </summary> 8 public class ChangeName : ScriptableWizard 9 { 10 11 12 public string PrefixStr = null; 13 14 /// <summary> 15 /// 当没有任何GameObject被选中的时候,将菜单disable(注意,这个函数名可以随意取) 16 /// </summary> 17 /// <returns></returns> 18 [MenuItem("ChangeName/AddPrefixAndEuipment", true)] 19 static bool CreateWindowDisabled() 20 { 21 return Selection.activeTransform; 22 } 23 24 25 /// <summary> 26 /// 创建编辑窗口(注意,这个函数名可以随意取) 27 /// </summary> 28 [MenuItem("ChangeName/AddPrefixAndEuipment")] 29 static void CreateWindow() 30 { 31 //第一个参数窗口标题 32 // 定制窗口标题和按钮,其中第二个参数是Create按钮,第三个则属于other按钮 33 // 如果不想使用other按钮,则可调用DisplayWizard的两参数版本 34 DisplayWizard<ChangeName>( 35 "AddPrefix", 36 "Add", "Remove"); 37 } 38 39 /// <summary> 40 /// 窗口创建或窗口内容更改时调用 41 /// </summary> 42 void OnWizardUpdate() 43 { 44 helpString = "Note: Prefix are not created"; 45 46 if (string.IsNullOrEmpty(PrefixStr)) 47 { 48 errorString = "Please enter Prefix"; 49 isValid = false; 50 } 51 else 52 { 53 errorString = ""; 54 isValid = true; 55 } 56 } 57 58 59 /// <summary> 60 /// 点击Add按钮(即Create按钮)调用 61 /// </summary> 62 void OnWizardCreate() 63 { 64 65 Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.OnlyUserModifiable); 66 67 foreach (Transform transform in transforms) 68 { 69 transform.name = PrefixStr + transform.name; 71 } 72 73 Debug.Log("AddPrefixAndEuipment " + PrefixStr+"successed!"); 74 } 75 76 /// <summary> 77 /// 点击Remove(即other按钮)调用 78 /// </summary> 79 void OnWizardOtherButton() 80 { 81 Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.OnlyUserModifiable); 82 83 foreach (Transform transform in transforms) 84 { 85 if (transform.name.Contains(PrefixStr)) 86 { 87 transform.name=transform.name.Replace(PrefixStr, ""); 88 } 89 } 90 91 Debug.Log("ReMove prefix " + PrefixStr + "successed!"); 92 } 93 94 95 96 [MenuItem("ChangeName/AddOrderNume2Name ")]// 为选择的对象名称添加序列号,让重名的物体相区别 97 static void AddOrder2Name() 98 { 99 int n = 0; 100 Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.OnlyUserModifiable); 101 102 foreach (Transform transform in transforms) 103 { 104 transform.name = transform.name + n.ToString(); 105 n++; 106 } 107 } 108 109 [MenuItem("GameObject/Add Child %g")] 110 static void MenuAddChild() 111 { 112 Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.OnlyUserModifiable); 113 114 foreach (Transform transform in transforms) 115 { 116 GameObject newChild = new GameObject("_Child"); 117 newChild.transform.parent = transform; 118 119 } 120 } 121 122 [MenuItem("ChangeName/ReNameUILabelX")] 123 static void ReNameUILableX() 124 { 125 UIButton [] UIButtions = GameObject.Find("CenterMenu").transform.GetChild(0).GetComponentsInChildren<UIButton>(); 126 127 foreach (UIButton uiButtion in UIButtions) 128 { 129 if (uiButtion.gameObject.activeSelf) 130 { 131 uiButtion.GetComponentInChildren<EptBtnOnClick>().EptName="X_"+ uiButtion.GetComponentInChildren<UILabel>().text; 132 } 133 } 134 } 135 141 142 }
ScriptableWizard:
继承自EditorWindow,主要用来做向导。有2个按钮,一个是Create,另一个是Other。当我们使用它的时候,他始终显示在最上层,不会被unity其他窗口遮挡。
SelectionMode:
can be used to tweak the selection returned by Selection.GetTransforms.
Note: This is an editor class. To use it you have to place your script in Assets/Editor inside your project folder. Editor classes are in the UnityEditor namespace so for C# scripts you need to add "using UnityEditor;" at the beginning of the script.
The default transform selection mode is: SelectionMode.TopLevel | SelectionMode.ExcludePrefab | SelectionMode.Editable.
Unfiltered |
Return the whole selection. |
TopLevel |
Only return the topmost selected transform. A selected child of another selected transform will be filtered out. |
Deep |
Return the selection and all child transforms of the selection. |
ExcludePrefab |
Excludes any prefabs from the selection. |
Editable |
Excludes any objects which shall not be modified. |
Assets |
Only return objects that are assets in the Asset directory. |
DeepAssets |
If the selection contains folders, also include all assets and subfolders within that folder in the file hierarchy. |
补充(190426):
一键导出包,非常方便迁移测试程序或者自己的代码库
1 using System; 2 #if UNITY_EDITOR 3 using UnityEditor; 4 using System.IO; 5 #endif 6 using UnityEngine; 7 8 namespace WSFramework{ 9 10 11 public class ExportPakge{ 12 13 #if UNITY_EDITOR 14 [MenuItem("WSTool/ExportPac %e")] 15 private static void ExportPackageAndCopyName(){ 16 var path="Assets/WSFramework"; 17 var fileName="WS_"+DateTime.Now.ToString("yyyyMMdd_hh")+".unitypackage"; 18 19 //--剪切板API,导出后直接粘贴出当前包的名字 20 GUIUtility.systemCopyBuffer=fileName; 21 22 23 //--导出package api 24 AssetDatabase.ExportPackage(path,fileName, ExportPackageOptions.Recurse); 25 26 //--打开asset目录 27 Application.OpenURL("file://"+Application.dataPath); 28 29 30 } 31 } 32 33 #endif 34 }
assetstore一个很优秀的编辑器扩展插件,只需要在类中添加 attribute标签就能方便的实现很多功能,有兴趣的可以下载学习下