Asset Store 链接: https://assetstore.unity.com/packages/tools/gui/runtime-inspector-hierarchy-111349
论坛讨论: https://forum.unity.com/threads/runtime-inspector-and-hierarchy-open-source.501220/
Discord: https://discord.gg/UJJt549AaV
这是一个简单但功能强大的 Unity 3D 运行时检查器和层级视图解决方案,适用于 Unity 支持的几乎所有平台,包括移动平台。
运行时检查器和层级视图使用 MIT 许可证(Asset Store 版本受 Asset Store EULA 管理)。请注意,该资产使用了一个外部资产,该资产使用 BSD 3-Clause 许可证。
有 5 种方式安装此插件:
"com.yasirkula.runtimeinspector": "https://github.com/yasirkula/UnityRuntimeInspector.git",
openupm add com.yasirkula.runtimeinspector
将 ENABLE_INPUT_SYSTEM
编译指令添加到 Player Settings/Scripting Define Symbols(这些符号是特定于平台的,因此如果稍后更改活动平台,你需要再次添加编译指令)。
从 RuntimeInspector.Runtime 程序集定义文件的 Assembly Definition References 列表中删除 Unity.InputSystem
程序集。
你可以将检查器连接到层级视图,这样每当层级视图中的选择发生变化时,检查器就会检查新选择的对象。要做到这一点,将检查器分配给层级视图的 Connected Inspector 属性。
你也可以将层级视图连接到检查器,这样每当检查器中的对象引用被突出显示时,层级视图中的选择就会更新。要做到这一点,将层级视图分配给检查器的 Connected Hierarchy 属性。
请注意,这些连接是单向的,这意味着将检查器分配给 层级视图不会自动将层级视图分配给检查器,反之亦然。还要注意,检查器和层级视图不是单例,因此你可以在场景中同时拥有多个具有不同配置的实例。
RuntimeInspector 的工作方式类似于编辑器检查器。它可以直接暴露常用的 Unity 类型,以及标有 System.Serializable 属性的自定义类和结构体。还支持一维数组和泛型 List。
在更改检查器的设置时,建议不要触碰 InternalSettings;而是创建一个单独的 Settings 资产并将其添加到检查器的 Settings 数组中。否则,当 InternalSettings 在更新中发生变化时,你的设置可能会被覆盖。
RuntimeHierarchy 简单地将场景中的对象暴露给用户界面。除了在层级视图中暴露当前活动的 Unity 场景外,你还可以在层级视图中暴露一组特定的对象,这被称为伪场景。伪场景可以帮助你对场景中的对象进行分类。只能通过脚本 API 和辅助组件向伪场景添加/从中移除对象。
刷新间隔:层级结构的刷新间隔。每次刷新时,被销毁的对象会从层级中移除,而新创建的对象会添加到层级中。对象的同级索引也会在每次刷新时与Unity层级同步
对象名称刷新间隔:访问GameObject.name属性会产生垃圾。因此,层级中对象的名称不会在每个刷新间隔同步,而是在每个对象名称刷新间隔同步,以帮助避免过多的垃圾产生
搜索刷新间隔:搜索结果的刷新间隔。每次刷新时,都会检查每个GameObject的名称是否匹配搜索词,因此这个过程会产生一些垃圾
允许多选:禁用时,层级中只能选择单个Transform
显示Unity场景:禁用时,Unity场景不会在层级中显示。当你只想使用层级来展示伪场景时,这很有用
显示的Unity场景子集:通过名称指定在层级中显示的场景。为空时,显示所有场景
显示DontDestroyOnLoad场景:启用时,DontDestroyOnLoad对象将在层级中显示
伪场景顺序:伪场景在层级中从上到下的顺序。注意,在这里输入伪场景并不会在应用程序启动时自动创建它。伪场景只能通过脚本API创建
指针长按动作:决定当点击并长按一个对象时会发生什么:
指针长按持续时间:决定需要按住对象多长时间才能执行指针长按动作
双击阈值:当在层级中双击一个对象时,会触发OnItemDoubleClicked事件(参见脚本API)。此值决定两次点击之间允许的最大延迟,以注册为双击
可重组项目:启用时,将持有Transform的拖拽引用项放到层级中的对象上会改变被拖拽Transform的父级(类似于Unity层级中的父子关系调整)
可将拖拽的父级放到子级上:启用时,拖拽引用项可以放到其子对象之一上。在这种情况下,子对象将解除父子关系,然后拖拽引用项将成为它的子级。如果禁用了可重组项目,则无效
可将拖拽对象放到伪场景:启用时,将拖拽引用项放到伪场景或伪场景中根对象的上方/下方会自动将其添加到该伪场景。如果禁用了可重组项目,则无效
显示工具提示:启用时,将鼠标悬停在对象上一段时间会显示一个工具提示,显示对象的名称。对于名称很长的对象很有用
工具提示延迟:决定光标在对象上保持静止多长时间后才显示工具提示。如果禁用了显示工具提示,则无效
显示水平滚动条:启用时,如果层级中显示的名称不适合可用空间,将显示一个水平滚动条。注意,只有可见项目的宽度值用于确定可滚动区域的大小
与编辑器层级同步选择:简单地在Unity层级和此RuntimeHierarchy之间同步选中的对象
可重组项目的其他设置可以在RuntimeHierarchy/ScrollView/Viewport对象中找到:
同级索引修改区域:当拖拽引用项被放置在层级中Transform的顶部或底部边缘附近时,它将被插入到目标Transform的上方或下方。此值决定顶部和底部边缘附近区域的大小
可滚动区域:当光标悬停在滚动视图顶部或底部边缘附近并持有拖拽引用项时,滚动视图将自动滚动以显示该方向的内容。此值决定滚动视图顶部和底部边缘附近区域的大小
滚动速度:决定当光标悬停在可滚动区域上时滚动视图的滚动速度
E.1和E.2部分中提到的变量值可以在运行时通过它们对应的属性进行调整。对这些属性的任何更改都会立即反映到UI上。在这里,你会发现一些可以通过脚本对检视器和层级进行的有趣操作:
public void Inspect( object obj ); public void StopInspect();
InspectedObject
属性访问当前检查的 对象// SelectOptions是一个枚举标志,意味着它可以使用|(或)运算符接受多个值。这些值是: // - Additive:新选择将附加到当前选择,而不是替换它 // - FocusOnSelection:滚动视图将对准选中的对象 // - ForceRevealSelection:通常,当选择改变时,新选择将在层级中完全展开(即选择的所有父级将展开以显示选择)。如果选择没有改变,这不会自动发生。 // 当设置此标志时,即使选择没有改变,选中的对 象也会被完全显示/展开 public bool Select( Transform selection, SelectOptions selectOptions = SelectOptions.None ); // 选择指定的Transform。成功更改选择时返回true public bool Select( IList<Transform> selection, SelectOptions selectOptions = SelectOptions.None ); // 选择指定的Transform(s) public void Deselect(); // 取消选择所有Transform public void Deselect( Transform deselection ); // 只取消选择指定的Transform public void Deselect( IList<Transform> deselection ); // 只取消选择指定的Transform(s) public bool IsSelected( Transform transform ); // 如果选择包括该Transform,则返回true
CurrentSelection
属性访问层级中当前选中的对象MultiSelectionToggleSelectionMode
属性手动启用层级的多选切换Refresh()
函数来手动刷新它们IsLocked
属性锁定检视器和/或层级OnSelectionChanged
事件,以在选择改变时得到通知OnInspectedObjectChanging
委托,以在检查的对象即将改变时得到通知,并且如果你愿意,可以完全更改检查的对象。例如,如果你只想检查附加了Renderer组件的对象,可以使用以下函数:private object OnlyInspectObjectsWithRenderer( object previousInspectedObject, object newInspectedObject ) { GameObject go = newInspectedObject as GameObject; if( go != null && go.GetComponent<Renderer>() != null ) return newInspectedObject; // 不检查没有Renderer组件的对象 return null; }
ComponentFilter
委托来过滤检视器中GameObject的可见组件列表(例如隐藏某些组件)runtimeInspector.ComponentFilter = ( GameObject gameObject, List<Component> components ) => { // 只需从'components'列表中移除不需要的Components };
GameObjectFilter
委托来从层级中隐藏某些对象(或者,你可以将这些对象添加到RuntimeInspectorUtils.IgnoredTransformsInHierarchy
中,它们将从所有层级中隐藏;只需确保在销毁它们之前从这个HashSet中移除它们)runtimeHierarchy.GameObjectFilter = ( Transform obj ) => { if( obj.CompareTag( "Main Camera" ) ) return false; // 从层级中隐藏主摄像机 return true; };
OnItemDoubleClicked
事件,以便在层级中的对象被双击时收到通知ButtonVisibility.InitializedObjects
的按钮只有在被检查的对象不为空时才会出现,而带有ButtonVisibility.UninitializedObjects
的按钮只有在被检查的对象为空时才会出现。您可以使用ButtonVisibility.InitializedObjects | ButtonVisibility.UninitializedObjects
来始终在检查器中显示按钮RuntimeInspectorUtils.ExposedExtensionMethodsHolder = typeof( 包含扩展方法的脚本 );
您可以使用以下函数将对象添加到层级中的伪场景:
public void AddToPseudoScene( string scene, Transform transform ); public void AddToPseudoScene( string scene, IEnumerable<Transform> transforms );
如果相关的伪场景不存在,这些函数会自动创建它们。
您可以使用以下函数从层级中的伪场景中移除对象:
public void RemoveFromPseudoScene( string scene, Transform transform, bool deleteSceneIfEmpty ); public void RemoveFromPseudoScene( string scene, IEnumerable<Transform> transforms, bool deleteSceneIfEmpty );
您可以使用以下函数手动创建或删除伪场景:
public void CreatePseudoScene( string scene ); public void DeletePseudoScene( string scene ); public void DeleteAllPseudoScenes();
这个辅助组件允许您将对象的子对象添加到层级中的伪场景。当子对象被添加到或从对象中移除时,此组件会自动刷新伪场景。如果启用了HideOnDisable,则在禁用对象时,其子对象将从伪场景中移除。
您可以通过ColorPicker.Instance访问内置的颜色选择器,然后使用以下函数显示它:
public void Show( ColorWheelControl.OnColorChangedDelegate onColorChanged, ColorWheelControl.OnColorChangedDelegate onColorConfirmed, Color initialColor, Canvas referenceCanvas );
ColorWheelControl.OnColorChangedDelegate
接受一个Color32参数您可以通过将UISkin分配给其Skin属性来更改颜色选择器的视觉外观。
您可以通过ObjectReferencePicker.Instance访问内置的对象引用选择器,然后使用以下函数显示它:
public void Show( ReferenceCallback onReferenceChanged, ReferenceCallback onSelectionConfirmed, NameGetter referenceNameGetter, NameGetter referenceDisplayNameGetter, object[] references, object initialReference, bool includeNullReference, string title, Canvas referenceCanvas );
ReferenceCallback
接受一个object参数NameGetter
接受一个object参数并返回该对象的名称作为字符串。传递的函数将用于对引用列表进行排序并将引用的名称与搜索字符串进行比较您可以通过将UISkin分配给其Skin属性来更改对象引用选择器的视觉外观。
在E.2节中提到,您可以从层级中拖放对象到检查器中的变量,以将这些对象分配给这些变量。但是,您不仅限于层级。有两个辅助组件可用于为其他对象创建拖动引用项:
private Object CreateDraggedReferenceItemForNPCsOnly( RaycastHit hit ) { if( hit.collider.gameObject.CompareTag( "NPC" ) ) return hit.collider.gameObject; // 非NPC对象不能创建拖动引用项 return null; }
您还可以使用自己的脚本通过调用RuntimeInspectorUtils类中的以下函数来创建拖动引用项:
public static DraggedReferenceItem CreateDraggedReferenceItem( Object reference, PointerEventData draggingPointer, UISkin skin = null ); public static DraggedReferenceItem CreateDraggedReferenceItem( Object[] references, PointerEventData draggingPointer, UISkin skin = null, Canvas referenceCanvas = null );
注意: 如果您只想从RuntimeInspector中隐藏一些字段/属性,只需使用Settings资源的Hidden Variables列表(在E.1节中提到)。
您可以向RuntimeInspector引入自己的自定义绘制器。然后这些绘制器将用于在RuntimeInspector中绘制被检查对象的属性。如果没有为类型指定自定义绘制器,内置的ObjectField将用于绘制该类型的所有属性。有两种方法可以创建自定义绘制器:
为了在所有绘制器中有一个标准化的视觉外观,每个绘制器都有一些共同的变量:
每个绘制器都可以访问以下属性:
抽屉有一些在特定情况下调用的特殊函数:
扩展 ExpandableInspectorField 的自定义抽屉可以访问以下属性:
ExpandableInspectorField 有以下特殊函数:
ExpandableInspectorField的子抽屉应存储在 protected List<InspectorField> elements
变量中,因为ExpandableInspectorField使用此列表来比较子抽屉的数量与 Length 属性。当调用 Refresh() 时,此列表中的子抽屉会自动刷新,当调用 ClearElements() 时,此列表中的子抽屉会自动清除。
您可以使用 RuntimeInspector.CreateDrawerForType( Type type, Transform drawerParent, int depth, bool drawObjectsAsFields = true )
函数创建子抽屉。如果找不到可以显示此类型的抽屉,该函数返回 null。对于ExpandableInspectorFields,drawerParent 参数应设置为ExpandableInspectorField的 drawArea 变量。如果 drawObjectsAsFields 参数设置为true,且类型继承自 UnityEngine.Object,则会在 Reference Drawers 中搜索支持此类型的抽屉。否则,会搜索 Standard Drawers。
创建子抽屉后,ExpandableInspectorField 必须手动将其子抽屉绑定到相应的变量。这是通过 InspectorField 类的以下 BindTo 函数完成的:
BindTo( InspectorField parent, MemberInfo variable, string variableName = null )
: 将对象绑定到 MemberInfo(可以通过反射获得)。这里,parent 参数应设置为此 ExpandableInspectorField。如果 variableName 设置为null,其值将直接从MemberInfo参数获取。BindTo( Type variableType, string variableName, Getter getter, Setter setter, MemberInfo variable = null )
: 这允许您为此子抽屉定义自己的getter和setter函数。例如,ArrayField 使用此函数,因为没有直接的MemberInfo来访问数组的元素。使用此方法,您可以使用自定义函数而不是MemberInfos来获取/设置绑定对象的值(ArrayField为其元素的getter函数使用 Array.GetValue,为其元素的setter函数使用 Array.SetValue)。ExpandableInspectorField中还有一些辅助函数,可以轻松创建子抽屉,而无需手动调用 CreateDrawerForType 或 BindTo:
InspectorField CreateDrawerForComponent( Component component, string variableName = null )
: 为组件创建一个 Standard Drawer。InspectorField CreateDrawerForVariable( MemberInfo variable, string variableName = null )
: 为 MemberInfo 存储的变量创建一个抽屉。这个变量必须在检查对象的类/结构或其基类之一中声明。InspectorField CreateDrawer( Type variableType, string variableName, Getter getter, Setter setter, bool drawObjectsAsFields = true )
: 类似于带有 Getter 和 Setter 参数的 BindTo 函数,允许您使用自定义函数来获取和设置子抽屉绑定的对象的值。扩展 ObjectReferenceField 类的抽屉可以访问 void OnReferenceChanged( Object reference )
函数,当分配给该抽屉的引用发生变化时会调用此函数。
PointerEventListener: 这是一个简单的辅助组件,当其UI GameObject被按下时触发 PointerDown 事件,释放时触发 PointerUp 事件,点击时触发 PointerClick 事件。
BoundInputField: 大多数内置抽屉使用此组件作为它们的输入字段。这个辅助组件允许您在输入时验证输入,并在提交输入时得到通知。它有以下属性和函数:
bool OnValueChangedDelegate( BoundInputField source, string input )
。注册到此事件的函数应解析 input 并在输入有效时返回 true,否则返回 false。要创建抽屉而无需为其创建预制体,您可以声明一个继承自 IRuntimeInspectorCustomEditor 并具有一个或多个 RuntimeInspectorCustomEditor 属性的类/结构。
RuntimeInspectorCustomEditor 属性具有以下属性:
IRuntimeInspectorCustomEditor 具有以下函数:
在 GenerateElements 函数内,你可以调用 parent 参数的 CreateDrawerForComponent、CreateDrawerForVariable 和 CreateDrawer 函数来创建子抽屉。除此之外,你还可以调用 ObjectField 的以下辅助函数:
void CreateDrawersForVariables( params string[] variables )
:为被检查对象的指定变量创建抽屉。如果没有提供特定变量,将为被检查对象的所有公开变量创建抽屉void CreateDrawersForVariablesExcluding( params string[] variablesToExclude )
:为被检查对象的所有公开变量创建抽屉,除了 variablesToExclude 列表中指定的变量。如果没有排除任何变量,将为被检查对象的所有公开变量创建抽屉以下是一些自定义抽屉的例子:
// Collider类型及其派生类型 的自定义抽屉 [RuntimeInspectorCustomEditor( typeof( Collider ), true )] public class ColliderEditor : IRuntimeInspectorCustomEditor { public void GenerateElements( ObjectField parent ) { // 只公开 Colliders 的 "enabled" 和 "isTrigger" 属性 // 注意,我们也可以通过修改 RuntimeInspector 的 Settings 资源中的 "Hidden Variables" 和 "Exposed Variables" 列表来实现同样的效果 parent.CreateDrawersForVariables( "enabled", "isTrigger" ); } public void Refresh() { } public void Cleanup() { } }
// MeshRenderer类型的自定义抽屉(但不包括其派生类型) [RuntimeInspectorCustomEditor( typeof( MeshRenderer ), false )] public class MeshRendererEditor : IRuntimeInspectorCustomEditor { public void GenerateElements( ObjectField parent ) { // 获取我们正在检查的 MeshRenderer 对象 MeshRenderer renderer = (MeshRenderer) parent.Value; // 不公开 MeshRenderer 的属性,而是公开其 sharedMaterial 的属性 ExpandableInspectorField materialField = (ExpandableInspectorField) parent.CreateDrawer( typeof( Material ), "", () => renderer.sharedMaterial, ( value ) => renderer.sharedMaterial = (Material) value, false ); // 材质的抽屉默认是 ExpandableInspectorField。在这个例子中,我们不想绘制其可折叠的标题 materialField.HeaderVisibility = RuntimeInspector.HeaderVisibility.Hidden; } public void Refresh() { } public void Cleanup() { } }
// Camera类型的自定义抽屉(但不包括其派生类型) [RuntimeInspectorCustomEditor( typeof( Camera ), false )] public class CameraEditor : IRuntimeInspectorCustomEditor { // 在 GenerateElements 中创建的一些子抽屉 private BoolField isOrthographicField; private NumberField orthographicSizeField, fieldOfViewField; public void GenerateElements( ObjectField parent ) { // 为 Camera 的 "orthographic"、"orthographicSize" 和 "fieldOfView" 属性创建子抽屉,并将它们存储在变量中 isOrthographicField = (BoolField) parent.CreateDrawerForVariable( typeof( Camera ).GetProperty( "orthographic", BindingFlags.Public | BindingFlags.Instance ), "Is Orthographic" ); orthographicSizeField = (NumberField) parent.CreateDrawerForVariable( typeof( Camera ).GetProperty( "orthographicSize", BindingFlags.Public | BindingFlags.Instance ) ); fieldOfViewField = (NumberField) parent.CreateDrawerForVariable( typeof( Camera ).GetProperty( "fieldOfView", BindingFlags.Public | BindingFlags.Instance ) ); // 为 "orthographicSize" 和 "fieldOfView" 子抽屉添加额外的缩进 orthographicSizeField.Depth++; fieldOfViewField.Depth++; // 为 Camera 的其余公开属性创建子抽屉 parent.CreateDrawersForVariablesExcluding( "orthographic", "orthographicSize", "fieldOfView" ); } public void Refresh() { // 检查 Camera 当前是否使用正交投影 bool isOrthographicCamera = (bool) isOrthographicField.Value; // 根据相机当前的投影类型,显示 "orthographicSize" 子抽屉或 "fieldOfView" 子抽屉 // (这里,我们首先通过 'activeSelf' 检查子抽屉是否已经处于激活/非激活状态,以进行优化,因为 GameObject.SetActive // 会导致大量的 GC 分配,而且不幸的是,至少在一些 Unity 版本中,它不会自动检查 GameObject 是否已经处于激活/非激活状态) if( orthographicSizeField.gameObject.activeSelf != isOrthographicCamera ) orthographicSizeField.gameObject.SetActive( isOrthographicCamera ); if( fieldOfViewField.gameObject.activeSelf == isOrthographicCamera ) fieldOfViewField.gameObject.SetActive( !isOrthographicCamera ); } public void Cleanup() { } }
AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各 类写作者提升内容品质和工作效率。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI 智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球, 无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常 生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量 化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述 职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号