Unity编辑器拓展最全实现
Posted 一丁目赠我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity编辑器拓展最全实现相关的知识,希望对你有一定的参考价值。
1编辑器顶部菜单学习
验证事项
2编辑器Scene菜单学习
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestSceneMenu : MonoBehaviour
[InitializeOnLoadMethod] //加入这个属性,就相当于在编辑器启动的时候执行
static void Ind()
UnityEditor.SceneView.duringSceneGui += (u) =>
//在Scene窗口绘制菜单,只需要在DuringSceneGui绑入一个事件即可
if (Event.current != null &&Event.current.button == 1 && Event.current.type == EventType.MouseUp)
//if里面是描述鼠标右键事件按下,
Rect position = new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y-100,100,100);
//描绘菜单的Rect方框的位置
GUIContent[] contens = new GUIContent[] new GUIContent("Test1"),new GUIContent("先锋/Test2");
//菜单里面的按钮数组
EditorUtility.DisplayCustomMenu(position, contens,-1,(data, opt, select)=>
Debug.LogFormat("data:0,opt:1,select:2,value:3",data,opt,select,opt[select]);
,null);
//这是描绘菜单按钮所需要传入的属性,(位置,按钮数组,是否选择(传入按钮数组没有的下标代表不选择),每个按钮所需要处理的点击回调,一般传入空值即可)
Event.current.Use(); //将鼠标复原到指针icon
;
3编辑器如何给按钮添加快捷键学习
4Assets菜单栏拓展
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestProject : MonoBehaviour
[MenuItem("Assets/Test1")]
static void Test1()
Debug.Log("Assets Test1");
//Project文件夹下的按钮,直接把路径改成Assects即可
/// <summary>
/// 在资源右侧加上按钮
/// </summary>
[InitializeOnLoadMethod]
static void InitializeOnLoad()
//这个是在Project的窗口创建按钮 guid是Assects下所有资源的唯一标识符
//rect每个资源所占的选中方框大小,
EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
//是否选中资源
if (Selection.activeObject != null)
//获取资源的GUID唯一标识符
string Select_guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(Selection.activeObject));
//判断传入的唯一标识符和点击的唯一标识符是否一致
if (guid == Select_guid&&!string.IsNullOrEmpty (Select_guid))
//按照所占方框去创建按钮大小
rect.x = rect.width - 100;
rect.width = 100;
if (GUI.Button(rect, "delect"))
//删除资源方法
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Selection.activeObject));
Debug.LogFormat("资源唯一标识符:0", Select_guid);
;
5Project事件介绍
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class TestProjectEvent : UnityEditor.AssetModificationProcessor
/// <summary>
/// 将要创建资源的会执行的方法
/// </summary>
/// <param name="Path"></param>
public static void OnWillCreateAsset(string Path)
Debug.LogFormat("创建资源0", Path);
/// <summary>
/// 点击Apply保存资源所执行的方法
/// </summary>
/// <param name="paths"></param>
/// <returns></returns>
public static string[] OnWillSaveAssets(string[] paths)
for (int i = 0; i < paths.Length; i++)
Debug.LogFormat("保存的资源0", paths[i]);
return paths;
/// <summary>
/// 移动资源所执行的方法
/// </summary>
/// <param name="OldPath"></param>
/// <param name="NewPath"></param>
/// <returns></returns>
public static AssetMoveResult OnWillMoveAsset(string OldPath, string NewPath)
Debug.LogFormat("移动资源从0到1", OldPath, NewPath);
///需要返回枚举
return AssetMoveResult.DidNotMove; //允许移动
//return AssetMoveResult.DidMove; //不允许移动
//return AssetMoveResult.FailedMove; //不允许移动
/// <summary>
/// 删除资源所执行的方法 删除资源的路径,操作的枚举,枚举中表述的是删除之后是否进入回收站
/// </summary>
/// <param name="path"></param>
/// <param name="opt"></param>
/// <returns></returns>
public static AssetDeleteResult OnWillDeleteAsset(string path, RemoveAssetOptions opt)
Debug.LogFormat("删除资源:0 options:1", path, opt);
return AssetDeleteResult.DidNotDelete; //可以删除
//return AssetDeleteResult.DidDelete; //不能删除
//return AssetDeleteResult.FailedDelete; //不能删除
/// <summary>
/// 这个标头是项目初始化,监听资源发生变化
/// </summary>
[InitializeOnLoadMethod]
static void InitOnLoad()
///根据不同回调监听不同界面的资源回调
EditorApplication.projectChanged += () =>
Debug.Log("资源发生改变");
;
EditorApplication.hierarchyChanged+=()=>
Debug.Log("层级资源发生改变");
;
6层级面板的拓展
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestHierarchy : MonoBehaviour
/// <summary>
/// 层级面板右键按钮拓展
/// </summary>
[MenuItem("GameObject/Test2", false, 0)]
public static void Test2()
Debug.Log("GameObject Test2");
/// <summary>
/// 在层级资源右侧加上按钮
/// </summary>
[InitializeOnLoadMethod]
static void InitializeOnLoad()
//这个是在Hierarchy的资源左侧创建按钮 InstancesID是Hierarchy下所有资源的唯一ID
//rect每个资源所占的选中方框大小,
EditorApplication.hierarchyWindowItemOnGUI += (InstancesID, rect) =>
//是否选中资源 判断选择的资源id和传入的ID是否相等
if (Selection.activeObject != null&&InstancesID==Selection.activeObject.GetInstanceID())
//按照所占方框去创建按钮大小
rect.x = rect.width - 50;
rect.width = 100;
if (GUI.Button(rect, "delect"))
//删除资源方法
GameObject.DestroyImmediate(Selection.activeObject);
Debug.LogFormat("删除资源:0", InstancesID);
;
7抛弃原来的菜单,重新创建菜单
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestMenuOverride
[InitializeOnLoadMethod]
static void InitOnLoad()
///监听鼠标在层级面板窗口
EditorApplication.hierarchyWindowItemOnGUI += (InstanceID, rect) =>
if (Event.current != null)
///判断右键抬起
if (Event.current.button == 1 && Event.current.type == EventType.MouseUp)
//阻断本身的右键菜单展出
//Event.current.Use();
//创建自己的菜单按钮,可以看到本身自己的菜单,在”先锋“的地方传入自己的菜单名称即可
//EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 100, 100)
// ,"先锋",null);
Debug.Log("鼠标抬起");
;
8在Inspector面板组件拓展 (在代码或者组件下面加按钮)
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
/// <summary>
/// CustomEditor属性指定类型,下面就是在Camera组件加入按钮
/// </summary>
[CustomEditor(typeof(Camera))]
public class TestInspector : Editor
public override void OnInspectorGUI()
base.OnInspectorGUI(); //保持原生的组件属性
///加入按钮,并且监听按钮按下
if (GUILayout.Button("Test1"))
Debug.Log("雨一直下,气氛不算融化ikun");
///获取目标组件
Camera c = this.target as Camera;
if (c != null)
c.fieldOfView = 10;
9在Inspector Context组件拓展(组件右键面板加按钮)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestInspectorContext : MonoBehaviour
/// <summary>
/// 命名规则 CONTEXT/组件名字(代码名字)/按钮名字)
/// </summary>
/// <param name="command"></param>
[MenuItem("CONTEXT/Transform/Test1")]
static void SetPosition(MenuCommand command)
Transform transform = command.context as Transform;
if (transform != null)
transform.position = Vector3.zero;
Debug.Log("重置位置");
10Scene视图拓展(Gizmos画图)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScene : MonoBehaviour
#if UNITY_EDITOR
public Color color;
/// <summary>
/// 选中才绘制
/// </summary>
private void OnDrawGizmosSelected()
Gizmos.DrawLine(transform .position,transform .position +Vector3 .up);
Gizmos.color = color;
Gizmos.DrawSphere(transform.position ,1);
/// <summary>
/// 一直绘制
/// </summary>
private void OnDrawGizmos()
//Gizmos.DrawLine(transform.position, transform.position + Vector3.up);
//Gizmos.color = color;
//Gizmos.DrawSphere(transform.position, 1);
#endif
11在Scene视图加UI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(TestScene))]
public class TestSceneGUI : Editor
private void OnSceneGUI()
Handles.BeginGUI(); //3d中开始2D块
if (GUILayout.Button("TestScene",GUILayout.Width (100)))
Debug.Log("This TestScene");
Handles.EndGUI();
12在Scene视图加固定的UI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(TestScene))]
public class TestSceneGUI : Editor
private void OnSceneGUI()
Handles.BeginGUI(); //3d中开始2D块
if (GUILayout.Button("TestScene",GUILayout.Width (100)))
Debug.Log("This TestScene");
Handles.EndGUI();
[InitializeOnLoadMethod]
static void InitLoad()
//代码启动就开始画UI
SceneView.duringSceneGui += (sceneView) =>
Handles.BeginGUI(); //3d中开始2D块
//按钮
if (GUILayout.Button("Test2", GUILayout.Width(100)))
Debug.Log("This TestScene");
//标签
GUILayout.Label("先锋");
Handles.EndGUI();
;
13Game视图增加拓展
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 这个特性运行在编辑器下,不需要运行就能出现按钮,如果
/// 不加属性,需要运行才会出现在Game视图(需要将代码挂载到物体上)
/// </summary>
[ExecuteInEditMode]
public class TestGame : MonoBehaviour
private void OnGUI()
if (GUILayout.Button("Test1",GUILayout.Width(100)))
Debug.Log("Test Scene");
14在编辑器下创建自己的窗口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestWindow : EditorWindow
/// <summary>
/// 在窗口中创建一个按钮
/// </summary>
private void OnGUI()
if (GUILayout.Button("创建对象"))
Debug.Log("创建模型");
//以下都是生命周期
/// <summary>
/// 窗口启动
/// </summary>
private void Awake()
Debug.Log("Awake");
/// <summary>
/// 窗口销毁
/// </summary>
private void OnDestroy()
Debug.Log("OnDestroy");
/// <summary>
/// 鼠标焦点,当鼠标出去再进来会执行一次
/// </summary>
private void OnFocus()
Debug.Log("OnFocus");
/// <summary>
/// 窗口常输出
/// </summary>
private void Update()
Debug.Log("Update");
创建一个按钮打开窗口
15窗口中右上角下拉菜单的拓展
效果图
16 在自己创建的Window窗口创建模型预览窗口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class TestPreview : EditorWindow
Object Obj; //
Editor PreviewObj;
Object LatsObj;
/// <summary>
/// 创建一个文件输入窗口
/// </summary>
private void OnGUI()
//可以在这里点击输出框
Obj=EditorGUILayout.ObjectField(Obj,typeof(Object),false);
//创建一个窗口
if (Obj!=null&&Obj!= LatsObj)
PreviewObj = Editor.CreateEditor(Obj);
LatsObj = Obj;
//创建预览画面
if (PreviewObj != null)
PreviewObj.OnPreviewGUI(GUILayoutUtility.GetRect(400, 400), EditorStyles.label);
/// <summary>
/// 打开预览窗口
/// </summary>
[MenuItem("先锋/预览窗口")]
static void Test3()
TestPreview tp = EditorWindow.GetWindow<TestPreview>();
tp.Show();
效果实现
以上是关于Unity编辑器拓展最全实现的主要内容,如果未能解决你的问题,请参考以下文章