下面是一些简单的编辑器用到的函数,一般通过 MenuItem 来添加到菜单中。。。
在 Inspector 中字段的各种特性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[Header( "My variables" )]
public string MyString;
[HideInInspector]
public string MyHiddenString;
[Multiline( 5 )]
public string MyMultilineString;
[TextArea( 2, 8 )]
public string MyTextArea;
[Space( 15 )]
public int MyInt;
[Range( 2.5f, 12.5f )]
public float MyFloat;
[Tooltip( "This is a tip for MyDouble" )]
public double MyDouble;
[SerializeField]
private double myHiddenDouble;
|
对组件的各种约束特性:
1
2
3
4
5
6
|
[DisallowMultipleComponent]
[RequireComponent( typeof( Rigidbody ) )]
public class AttributesExample : MonoBehaviour
{
}
|
AssetDatabase.SaveAssets 之前需要 EditorUtility.SetDirty。
Prefab 中可能残留一些数据,导致通过 GetDependencies 获取依赖时被获取到,导致打包时导入了没用的资源,清洗方法:
EditorUtility.SetDirty(obj);
AssetDatabase.SaveAssets();
Onvalidate 函数用于检测 Inspector 上面变量值的变化
1
2
3
4
5
6
7
|
public class OnValidateExample : MonoBehaviour {
public int size;
void OnValidate() {
Debug.Log("OnValidate");
}
}
|
使用 Application.IsEditor 可以替代 #if UNITY_EDITOR,在 dll 中不识别 UNITY_EDITOR,所以用这个很好。
1
|
EditorApplication.isPlaying == (Application.isPlaying && Application.isEditor)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.IO;
using System;
public class EditorTool : MonoBehaviour {
public static bool ShowDialog (string msg, string title = "提示", string button = "确定")
{
return EditorUtility.DisplayDialog (title, msg, button);
}
// 对话框
public static void ShowDialogSelection (string msg, Action yesCallback)
{
if (EditorUtility.DisplayDialog ("确定吗", msg, "是!", "不!")) {
yesCallback ();
}
}
// 创建 Prefab,复制组件信息
[MenuItem("Tools/CreatePrefab")]
static void CreatePrefab()
{
string path = "Assets/test.prefab";
Object obj = AssetDatabase.LoadMainAssetAtPath(path);
GameObject go = new GameObject();
if (obj == null)
{
go.AddComponent<GameData>();
PrefabUtility.CreatePrefab(path, go);
}
else
{
GameObject o = obj as GameObject;
foreach (var c in o.GetComponentsInChildren<MonoBehaviour>())
{
UnityEditorInternal.ComponentUtility.CopyComponent(c);
UnityEditorInternal.ComponentUtility.PasteComponentAsNew(go);
PrefabUtility.ReplacePrefab(go, obj);
}
}
DestroyImmediate(go);
}
// 复制路径,使用 ctrl + c (%_C)会导致其它复制内容失效,所以不能使用
[MenuItem("Assets/CopyPath #_c", false, 100)]
private static void CopyAssetPath()
{
if (Selection.activeObject != null)
{
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
EditorGUIUtility.systemCopyBuffer = path;
}
}
// 打开场景
[MenuItem("Tools/Open Main Scene %&i", false, 1)]
public static void OpenMainScene()
{
var mainScene = "Assets/Game/Scene/Main.unity";
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(mainScene);
}
// 自动选择某个物体
[MenuItem("Tools/Setting")]
static void ShowSetting()
{
var obj = AssetDatabase.LoadMainAssetAtPath("Assets/Editor/EditorTool.cs");
Selection.activeObject = obj;
EditorGUIUtility.PingObject(obj);
EditorApplication.ExecuteMenuItem("Window/Inspector");
}
// 打开目录
[MenuItem("Tools/Open PC PersistentDataPath", false, 2)]
public static void OpenPersistentDataPath()
{
System.Diagnostics.Process.Start(Application.persistentDataPath);
}
// 清理存储的数据
[MenuItem("Tools/Clear PC PersistentDataPath", false, 3)]
public static void ClearPersistentDataPath()
{
foreach (string dir in Directory.GetDirectories(Application.persistentDataPath))
{
Directory.Delete(dir, true);
}
foreach (string file in Directory.GetFiles(Application.persistentDataPath))
{
File.Delete(file);
}
}
// 清理所有 PlayerPrefs
[MenuItem("Tools/Clear Prefs", false, 4)]
public static void ClearPlayerPrefs()
{
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
ShowDialog("Prefs Cleared!");
}
// 打开网页
[MenuItem ("Tools/Open Url", false, 5)]
public static void OpenUrl ()
{
System.Diagnostics.Process.Start ("https://www.baidu.com/");
}
}
|
在NGUI中检查无效图片,还可以使用快捷键shift_c:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[MenuItem ("FNW/检查无效图片 #_c", false, 6)]
static void CheckInvalidSprite ()
{
if (Selection.activeGameObject != null) {
GameObject obj = Selection.activeGameObject;
foreach (var v in obj.GetComponentsInChildren<UISprite>(true)) {
if (v.atlas == null || !v.isValid) {
Debug.LogWarning ("无效的Sprite", v);
}
}
foreach (var v in obj.GetComponentsInChildren<UITexture>(true)) {
Debug.LogWarning ("无效的Texture", v);
}
}
}
|
如果希望在GameObject的脚本上右键弹出可执行菜单,可以在该脚本的函数上添加 ContextMenu,比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[ContextMenu("LogAllAtlasName")]
public void LogAllAtlasName ()
{
Debug.LogWarning ("[[[---Atlas: " + this.name);
HashSet<UIAtlas> atlasContainer = new HashSet<UIAtlas> ();
foreach (var v in this.GetComponentsInChildren<UISprite>(true)) {
atlasContainer.Add (v.atlas);
}
foreach (var v in atlasContainer) {
Debug.LogWarning (v);
}
Debug.LogWarning ("---]]]");
}
|
创建向导窗口要继承 ScriptableWizard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class WizardTest : ScriptableWizard
{
public float range = 500;
public Color color = Color.red;
[MenuItem("GameObject/New Light", false, 10)]
static void CreateWizard()
{
// 创建向导窗口
ScriptableWizard.DisplayWizard<WizardTest>("Create Light", "Create", "Apply");
}
private void OnWizardCreate()
{
GameObject go = new GameObject("New Light");
Light lt = go.AddComponent<Light>();
lt.range = range;
lt.color = color;
}
private void OnWizardUpdate()
{
helpString = "Please set the color of the light";
}
private void OnWizardOtherButton()
{
if (Selection.activeTransform != null)
{
Light lt = Selection.activeTransform.GetComponent<Light>();
if (lt != null)
{
lt.color = Color.green;
}
}
}
}
|
在 Create 中创建菜单,用于创建asset资源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class Test : MonoBehaviour {
void Start () {
// 创建asset资源
var t = ScriptableObject.CreateInstance<AbilityData>();
AssetDatabase.CreateAsset(t, "Assets/ability.asset");
}
}
[CreateAssetMenu(fileName = "", menuName = "", order = 1)]
public class AbilityData : ScriptableObject
{
public int ID;
public int Name;
}
|
在编辑器扩展创建拖拽区域
1
2
3
4
5
6
7
8
9
10
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriggerContainer : MonoBehaviour {
void Start () {
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
using UnityEngine;
using System.Collections;
using UnityEditor;
// CustomEditor 允许自定义组件的编辑器显示
[CustomEditor (typeof(TriggerContainer))]
public class TriggerContainerEditor : Editor
{
private SerializedObject obj;
public void OnEnable ()
{
obj = new SerializedObject (target);
}
public override void OnInspectorGUI ()
{
DrawDefaultInspector ();
EditorGUILayout.Space ();
DropAreaGUI ();
}
public void DropAreaGUI ()
{
Event evt = Event.current;
Rect drop_area = GUILayoutUtility.GetRect (0.0f, 50.0f, GUILayout.ExpandWidth (true));
GUI.Box (drop_area, "Add Trigger");
switch (evt.type) {
case EventType.DragUpdated:
case EventType.DragPerform:
if (!drop_area.Contains (evt.mousePosition))
return;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (evt.type == EventType.DragPerform) {
DragAndDrop.AcceptDrag ();
foreach (Object dragged_object in DragAndDrop.objectReferences) {
// Do On Drag Stuff here
Debug.Log(dragged_object.name);
}
}
break;
}
}
}
|
在菜单 Edit -> Preferences 中添加新选项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class CustomSetting
{
public class SettingData
{
public bool needCheckTable = true;
}
#if UNITY_EDITOR
private static string settingkey = "customSetting";
private static SettingData settingData;
private static GUIContent needCheckTableContent = new GUIContent("needCheckTable");
public static SettingData GetSetting()
{
CheckData();
return settingData;
}
// PreferenceItem 允许在 Preference 菜单中创建菜单
[PreferenceItem("CustomSetting")]
private static void PreferenceGUI()
{
CheckData();
settingData.needCheckTable = EditorGUILayout.Toggle(needCheckTableContent, settingData.needCheckTable);
if (GUI.changed)
{
SaveData();
}
}
private static void CheckData()
{
if (settingData == null)
{
if (EditorPrefs.HasKey(settingkey))
{
settingData = JsonUtility.FromJson<SettingData>(EditorPrefs.GetString(settingkey));
}
else
{
settingData = new SettingData();
SaveData();
}
}
}
private static void SaveData()
{
EditorPrefs.SetString(settingkey, JsonUtility.ToJson(settingData));
}
#endif
}
|
清除 Console Log
1
2
3
4
5
6
7
|
public void ClearLog()
{
var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
var type = assembly.GetType("UnityEditor.LogEntries");
var method = type.GetMethod("Clear");
method.Invoke(new object(), null);
}
|
Gizmos 用线画圆,如果是在 Editor 目录下可以用 UnityEditor.Handles.DrawWireDisc 方法替代
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private void OnDrawGizmos()
{
float meleeRadius = 3f;
Gizmos.color = Color.white;
float theta = 0;
float x = meleeRadius * Mathf.Cos(theta);
float y = meleeRadius * Mathf.Sin(theta);
Vector3 pos = transform.position + new Vector3(x, 0, y);
Vector3 newPos = pos;
Vector3 lastPos = pos;
for (theta = 0.1f; theta < Mathf.PI * 2; theta += 0.1f)
{
x = meleeRadius * Mathf.Cos(theta);
y = meleeRadius * Mathf.Sin(theta);
newPos = transform.position + new Vector3(x, 0, y);
Gizmos.DrawLine(pos, newPos);
pos = newPos;
}
Gizmos.DrawLine(pos, lastPos);
}
|
InitializeOnLoad 当编辑器启动或代码编译时自动执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[InitializeOnLoad]
public class AttributesExample : MonoBehaviour
{
static AttributesExample()
{
[...]
}
[InitializeOnLoadMethod]
private static void Foo()
{
[...]
}
}
|
CustomPropertyDrawer 允许为组件在 Inspector 中自定义外观
1
2
3
4
5
|
[CustomPropertyDrawer( typeof( MyClass ) )]
public class AttributesExample : PropertyDrawer
{
}
|
DrawGizmo 允许为组件创建自定义的 Gizmos
1
2
3
4
5
|
[DrawGizmo( GizmoType.Selected )]
private static void DoGizmo( AttributesExample obj, GizmoType type )
{
}
|