跟着书学Unity-《Unity3D游戏开发》宣雨松编著-(三)拓展编辑器(拓展Sence视图、拓展Game视图、MeneItem菜单)
自定义菜单能做的改动就更多了//菜单排序//false表示Root/Test/2菜单会置灰,不可点击mcheched);效果,默认选中Test3参考文档MenuItem - Unity 脚本 APIMenu - Unity 脚本 APIif (e!new GUIContent(""),//分割线//设置菜单显示区域//显示菜单e.Use();效果是可以在Scene界面右键调用我们创建的菜单参考文档
跟着书学Unity-《Unity3D游戏开发》宣雨松编著-(一)Unity的基础知识、编辑器结构、及拓展编辑器(拓展Project视图)_unity3d游戏开发宣雨松第三版 pdf-CSDN博客
目录
3拓展编辑器
3.4拓展Sence视图
3.4.1辅助元素(Gizmo)
仅在编辑模式下生效
using UnityEngine;
public class Script_03_15 : MonoBehaviour
{
public void OnDrawGizmosSelected()
{
//设置颜色
Gizmos.color = Color.red;
//画线
Gizmos.DrawLine(transform.position, Vector3.one);
//立方体
Gizmos.DrawCube(Vector3.one, Vector3.one);
}
}
效果

参考文档
MonoBehaviour-OnDrawGizmosSelected() - Unity 脚本 API
3.4.2辅助UI
可以通过添加Editor GUI方便在视图中处理一些操作事件
示例代码
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Camera))]
public class Script_03_16 : Editor
{
private void OnSceneGUI()
{
Camera cam = target as Camera;//或者写(Camera)target,但是有可能抛出异常
if (cam != null)
{
Handles.color = Color.red;
Handles.Label(cam.transform.position,
cam.transform.rotation.ToString());
Handles.BeginGUI();
GUI.backgroundColor = Color.red;
if (GUILayout.Button("click", GUILayout.Width(200f)))
{
Debug.LogFormat("click = {0}", cam.name);
}
GUILayout.Label("Label");
Handles.EndGUI();
}
}
}
效果

测试中发现Scene界面中的按钮一直出不来,检查测试之后发现是因为和上一篇的一个脚本当中的对OnInspectorGUI的内容产生了冲突,但是将两组代码合并成一个脚本后又能正常显示了。暂时还不明白这个问题的底层逻辑是什么
参考文档
Editor-OnSceneGUI() - Unity 脚本 API
3.4.3辅助常驻UI
示例代码
using UnityEngine;
using UnityEditor;
public class Script_03_17
{
[InitializeOnLoadMethod]
[System.Obsolete]
static void InitializeOnLoadMethod()
{
SceneView.onSceneGUIDelegate = delegate (SceneView sceneView)
{
Handles.BeginGUI();
GUI.Label(new Rect(0f, 0f, 50f, 15f), "标题");
GUI.Button(new Rect(0f, 20f, 50f, 50f),
AssetDatabase.LoadAssetAtPath<Texture>("Assets/unity.png"));
Handles.EndGUI();
};
}
}
实际这段代码中使用的方法已经被最新版的unity弃用了,所以我进行了改写
using UnityEngine;
using UnityEditor;
public class Script_03_17
{
[InitializeOnLoadMethod]
static void SceneViewUI()
{
SceneView.duringSceneGui += delegate (SceneView sceneView)
{
Handles.BeginGUI();
GUI.Label(new Rect(0f, 0f, 50f, 15f), "标题");
GUI.Button(new Rect(0f, 20f, 50f, 50f),
AssetDatabase.LoadAssetAtPath<Texture>("Assets/unity.png"));
Handles.EndGUI();
};
}
}
效果

参考文档
SceneView-duringSceneGui - Unity 脚本 API
第一段代码所使用的方法我暂时也没有在之前的官方文档中找到就不放了
3.4.4禁用选中对象
using UnityEngine;
using UnityEditor;
public class Script_03_18
{
[InitializeOnLoadMethod]
static void InitializeOnLoadMethod()
{
SceneView.duringSceneGui += delegate (SceneView sceneView)
{
Event e = Event.current;
if (e != null)
{
int controlID = GUIUtility.GetControlID(FocusType.Passive);
if (e.type == EventType.Layout)
{
HandleUtility.AddDefaultControl(controlID);
}
}
};
}
}
添加这段代码之后将无法在Sence视图中选择任何一个物体
参考文档
3.5拓展Game视图
代码不放了主要涉及的就是怎么让Game视图在非运行模式下也绘制GUI,一般只用来做编辑器
参考文档
ExecuteInEditMode - Unity 脚本 API
3.6MenuItem菜单
3.6.1覆盖系统菜单
如果想要重写系统菜单的内容
[MenuItem("GameObject/UI/Text")]
static void CreateNewText()
{
Debug.log("写你的功能");
}
3.6.2自定义菜单
自定义菜单能做的改动就更多了
using UnityEngine;
using UnityEditor;
public class Script_03_20
{
[MenuItem("Root/Test1",false,1)]
static void Test1()
{
}
//菜单排序
[MenuItem("Root/Test0", false, 0)]
static void Test0()
{
}
[MenuItem("Root/Test/2")]
static void Test2()
{
}
[MenuItem("Root/Test/2", true, 0)]
static bool Test2Validation()
{
//false表示Root/Test/2菜单会置灰,不可点击
return false;
}
[MenuItem("Root/Test3", false, 3)]
static void Test3()
{
var menuPath = "Root/Test3";
bool mcheched = Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, !mcheched);
}
}
效果,默认选中Test3

参考文档
3.6.3源生自定义菜单
using UnityEngine;
using UnityEditor;
using UnityEditor.SearchService;
public class Script_03_21
{
[InitializeOnLoadMethod]
static void InitializeOnLoadMethod()
{
SceneView.duringSceneGui += delegate (SceneView sceneView)
{
Event e = Event.current;
if (e != null && e.button == 1 && e.type == EventType.MouseUp)
{
Vector2 mousePosition = e.mousePosition;
var options = new GUIContent[]
{
new GUIContent("Test1"),
new GUIContent("Test2"),
new GUIContent(""),//分割线
new GUIContent("Test/Test3"),
new GUIContent("Test/Test4"),
};
//设置菜单显示区域
var selected = -1;
var userDate = Selection.activeGameObject;
var width = 100;
var height = 100;
var position = new Rect(mousePosition.x, mousePosition.y - height, width, height);
//显示菜单
EditorUtility.DisplayCustomMenu(position, options, selected,
delegate (object data, string[] opt, int select)
{
Debug.Log(opt[select]);
}, userDate);
e.Use();
}
};
}
}
效果是可以在Scene界面右键调用我们创建的菜单

参考文档
EditorUtility-DisplayPopupMenu - Unity 脚本 API
Unity 的官方文档仅收录公开稳定的接口,而 DisplayCustomMenu 是编辑器内部的工具方法,未列入正式支持列表
替代方法有很多,文档如下
3.6.4拓展全局自定义快捷键
基础语法
[MenuItem("Tools/Delete Selected Objects %#d")]
static void DeleteSelected()
{
foreach (var obj in Selection.gameObjects)
Object.DestroyImmediate(obj);
}

参考文档
更多推荐



所有评论(0)