网上看到一篇关于 Unity 实用技巧的博文,觉得颇有意思,这里简单翻译一下,原文在这里(PS: 部分技巧仅适用于 Unity 较新版本,有兴趣的朋友注意一下)
TextArea 特性
TextArea 特性可以让我们更加方便的在 Inspector 中编辑字符串文本.
Header, Tooltip 和 Space 特性
Header, Tooltip 和 Space 特性可以帮助我们更好的组织 Inspector 中字段的显示.
扩展方法(C#)
我们可以使用 C# 的扩展方法来为已经存在的类型添加功能(译注:严格来说,扩展方法应该属于 “C# 实用技巧”~)
平台自定义 #defines
我们可以通过设置自己的 “平台自定义 #defines” 来快速的增删一些游戏功能,这里有更多的介绍.
调整 Inspector 的编辑速度
我们可以通过
- 按住 SHIFT 键来加快 Inspector 的编辑速度
- 按住 ALT 键来减慢 Inspector 的编辑速度.
内置 shaders(Built-in shaders)
在 Unity 的 archive 下载页面,我们可以获取到所有内置 shader 的源码(包含所用 CGinc 文件)
MinMax 特性
下面列出的代码是我实现的 “MinMax” 特性,通过使用该特性,我们可以在 Inspector 中更方便的编辑用于表示范围的 Vector2 结构字段.
// MinMaxAttribute.cs
using UnityEngine;
// ! -> Put this anywhere, but not inside an Editor Folder
// By @febucci : https://www.febucci.com/
public class MinMaxAttribute : PropertyAttribute
{
public float minLimit = 0;
public float maxLimit = 1;
public MinMaxAttribute(int min, int max)
{
minLimit = min;
maxLimit = max;
}
}
// MinMaxDrawer.cs
using UnityEngine;
using UnityEditor;
// ! -> Put this in an Editor folder
// By @febucci : https://www.febucci.com/
[CustomPropertyDrawer(typeof(MinMaxAttribute))]
public class MinMaxDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
//Asserts that we're using the MinMax attribute on a Vector2
UnityEngine.Assertions.Assert.IsTrue(property.propertyType == SerializedPropertyType.Vector2, "Devi usare un vector2 per MinMax");
if (property.propertyType == SerializedPropertyType.Vector2)
{
MinMaxAttribute minMax = attribute as MinMaxAttribute;
//Writes the variable name on the left
Rect totalValueRect = EditorGUI.PrefixLabel(position, label);
//The left value, after the variable name
Rect leftRect = new Rect(totalValueRect.x, totalValueRect.y, 50, totalValueRect.height);
//Rect of the slider
Rect valueRect = new Rect(leftRect.xMax, totalValueRect.y, totalValueRect.width - leftRect.width * 2 - 4, totalValueRect.height);
//The right value
Rect rightRect = new Rect(totalValueRect.xMax - leftRect.width - 2, totalValueRect.y, leftRect.width, totalValueRect.height);
float minValue = property.vector2Value.x; //Current x
float maxValue = property.vector2Value.y; //Current y
EditorGUI.MinMaxSlider(valueRect, ref minValue, ref maxValue, minMax.minLimit, minMax.maxLimit);
//Assigns the value to the property
property.vector2Value = new Vector2(minValue, maxValue);
EditorGUI.LabelField(leftRect, minValue.ToString("F3")); //Writes the value on the left
EditorGUI.LabelField(rightRect, maxValue.ToString("F3")); //Writes the value on the right
}
else
{
GUI.Label(position, "You can use MinMax only on a Vector2!");
}
}
}
动画曲线
借助动画曲线,我们可以使用代码来创造出非常酷的物体效果(这里是我写的一篇相关教程)
Un-dock Preview 窗口
我们可以 un-dock Preview 窗口并且将 Preview 窗口放置在任何我们想要的位置上,方法就是右击 Preview 窗口的顶部栏.
组织 Hierarchy
组织 Hierarchy 的一个技巧就是创建一些空的 GameObjects 来分隔层级结构,同时我也建议将这些空 GameObjects 的 tag 设置为 “EditorOnly”(译注: 关于 EditorOnly 后面有说明),这样在游戏的发布版中就不会保存这些空 GameObjects了.
(译注:将分隔层级结构的游戏对象作为相应层级结构的统一父节点也是一种组织 Hierarchy 的方法)
粒子系统(Particle System)的回放时间
我们可以在编辑器中控制粒子的回放时间以更好的方便我们调整粒子效果.
EditorOnly tag
游戏的发布版中不会保存标签(tag) 为 EditorOnly 的 GameObjects.
material 创建时自动指定 shader
通过点选 shader 然后再创建 material 的这种方式, 材质便会在创建之后自动指定 shader 为之前点选的 shader.
在 Inspector 中插入数组元素
我们可以使用快捷键 “CTRL + D”(Mac 平台为 “CMD + D”)来快速的向数组中插入元素(插入的元素会直接复制当前点选的数组元素,而按键 D 也是代表复制(Duplicate)的意思)
显示多个文件夹的内容
我们可以在 Project 窗口中通过多选文件夹的方式来统一查看这些文件夹的内容.
自定义 Unity 的 C# 代码模板
在 “%EDITOR_PATH%\Data\Resources\ScriptTemplates” 文件夹下(译注:其中的 %EDITOR_PATH% 指代 Unity 的安装路径),存在一个名为 “81-C#” 的文件,通过更改该文件的内容,我们就可以自定义 Unity 的 C# 代码模板.
这里有更多的介绍.
控制台日志
我们可以调整控制台日志的显示行数.
OnValidate 函数
OnValidate 函数可以帮助我们确保 Inspector 中的输入数值合法.
更多信息可以在这里找到.
设置 Editor Presets 为默认
我们可以将 Editor Presets 设置为默认(之后的 Reset 操作就会应用对应的 Editor Presets)
Play 模式下的编辑器颜色
我们可以设置 Play 模式下的编辑器颜色,这可以让我们更加明显的看出编辑器是否正处在 Play 模式下~
在构建设置中拖动/选择场景
我们可以同时拖动多个场景到构建设置(build settings)中,并且同时勾选或者不选他们(而不用一个个进行单独操作)
折叠整个 Hierarchy
下面列出的代码用于折叠整个 Hierarchy,如果再添加一个快捷键的话就会更加方便.(译注:展开整个 Hierarchy 应该也是实用技巧之一)
// febucci unitytips unity fold entire hierarchy gameobjects
using UnityEngine;
using UnityEditor;
public class EditorUtils : Editor
{
//This code is released under the MIT license: https://opensource.org/licenses/MIT
[MenuItem("Window/Fold all")]
static void UnfoldSelection()
{
EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
var hierarchyWindow = EditorWindow.focusedWindow;
var expandMethodInfo = hierarchyWindow.GetType().GetMethod("SetExpandedRecursive");
foreach (GameObject root in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects())
{
expandMethodInfo.Invoke(hierarchyWindow, new object[] { root.GetInstanceID(), false });
}
}
}
控制台中的富文本
Unity 的控制台是支持富文本的,更多的信息可以参考这里.
在 Project 窗口中搜索 Asset Store
我们可以在 Project 窗口中直接搜索 Asset Store 中的内容.
DisallowMultipleComponent 和 RequireComponent 特性
我们可以使用
DisallowMultipleComponent 特性和
RequireComponent 特性来规避一些组件的设置错误.
Graphy
Graphy 可以直接监测游戏构建版本的性能.(@tayx94 开发了这个优秀的工具)
Graphy 的 GitHub 地址.
拖动多个 item 至 Inspector
我们可以首先锁定(lock) Inspector,之后便可以拖动多个 item 到 Inspector 上了(譬如将这些 item 赋值给一个数组).
Unity Visual Search
Unity Visual Search 是一个免费的 Unity 插件,使用他我们可以快速的找到需要的 3D 模型,并且可以在编辑器中进行预览(特别适用于游戏原型的制作).
NaughtyAttributes
NaughtyAttributes 项目实现了 20 多种有用的特性,例如 ReorderableList, Slider, ResizableTextArea 等等.
Foldout 特性
dimmpixeye 实现了 Foldout 特性,该特性可以用于给 Inspector 中的变量分组.
Scene 窗口图标
我们可以给 GameObject 和 Script 设置 Scene 窗口下的显示图标,这里有更多信息.
ContextMenu 特性
使用 ContextMenu 特性可以让我们在 Inspector 中直接调用其修饰的方法,更多的信息看这里.
Inspector 中使用数学表达式
Inspector 支持数学表达式的输入.
SerializeField 和 HideInInspector 特性
- SerializeField 特性可以让非公有变量在 Inspector 中显示(并序列化)
- HideInInspector 特性可以让在 Inspector 中显示的变量隐藏.
FormerlySerializedAs 特性
FormerlySerializedAs 特性在你需要重命名一个变量,但又不希望丢失之前的序列化数值的时候特别有用.
AddComponentMenu 特性
使用 AddComponentMenu 特性可以更好的组织脚本在 “AddComponent” 菜单中的层级位置.
MenuItem 特性
MenuItem 特性可以向 主菜单 和 Inspector 上下文菜单中添加方法调用,但要注意的是, MenuItem 是 Editor 下的特性,发布版本中不能使用.
以下内容不来自于译文,是我另外添加的技巧条目
Inspector 的 Debug 模式
一般情况下, Inspector 只会显示需要序列化的变量字段,很多时候并不方便我们调试,我们可以将 Inspector 切换为 Debug 模式,这时就可以显示所有的变量字段了.
譬如以下脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PrivateMonoBehaviour : MonoBehaviour
{
private int m_privateVal = 0;
private Vector3 m_privateV3 = Vector3.one;
}
正常在 Inspector 中是这样显示的:
将 Inspector 切换为 Debug 模式后,显示如下所示:
Unity 的实用技巧自然不止如此,原文作者也一直在持续更新,了解其他实用技巧的朋友也可以分享讨论~