文章目录
- 一、简介
- 二、修改Editor
- 1.菜单栏
- 2.窗口
- 3.Inspector
- 4.Gizmos
- (1)在MonoBehaviour的Message函数中绘制
- (2)使用DrawGizmo Attribute绘制
- 三、在Unity Editor环境下运行
- 1.场景管理
一、简介
游戏开发中遇到的一些问题:
1.如果项目大了,关卡调整这种工作就变成了一种重复的体力劳动
2.发布打包的时候每次都要检查配置,耗费大量精力
3.美术资源更新的时候每次都要检查是否正确配置
解决方法:
Unity提供一些API可以改变编辑器的功能。我们可以使用这些API来自定义GUI改善我们的工作流程,或者将一些重复的体力劳动自动化。
什么是编辑器脚本?
使用UnityEditor命名空间中的API编写的代码段,可以用来创建或修改Editor中的一些功能。
编辑器脚本的“作用域”
一旦脱离Unity Editor环境,这部分代码就不起作用了,所以在Build的时候不能包含Editor代码,否则会报错。为了防止Build的时候包含Editor代码,有两种可选方法:
- 将Editor有关的代码都放入“Editor”文件夹。这个文件夹是一个特殊文件夹,可以放在Project中的任意位置,其中的代码不会被Unity打包。
- 用条件编译语句把Editor有关的代码括起来。如下代码所示:
#if UNITY_EDITOR
using UnityEditor;
#endif
二、修改Editor
我们可以看一下Unity Editor都包含了哪些部分:
1.菜单栏
首先,添加MenuItem Attribute,然后添加响应函数(必须是静态方法)。【Attribute简单了解】
如下图所示,我们可以填入这些参数。通常我们只填入一个itemName
就够了。
using UnityEditor;
public static class MenuItems {
[MenuItem("Tools/Level Creator/New Level Scene")]
private static void NewLevel()
{
EditorUtils.NewLevel();
}
}
- EditorApplication
- EditorSceneManager
- EditorGUILayout:继承自Editor,需要写[CustomEditor()]。override函数OnInspectorGUI
- EditorWindow:继承自EditorWindow。回调函数OnGUI()
- AssetDatabase
- GUIContent
EditorUtility类中包含了一些“弹出对话框”、“弹出读取文件面板”的静态方法:
//public static bool DisplayDialog(string title, string message, string ok, string cancel = "");
bool res = EditorUtility.DisplayDialog("Place Selection On Surface?", "Are you sure you want to place?", "Place", "Do Not Place"))
//public static string OpenFilePanel(string title, string directory, string extension);
string path = EditorUtility.OpenFilePanel("Overwrite with png", "", "png");
2.窗口
3.Inspector
4.Gizmos
打开Gizmos选项卡,可以从Scripts栏中看到有哪些脚本在控制Gizmos,去掉勾选就是禁用该脚本对Gizmos的影响。
Gizmos可以用来可视化地debug,或者在Scene view中添加一些辅助工具。
(1)在MonoBehaviour的Message函数中绘制
所有的Gizmo绘制必须在OnDrawGizmos 或 OnDrawGizmosSelected函数中完成。
OnDrawGizmos函数每帧被调用一次.。所有在OnDrawGizmos 函数中绘制的gizmo都是可以被选中的。OnDrawGizmosSelected只有在该脚本附着的物体被选中时才会被调用。
MonoBehaviour.OnDrawGizmos()
MonoBehaviour.OnDrawGizmosSelected()
Gizmos类包含的属性如下:
- color: 绘制下个gizmo的颜色。
- exposure: 不常用。
- matrix: Unity Editor用来绘制gizmo的4x4矩阵。如果希望gizmo能在场景中移动,就需要修改矩阵了。
举个例子:
private void OnDrawGizmos(){
Matri4x4 oldMatrix = Gizmos.matrix;
Gizmos.matrix = transform.localToWorldMatrix;
//......(draw)
Gizmos.matrix = oldMatrix ;
}
函数有:
-
DrawCube
: Draw a solid box withcenter
andsize
. -
DrawFrustum
: Draw a camera frustum using the currently set Gizmos.matrix for it’s location and - rotation. -
DrawGUITexture
: Draw a texture in the Scene. -
DrawIcon
: Draw an icon at a position in the Scene view. -
DrawLine
: Draws a line starting atfrom
towardsto
. -
DrawMesh
: Draws a mesh. -
DrawRay
: Draws a ray starting at from tofrom
+direction
. -
DrawSphere
: Draws a solid sphere withcenter
andradius
. -
DrawWireCube
: Draw a wireframe box withcenter
andsize
. -
DrawWireMesh
: Draws a wireframe mesh. -
DrawWireSphere
: Draws a wireframe sphere withcenter
andradius
.
using UnityEngine;
public class GizmoExample:MonoBehavior{
private void OnDrawGizmos(){
var color = Gizmos.color;
Gizmos.color = Color.white;
Gizmos.DrawCube(transform.position,Vector3.one);//center,size
Gizmos.color= color;
}
private void OnDrawGizmosSelected(){
var color = Gizmos.color;
Gizmos.color = Color.red;
Gizmos.DrawCube(transform.position,Vector3.one);//pos,size
Gizmos.color= color;
}
}
(2)使用DrawGizmo Attribute绘制
DrawGizmo Attribute允许您为任何组件提供gizmo呈现器。renderer函数必须是静态的,并且有两个参数,一个是为gizmo绘制的对象,另一个是GizmoType参数,它表示gizmo正在生成的上下文。renderer函数可以在class中定义,包括编辑器代码。这允许您将您的gizmo绘制代码从您的组件中取出,而不是将其包含在builds中。
using UnityEditor;
public static class EditorUtils {
[DrawGizmo(GizmoType.NotInSelectionHierarchy |
GizmoType.InSelectionHierarchy |
GizmoType.Active |
GizmoType.Selected |
GizmoType.Pickable )]
public static void CustomDrawGizmos(TargetScript target,GizmoType gizmoType)
{
var color = Gizmos.color;
Gizmos.color = Color.white;
Gizmos.DrawCube(target.transform.position,Vector3.one);//center,size
Gizmos.color= color;
}
}
三、在Unity Editor环境下运行
1.场景管理
using UnityEditor;
using UnityEditor.SceneManagement;
public static class EditorUtils {
# 新建场景
public static void NewScene()
{
EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
}
}