Unity___编辑器开发
在Editor模式中执行组件内部的public字段/方法
1.确定绑定的组件
- 创建GUI按钮
[CustomEditor(typeof(Camera))]
public class TestInspector : Editor
{
/// <summary>
/// Inspector扩展,在对应的组件中添加按钮,可以点击后调用方法
/// </summary>
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Test1"))
{
Camera camera= this.target as Camera;
if (camera != null)
{
camera.depth++;
}
}
}
}
扩展组件设置菜单
例如给Transform组件添加一个设置位置的方法
/// <summary>
/// 扩展组件的菜单,例如在Transform下添加一个SetPositon
/// </summary>
public class TestInspectorContext : MonoBehaviour
{
[MenuItem("CONTEXT/Transform/SetPosition")]
static void SetPosition(MenuCommand command)
{
Transform transform = command.context as Transform;
if (transform != null)
{
transform.position += Vector3.one;
}
Debug.Log("SetPosition");
}
}
绘制Gizmos
主要用来标识物体
/// <summary>
/// 选中某对象后可以绘制一些东西标识物体
/// </summary>
public Color color;
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
Gizmos.color = color;
Gizmos.DrawLine(transform.position, transform.position + Vector3.up);
Gizmos.DrawSphere(transform.position, 1);
}
private void OnDrawGizmos()
{
//不选中也能绘制
}
#endif
添加菜单
static bool isValidate = true;
/// <summary>
/// 至少需要子路径,只有根路径会报错,根路径可以是已有的比如“GameObject”,第三个参数标识优先级
/// 快捷键%=Ctrl,#=Shift,&=Alt,上下左右=UP/DOWN/LEFT/RIGHT
/// </summary>
[MenuItem("Liudas/Text1 %#m",false,1)]
static void Test1()
{
isValidate = !isValidate;
TestWindow testWindow= EditorWindow.GetWindow<TestWindow>();
testWindow.Show();
Debug.LogError("测试菜单栏");
}
/// <summary>
/// 添加true表示是否是验证函数Test1
/// </summary>
/// <returns></returns>
[MenuItem("Liudas/Text1", true)]
static bool Test1Validate()
{
//判断逻辑。。。。
return isValidate;
}
监听资源的变化
包括监听创建,保存,移动,删除,改动资源
public class TestProjectEvent : UnityEditor.AssetModificationProcessor
{
public static void OnWillCreateAsset(string path)
{
Debug.LogFormat("创建资源{0}",path);
}
public static string[] OnWillSaveAssets(string[] paths)
{
for(int i = 0; i < paths.Length; i++)
{
Debug.Log($"保存资源:{paths[i]}");
}
return paths;
}
public static AssetMoveResult OnWillMoveAsset(string oldPath,string newPath)
{
Debug.Log($"移动资源:{oldPath}--->{newPath}");
return AssetMoveResult.DidNotMove;//可以移动
//AssetMoveResult.DidMove;//不可以移动
}
public static AssetDeleteResult OnWillDeleteAsset(string path,RemoveAssetOptions options)
{
Debug.Log($"删除资源:{path} Option:{1}");
//AssetDatabase.MoveAssetsToTrash();//将资源拖入回收站
return AssetDeleteResult.DidNotDelete;
}
[InitializeOnLoadMethod]
public void InitOnLoad()
{
EditorApplication.projectChanged += () =>
{
Debug.LogError("资源发生改变");
};
}
}
编辑模式中执行
[ExecuteInEditMode]
public class TestGame : MonoBehaviour
{
private void OnGUI()
{
if (GUILayout.Button("test1", GUILayout.Width(100)))
{
Debug.Log("test");
}
}
}
在GameObject/Asset窗口中添加菜单选项
[MenuItem("GameObject/Test",false,0)]
static void Test()
{
Debug.Log("Test project ");
}
[MenuItem("Asset/Test1")]
static void Test1()
{
Debug.LogError("Project视图菜单");
}
快速删除物体
hierarchy
[InitializeOnLoadMethod]
static void InitializeOnLoad()
{
//在Scene中右击弹出菜单栏,自定义菜单选项
EditorApplication.hierarchyWindowItemOnGUI+= (InstanceID, rect) =>
{
if (Selection.activeObject != null&&InstanceID==Selection.activeObject.GetInstanceID())
{
rect.x = rect.width - 50;
rect.width = 100;
if (GUI.Button(rect, "delete"))
{
DestroyImmediate((Selection.activeObject));
Debug.LogError($"删除物体:{Selection.activeObject},成功");
}
}
};
}
project
[InitializeOnLoadMethod]
static void InitializeOnLoad()
{
//在Scene中右击弹出菜单栏,自定义菜单选项
EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
{
if (Selection.activeObject != null)
{
string active_guid= AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(Selection.activeObject));
if (guid == active_guid&&string.IsNullOrEmpty(active_guid))
{
rect.x = rect.width - 100;
rect.width = 100;
if( GUI.Button(rect, "delete")) {
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Selection.activeObject));
Debug.LogError($"删除文件:{AssetDatabase.GetAssetPath(Selection.activeObject)},成功");
}
}
}
};
}
制作一个预览窗口
首先需要继承EditorWindow
public class TestPreview : EditorWindow
{
private Object obj;
private Object lastObj;
private Editor previewObj;
private void OnGUI()
{
obj=EditorGUILayout.ObjectField(obj, typeof(Object), false);
if (obj != null&&obj!=lastObj)
{
previewObj = Editor.CreateEditor(obj);
lastObj = obj;
}
if (previewObj!=null&& previewObj.HasPreviewGUI())
{
previewObj.OnPreviewGUI(GUILayoutUtility.GetRect(400,400),EditorStyles.label);
}
}
}
// 打开方式
[MenuItem("Liudas/Test2 ", false, 2)]
static void Test2()
{
TestPreview testWindow = EditorWindow.GetWindow<TestPreview>();
testWindow.Show();
}
窗口的一些监听方法
public class TestWindow : EditorWindow,IHasCustomMenu
{
private bool isOpen = false;
private void OnGUI()
{
if (GUILayout.Button("testWindow"))
{
Debug.Log("testwindow");
}
}
private void Awake()
{
}
private void OnDestroy()
{
}
private void OnFocus()
{
}
private void Update()
{
}
private void OnLostFocus()
{
}
/// <summary>
/// 窗口下拉菜单
/// </summary>
/// <param name="menu"></param>
public void AddItemsToMenu(GenericMenu menu)
{
menu.AddItem(new GUIContent("test1"), isOpen, () =>
{
Debug.Log("test1");
isOpen = !isOpen;
});
//menu.AddDisabledItem()
}
}