Code Monkey home page Code Monkey logo

unityruntimeinspector's Introduction

Runtime Inspector & Hierarchy for Unity 3D

screenshot

Available on Asset Store: https://assetstore.unity.com/packages/tools/gui/runtime-inspector-hierarchy-111349

Forum Thread: https://forum.unity.com/threads/runtime-inspector-and-hierarchy-open-source.501220/

Discord: https://discord.gg/UJJt549AaV

GitHub Sponsors ☕

A. ABOUT

This is a simple yet powerful runtime Inspector and Hierarchy solution for Unity 3D that should work on pretty much any platform that Unity supports, including mobile platforms.

B. LICENSE

Runtime Inspector & Hierarchy is licensed under the MIT License (Asset Store version is governed by the Asset Store EULA). Please note that this asset uses an external asset which is licensed under the BSD 3-Clause License.

C. INSTALLATION

There are 5 ways to install this plugin:

  • import RuntimeInspector.unitypackage via Assets-Import Package
  • clone/download this repository and move the Plugins folder to your Unity project's Assets folder
  • import it from Asset Store
  • (via Package Manager) add the following line to Packages/manifest.json:
    • "com.yasirkula.runtimeinspector": "https://github.com/yasirkula/UnityRuntimeInspector.git",
  • (via OpenUPM) after installing openupm-cli, run the following command:
    • openupm add com.yasirkula.runtimeinspector

FAQ

  • New Input System isn't supported on Unity 2019.2.5 or earlier

Add ENABLE_INPUT_SYSTEM compiler directive to Player Settings/Scripting Define Symbols (these symbols are platform specific, so if you change the active platform later, you'll have to add the compiler directive again).

  • "Unity.InputSystem" assembly can't be resolved on Unity 2018.4 or earlier

Remove Unity.InputSystem assembly from RuntimeInspector.Runtime Assembly Definition File's Assembly Definition References list.

D. HOW TO

  • To use the hierarchy in your scene, drag&drop the RuntimeHierarchy prefab to your canvas
  • To use the inspector in your scene, drag&drop the RuntimeInspector prefab to your canvas

You can connect the inspector to the hierarchy so that whenever the selection in the hierarchy changes, inspector inspects the newly selected object. To do this, assign the inspector to the Connected Inspector property of the hierarchy.

You can also connect the hierarchy to the inspector so that whenever an object reference in the inspector is highlighted, the selection in hierarchy is updated. To do this, assign the hierarchy to the Connected Hierarchy property of the inspector.

Note that these connections are one-directional, meaning that assigning the inspector to the hierarchy will not automatically assign the hierarchy to the inspector or vice versa. Also note that the inspector and the hierarchy are not singletons and therefore, you can have several instances of them in your scene at a time with different configurations.

E. FEATURES

  • Both panels are heavily optimized in terms of GC in order not to cause any unnecessary allocations. By default, both the inspector and the hierarchy are refreshed 4 times a second to reflect any changes to their user interface almost immediately. Each refresh of the inspector generates some garbage for GC since most of the time, the inspected object has variables of value types. These variables are boxed when accessed via reflection and this boxing creates some unavoidable garbage. However, this process can be greatly optimized by increasing the Refresh Interval of the inspector and/or the hierarchy
  • Includes a built-in color picker and a reference picker:

screenshot

  • Visual appearance of the inspector and the hierarchy can be tweaked by changing their Skin. There are two premade skins included in the Skins directory: LightSkin and DarkSkin. You can create your own skins using the Assets-Create-yasirkula-RuntimeInspector-UI Skin context menu

screenshot

  • The hierarchy supports multi-selection:

screenshot

E.1. INSPECTOR

screenshot

RuntimeInspector works similar to the editor Inspector. It can expose commonly used Unity types out-of-the-box, as well as custom classes and structs that are marked with System.Serializable attribute. 1-dimensional arrays and generic Lists are also supported.

  • Refresh Interval: as the name suggests, this is the refresh interval of the inspector. At each refresh, values of all the exposed fields and properties are refreshed. This generates some garbage for boxed value types (unavoidable) and thus, increasing this value even slightly should help with GC a lot
  • Expose Fields: determines which fields of the inspected object should be exposed: None, Serializable Only or All
  • Expose Properties: determines which properties of the inspected object should be exposed
  • Array Indices Start At One: when enabled, exposed arrays and lists start their indices at 1 instead of 0 (just a visual change)
  • Use Title Case Naming: when enabled, variable names are displayed in title case format (e.g. m_myVariable becomes My Variable)
  • Show Add Component Button: when enabled, Add Component button will appear while inspecting a GameObject
  • Show Remove Component Button: when enabled, Remove Component button will appear under inspected components
  • Show Tooltips: when enabled, hovering over a variable's name for a while will show a tooltip displaying the variable's name. Can be useful for variables whose names are partially obscured
  • Tooltip Delay: determines how long the cursor should remain static over a variable's name before the tooltip appears. Has no effect if Show Tooltips is disabled
  • Nest Limit: imagine exposing a linked list. This variable defines how many nodes you can expose in the inspector starting from the initial node until the inspector stops exposing any further nodes
  • Inspected Object Header Visibility: if the inspected object has a collapsible header, determines that header's visibility
  • Pool Capacity: the UI elements are pooled to avoid unnecessary Instantiate and Destroy calls. This value defines the pool capacity for each of the UI elements individually. On standalone platforms, you can increase this value for better performance
  • Settings: an array of settings for the inspector. A new settings asset can be created using the Assets-Create-yasirkula-RuntimeInspector-Settings context menu. A setting asset stores 4 different things:
    • Standard Drawers and Reference Drawers: a drawer is a prefab used to expose a single variable in the inspector. For variables that extend UnityEngine.Object, a reference drawer is created and for other variables, a standard drawer is created
      • While searching for a suitable drawer for a variable, the corresponding drawers list is traversed from bottom to top until a drawer that supports that variable type is found. If such a drawer is not found, that variable is not exposed
    • Hidden Variables: allows you to hide some variables from the inspector for a given type and all the types that extend/implement it. You can enter asterisk character (*) to hide all the variables for that type
    • Exposed Variables: allows you to expose (counter) some hidden variables. A variable goes through a number of filters before it is exposed:
    1. Its Type must be serializable
    2. It must not have a System.Obsolete, System.NonSerialized or HideInInspector attribute
    3. If it is in Exposed Variables, it is exposed
    4. It must not be in Hidden Variables
    5. it must pass the Expose Fields and Expose Properties filters
    • So, to expose only a specific set of variables for a given type, you can hide all of its variables by entering an asterisk to its Hidden Variables and then entering the set of exposed variables to its Exposed Variables

While changing the inspector's settings, you are advised not to touch InternalSettings; instead create a separate Settings asset and add it to the Settings array of the inspector. Otherwise, when InternalSettings is changed in an update, your settings might get overridden.

E.2. HIERARCHY

screenshot

RuntimeHierarchy simply exposes the objects in your scenes to the user interface. In addition to exposing the currently active Unity scenes in the hierarchy, you can also expose a specific set of objects under what is called a pseudo-scene in the hierarchy. Pseudo-scenes can help you categorize the objects in your scene. Adding/removing objects to/from pseudo-scenes is only possible via the scripting API and helper components.

  • Refresh Interval: the refresh interval of the hierarchy. At each refresh, the destroyed objects are removed from the hierarchy while newly created objects are added to the hierarchy. Sibling indices of the objects are also synced with the Unity Hierarchy at each refresh
  • Object Names Refresh Interval: accessing GameObject.name property generates garbage. Therefore, names of objects in the hierarchy are not synced at each Refresh Interval but rather at each Object Names Refresh Interval to help avoid excessive garbage
  • Search Refresh Interval: the refresh interval for the search results. At each refresh, each GameObject's name is checked to see if it matches the searched term, so this process will generate some garbage
  • Allow Multi Selection: when disabled, only a single Transform can be selected in the hierarchy
  • Expose Unity Scenes: when disabled, Unity scenes are not exposed in the hierarchy. This is useful when you want to use the hierarchy solely for pseudo-scenes
  • Exposed Unity Scenes Subset: specifies the scenes that are exposed in the hierarchy by their name. When empty, all scenes are exposed
  • Expose Dont Destroy On Load Scene: when enabled, DontDesroyOnLoad objects will be exposed in the hierarchy
  • Pseudo Scenes Order: the order of the pseudo-scenes from top to bottom in the hierarchy. Note that entering a pseudo-scene here does not automatically create it when the application starts. Pseudo-scenes can be created via the scripting API only
  • Pointer Long Press Action: determines what will happen when an object is clicked and then held for a while:
    • None: nothing ¯\_(ツ)_/¯
    • Create Dragged Reference Item: creates a dragged reference item that can be dropped onto a reference drawer in the inspector to assign the held object(s) to that variable (similar to Unity's drag&drop reference assignment)
    • Show Multi Selection Toggles: displays multi-selection toggles in front of each object. This is mostly useful on mobile devices where CTRL and Shift keys aren't present. Has no effect if Allow Multi Selection is disabled
    • Show Multi Selection Toggles Then Create Dragged Reference Item: if multi-selection toggles aren't visible, displays them. Otherwise, creates a dragged reference item
  • Pointer Long Press Duration: determines how long an object should be held until the Pointer Long Press Action is executed
  • Double Click Threshold: when an object in the hierarchy is double clicked, OnItemDoubleClicked event is raised (see SCRIPTING API). This value determines the maximum allowed delay between two clicks to register a double click
  • Can Reorganize Items: when enabled, dropping a dragged reference item that holds Transform(s) onto an object in the hierarchy will change the dragged Transform(s)' parents (similar to parenting in Unity's Hierarchy)
  • Can Drop Dragged Parent On Child: when enabled, a dragged reference item can be dropped onto one of its child objects. In this case, the child object will be unparented and then the dragged reference item will become a child of it. Has no effect if Can Reorganize Items is disabled
  • Can Drop Dragged Objects To Pseudo Scenes: when enabled, dropping a dragged reference item onto a pseudo-scene or above/below a root object in the pseudo-scene will automatically add it to that pseudo-scene. Has no effect if Can Reorganize Items is disabled
  • Show Tooltips: when enabled, hovering over an object for a while will show a tooltip displaying the object's name. Can be useful for objects with very long names
  • Tooltip Delay: determines how long the cursor should remain static over an object before the tooltip appears. Has no effect if Show Tooltips is disabled
  • Show Horizontal Scrollbar: when enabled, a horizontal scrollbar will be displayed if the names displayed in the hierarchy don't fit the available space. Note that only the visible items' width values are used to determine the size of the scrollable area
  • Sync Selection With Editor Hierarchy: simply synchronizes the selected object between the Unity Hierarchy and this RuntimeHierarchy

Additional settings for Can Reorganize Items can be found at the RuntimeHierarchy/ScrollView/Viewport object:

screenshot

  • Sibling Index Modification Area: when a dragged reference item is dropped near the top or bottom edges of a Transform in hierarchy, it will be inserted above or belove the target Transform. This value determines the size of the area near the top and bottom edges
  • Scrollable Area: while hovering the cursor near the top or bottom edges of the scroll view with a dragged reference item, scroll view will automatically be scrolled to show contents in that direction. This value determines the size of the area near the top and bottom edges of the scroll view
  • Scroll Speed: determines how fast the scroll view will be scrolled while hovering the cursor over Scrollable Area

F. SCRIPTING API

Values of the variables that are mentioned in E.1 and E.2 sections can be tweaked at runtime via their corresponding properties. Any changes to these properties will be reflected to UI immediately. Here, you will find some interesting things that you can do with the inspector and the hierarchy via scripting:

  • You can change the inspected object in the inspector using the following functions:
public void Inspect( object obj );
public void StopInspect();
  • You can access the currently inspected object via the InspectedObject property of the inspector
  • You can change the selected object in the hierarchy using the following functions:
// SelectOptions is an enum flag meaning that it can take multiple values with | (OR) operator. These values are:
// - Additive: new selection will be appended to the current selection instead of replacing it
// - FocusOnSelection: scroll view will be snapped to the selected object(s)
// - ForceRevealSelection: normally, when selection changes, the new selection will be fully explored in the hierarchy (i.e. all of the parents of the selection will be
//   expanded to reveal the selection). This doesn't automatically happen if selection doesn't change. When this flag is set, however, the selected objects will be fully
//   revealed/explored even if the selection doesn't change
public bool Select( Transform selection, SelectOptions selectOptions = SelectOptions.None ); // Selects the specified Transform. Returns true when the selection is changed successfully
public bool Select( IList<Transform> selection, SelectOptions selectOptions = SelectOptions.None ); // Selects the specified Transform(s)

public void Deselect(); // Deselects all Transforms
public void Deselect( Transform deselection ); // Deselects only the specified Transform
public void Deselect( IList<Transform> deselection ); // Deselects only the specified Transform(s)

public bool IsSelected( Transform transform ); // Returns true if the selection includes the Transform
  • You can access the currently selected object(s) in the hierarchy via the CurrentSelection property
  • Hierarchy's multi-selection toggles can be enabled manually via the MultiSelectionToggleSelectionMode property
  • You can call the Refresh() function on the inspector and/or the hierarchy to refresh them manually
  • You can lock the inspector and/or the hierarchy via the IsLocked property
  • You can register to the OnSelectionChanged event of the hierarchy to get notified when the selection has changed
  • You can register to the OnInspectedObjectChanging delegate of the inspector to get notified when the inspected object is about to change and, if you prefer, change the inspected object altogether. For example, if you want to inspect only objects that have a Renderer component attached, you can use the following function:
private object OnlyInspectObjectsWithRenderer( object previousInspectedObject, object newInspectedObject )
{
	GameObject go = newInspectedObject as GameObject;
	if( go != null && go.GetComponent<Renderer>() != null )
		return newInspectedObject;

	// Don't inspect objects without a Renderer component
	return null;
}
  • You can register to the ComponentFilter delegate of the inspector to filter the list of visible components of a GameObject in the inspector (e.g. hide some components)
runtimeInspector.ComponentFilter = ( GameObject gameObject, List<Component> components ) =>
{
    // Simply remove the undesired Components from the 'components' list
};
  • You can register to the GameObjectFilter delegate of the hierarchy to hide some objects from the hierarchy (or, you can add those objects to RuntimeInspectorUtils.IgnoredTransformsInHierarchy and they will be hidden from all hierarchies; just make sure to remove them from this HashSet before they are destroyed)
runtimeHierarchy.GameObjectFilter = ( Transform obj ) =>
{
    if( obj.CompareTag( "Main Camera" ) )
        return false; // Hide Main Camera from hierarchy
 
    return true;
};
  • You can register to the OnItemDoubleClicked event of the hierarchy to get notified when an object in the hierarchy is double clicked
  • You can add RuntimeInspectorButton attribute to your functions to expose them as buttons in the inspector. These buttons appear when an object of that type is inspected. This attribute takes 3 parameters:
    • string label: the text that will appear on the button
    • bool isInitializer: if set to true and the function returns an object that is assignable to the type that the function was defined in, the resulting value of the function will be assigned back to the inspected object. In other words, this function can be used to initialize null objects or change the variables of structs
    • ButtonVisibility visibility: determines when the button can be visible. Buttons with ButtonVisibility.InitializedObjects can appear only when the inspected object is not null whereas buttons with ButtonVisibility.UninitializedObjects can appear only when the inspected object is null. You can use ButtonVisibility.InitializedObjects | ButtonVisibility.UninitializedObjects to always show the button in the inspector
  • Although you can't add RuntimeInspectorButton attribute to Unity's built-in functions, you can show buttons under built-in Unity types via extension methods. You must write all such extension methods in a single static class, mark the methods with RuntimeInspectorButton attribute and then introduce these functions to the RuntimeInspector as follows: RuntimeInspectorUtils.ExposedExtensionMethodsHolder = typeof( TheScriptThatContainsTheExtensionsMethods );

F.1. PSEUDO-SCENES

You can use the following functions to add object(s) to pseudo-scenes in the hierarchy:

public void AddToPseudoScene( string scene, Transform transform );
public void AddToPseudoScene( string scene, IEnumerable<Transform> transforms );

These functions will create the relevant pseudo-scenes automatically if they do not exist.

You can use the following functions to remove object(s) from pseudo-scenes in the hierarchy:

public void RemoveFromPseudoScene( string scene, Transform transform, bool deleteSceneIfEmpty );
public void RemoveFromPseudoScene( string scene, IEnumerable<Transform> transforms, bool deleteSceneIfEmpty );

You can use the following functions to create or delete a pseudo-scene manually:

public void CreatePseudoScene( string scene );
public void DeletePseudoScene( string scene );
public void DeleteAllPseudoScenes();

F.1.1. PseudoSceneSourceTransform

This helper component allows you to add an object's children to a pseudo-scene in the hierarchy. When a child is added to or removed from the object, this component refreshes the pseudo-scene automatically. If HideOnDisable is enabled, the object's children are removed from the pseudo-scene when the object is disabled.

F.2. COLOR PICKER

You can access the built-in color picker via ColorPicker.Instance and then present it with the following function:

public void Show( ColorWheelControl.OnColorChangedDelegate onColorChanged, ColorWheelControl.OnColorChangedDelegate onColorConfirmed, Color initialColor, Canvas referenceCanvas );
  • onColorChanged: invoked regularly as the user changes the color. ColorWheelControl.OnColorChangedDelegate takes a Color32 parameter
  • onColorConfirmed: invoked when user submits the color via OK button
  • initialColor: the initial value of the color picker
  • referenceCanvas: if assigned, the reference canvas' properties will be copied to the color picker canvas

You can change the color picker's visual appearance by assigning a UISkin to its Skin property.

F.3. OBJECT REFERENCE PICKER

You can access the built-in object reference picker via ObjectReferencePicker.Instance and then present it with the following function:

public void Show( ReferenceCallback onReferenceChanged, ReferenceCallback onSelectionConfirmed, NameGetter referenceNameGetter, NameGetter referenceDisplayNameGetter, object[] references, object initialReference, bool includeNullReference, string title, Canvas referenceCanvas );
  • onReferenceChanged: invoked when the user selects a reference from the list. ReferenceCallback takes an object parameter
  • onSelectionConfirmed: invoked when user submits the selected reference via OK button
  • referenceNameGetter: NameGetter takes an object parameter and returns that object's name as string. The passed function will be used to sort the references list and compare the references' names with the search string
  • referenceDisplayNameGetter: the passed function will be used to get display names for the references. Usually, the same function is passed to this parameter and the referenceNameGetter parameter
  • references: array of references to pick from
  • initialReference: initially selected reference
  • includeNullReference: is set to true, a null reference option will be added to the top of the references list
  • title: title of the object reference picker
  • referenceCanvas: if assigned, the reference canvas' properties will be copied to the object reference picker canvas

You can change the object reference picker's visual appearance by assigning a UISkin to its Skin property.

F.4. DRAGGED REFERENCE ITEMS

In section E.2, it is mentioned that you can drag&drop objects from the hierarchy to the variables in the inspector to assign these objects to those variables. However, you are not limited with just hierarchy. There are two helper components that you can use to create dragged reference items for other objects:

  • DraggedReferenceSourceCamera: when attached to a camera, casts a ray to your scene at each mouse click and creates a dragged reference item if you hold on an object for a while. You can register to the ProcessRaycastHit delegate of this component to filter the objects than can create a dragged reference item. For example, if you want only objects with tag NPC to be able to create a dragged reference item, you can use the following function:
private Object CreateDraggedReferenceItemForNPCsOnly( RaycastHit hit )
{
	if( hit.collider.gameObject.CompareTag( "NPC" ) )
		return hit.collider.gameObject;

	// Non-NPC objects can't create dragged reference items
	return null;
}
  • DraggedReferenceSourceUI: when assigned to a UI element, that element can create a dragged reference item for its References object(s) after it is clicked and held for a while

You can also use your own scripts to create dragged reference items by calling the following functions in the RuntimeInspectorUtils class:

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 );

G. CUSTOM DRAWERS (EDITORS)

NOTE: if you just want to hide some fields/properties from the RuntimeInspector, simply use Settings asset's Hidden Variables list (mentioned in section E.1).

You can introduce your own custom drawers to RuntimeInspector. These drawers will then be used to draw inspected objects' properties in RuntimeInspector. If no custom drawer is specified for a type, built-in ObjectField will be used to draw all properties of that type. There are 2 ways to create custom drawers:

  • Creating a drawer prefab and adding it to the Settings asset mentioned in section E.1. Each drawer extends from InspectorField base class. There is also an ExpandableInspectorField abstract class that allows you to create an expandable/collapsable drawer like arrays. Lastly, extending ObjectReferenceField class allows you to create drawers that can be assigned values via the reference picker or via drag&drop
    • This option provides the most flexibility because you'll be able to customize the drawer prefab as you wish. The downside is, you'll have to create a prefab asset and manually add it to RuntimeInspector's Settings asset. All built-in drawers use this method; they can be as simple as BoolField and TransformField, or as complex as BoundsField, GameObjectField and ArrayField
  • Extending IRuntimeInspectorCustomEditor interface and decorating the class/struct with RuntimeInspectorCustomEditor attribute
    • This option is simpler because you won't have to create a prefab asset for the drawer. Created custom drawer will internally be used by ObjectField to populate its sub-drawers. This option should be sufficient for most use-cases. But imagine that you want to create a custom drawer for Matrix4x4 where the cells are displayed in a 4x4 grid. In this case, you must use the first option because you'll need a custom prefab with 16 InputFields organized in a 4x4 grid for it. But if you can represent the custom drawer you have in mind by using a combination of built-in drawers, then this second option should suffice

G.1. InspectorField

To have a standardized visual appearance across all the drawers, there are some common variables for each drawer:

  • Layout Element: is used to set the height of the drawer. A standard height is set by the currently active Inspector skin's Line Height property. This value is multiplied by the virtual HeightMultiplier property of the drawer. For ExpandableInspectorField's of unknown height, this variable should be left unassigned
  • Variable Name Text: the Text object that displays the name of the exposed variable
  • Variable Name Mask: to understand this one, you may have to examine a simple drawer like BoolField. An Image is drawn on top of the Variable Name Text in order to mask its visible area in an efficient way. And this mask is assigned to this variable

Each drawer has access to the following properties:

  • object Value: the most recent value of the variable that this drawer is bound to. It is refreshed at each refresh interval of the inspector. Changing this property will also change the bound object
  • RuntimeInspector Inspector: the RuntimeInspector that currently uses this drawer
  • UISkin Skin: the skin that is assigned to this drawer
  • Type BoundVariableType: the type of the bound object
  • int Depth: the depth that this drawer is drawn at. As Depth increases, a padding should be applied to the contents of this drawer from left (in OnDepthChanged function)
  • string Name: the name of the bound variable. When set, the variable name is converted to title case format if Use Title Case Naming is enabled in the inspector
  • string NameRaw: When set, the variable name is used as is without being converted to title case format
  • float HeightMultiplier: affects the height of the drawer

There are some special functions on drawers that are invoked on certain circumstances:

  • void Initialize(): should be used instead of Awake/Start to initialize the drawer
  • bool SupportsType( Type type ): returns whether or not this drawer can expose (supports) a certain type in the inspector
  • bool CanBindTo( Type type, MemberInfo variable ): returns whether or not this drawer can expose the provided variable. This function is called only if SupportsType returns true. This function is useful for drawers that can expose only variables with specific attribute(s) (e.g. NumberRangeField queries RangeAttribute). Please note that the variable parameter can be null. By default, this function returns true
  • void OnBound( MemberInfo variable ): called when the drawer is bound to a variable via reflection. Please note that the variable parameter can be null
  • void OnUnbound(): called when the drawer is unbound from the variable that it was bound to
  • void OnInspectorChanged(): called when the Inspector property of the drawer is changed
  • void OnSkinChanged(): called when the Skin property of the drawer is changed. Your custom drawers must adjust their UI elements' visual appearance here to comply with the assigned skin's standards
  • void OnDepthChanged(): called when the Depth property of the drawer is changed. Here, your custom drawers must add a padding to their content from left to comply with the nesting standard. This function is also called when the Skin changes
  • void Refresh(): called when the value of the bound object is refreshed. Drawers must refresh the values of their UI elements here. Invoked by RuntimeInspector at every Refresh Interval seconds

G.2. ExpandableInspectorField

Custom drawers that extend ExpandableInspectorField have access to the following properties:

  • bool IsExpanded: returns whether the drawer is expanded or collapsed. When set to true, the drawer is expanded and its contents are drawn under it
  • HeaderVisibility HeaderVisibility: sets the visibility of this drawer's header: Collapsible, AlwaysVisible or Hidden. By default, this value is set to Collapsible
  • int Length: the number of elements that this drawer aims to draw. If its value does not match the number of child drawers that this drawer has, the contents of the drawer are regenerated

ExpandableInspectorField has the following special functions:

  • void GenerateElements(): the sub-drawers of this drawer must be generated here
  • void ClearElements(): the sub-drawers of this drawer must be cleared here

Sub-drawers of an ExpandableInspectorField should be stored in the protected List<InspectorField> elements variable as ExpandableInspectorField uses this list to compare the number of sub-drawers with the Length property. When Refresh() is called, sub-drawers in this list are refreshed automatically and when ClearElements() is called, sub-drawers in this list are cleared automatically.

You can create sub-drawers using the RuntimeInspector.CreateDrawerForType( Type type, Transform drawerParent, int depth, bool drawObjectsAsFields = true ) function. If no drawer is found that can expose this type, the function returns null. Here, for ExpandableInspectorFields, the drawerParent parameter should be set as the drawArea variable of the ExpandableInspectorField. If the drawObjectsAsFields parameter is set to true and if the type extends UnityEngine.Object, Reference Drawers are searched for a drawer that supports this type. Otherwise Standard Drawers are searched.

After creating sub-drawers, ExpandableInspectorFields must bind their sub-drawers to their corresponding variables manually. This is done via the following BindTo functions of the InspectorField class:

  • BindTo( InspectorField parent, MemberInfo variable, string variableName = null ): binds the object to a MemberInfo (it can be received via reflection). Here, parent parameter should be set to this ExpandableInspectorField. If variableName is set to null, its value is fetched directly from the MemberInfo parameter
  • BindTo( Type variableType, string variableName, Getter getter, Setter setter, MemberInfo variable = null ): this one allows you to define your own getter and setter functions for this sub-drawer. For example, ArrayField uses this function because there is no direct MemberInfo to access an element of an array. With this method, you can use custom functions instead of MemberInfos to get/set the values of the bound objects (ArrayField uses Array.GetValue for its elements' getter function and Array.SetValue for its elements' setter function)

There are also some helper functions in ExpandableInspectorField to easily create sub-drawers without having to call CreateDrawerForType or BindTo manually:

  • InspectorField CreateDrawerForComponent( Component component, string variableName = null ): creates a Standard Drawer for a component
  • InspectorField CreateDrawerForVariable( MemberInfo variable, string variableName = null ): creates a drawer for the variable that the MemberInfo stores. This variable must be declared inside inspected object's class/struct or one of its base classes
  • InspectorField CreateDrawer( Type variableType, string variableName, Getter getter, Setter setter, bool drawObjectsAsFields = true ): similar to the BindTo function with the Getter and Setter parameters, allows you to use custom functions to get and set the value of the object that the sub-drawer is bound to

G.3. ObjectReferenceField

Drawers that extend ObjectReferenceField class have access to the void OnReferenceChanged( Object reference ) function that is called when the reference assigned to that drawer is changed.

G.4. Helper Classes

PointerEventListener: this is a simple helper component that invokes PointerDown event when its UI GameObject is pressed, PointerUp event when it is released and PointerClick event when it is clicked

BoundInputField: most of the built-in drawers use this component for their input fields. This helper component allows you to validate the input as it is entered and also get notified when the input is submitted. It has the following properties and functions:

  • string DefaultEmptyValue: the default value that the input field will have when its input is empty. For example, NumberField sets this value to "0"
  • string Text: a property to refresh the current value of the input field. If the input field is currently focused and being edited, then this property will not change its text immediately but store the value in a variable so that it can be used when the input field is no longer focused. Also, setting this property will not invoke the OnValueChanged event
  • UISkin Skin: the skin that this input field uses. When set, input field will adjust its UI accordingly
  • OnValueChangedDelegate OnValueChanged: called while the value of input field is being edited (called at each change to the input). The OnValueChangedDelegate has the following signature: bool OnValueChangedDelegate( BoundInputField source, string input ). A function that is registered to this event should parse the input and return true if the input is valid, false otherwise
  • OnValueChangedDelegate OnValueSubmitted: called when user finishes editing the value of input field. Similar to OnValueChanged, a function that is registered to this event should parse the input and return true only if the input is valid
  • bool CacheTextOnValueChange: determines what will happen when user stops editing the input field while its contents are invalid (i.e. its background has turned red). If this variable is set to true, input field's text will revert to the latest value that returned true for OnValueChanged. Otherwise, the text will revert to the value input field had when it was focused

G.5. RuntimeInspectorCustomEditor Attribute

To create drawers without having to create a prefab for it, you can declara a class/struct that extends IRuntimeInspectorCustomEditor and has one or more RuntimeInspectorCustomEditor attributes.

RuntimeInspectorCustomEditor attribute has the following properties:

  • Type inspectedType: the type this custom drawer supports (can expose)
  • bool editorForChildClasses: if set to true, types derived from inspectedType can also be drawn with this drawer. By default, this value is false

IRuntimeInspectorCustomEditor has the following functions:

  • void GenerateElements( ObjectField parent ): called by built-in ObjectField's GenerateElements function. Sub-drawers should be added to ObjectField in this function
  • void Refresh(): called by ObjectField's Refresh function
  • void Cleanup(): called by ObjectField's ClearElements function. If the drawer has created some disposable resources, they must be disposed here. No need to destroy the created sub-drawers here because it is handled by ObjectField automatically, as explained in ExpandableInspectorField section

Inside GenerateElements function, you can call parent parameter's CreateDrawerForComponent, CreateDrawerForVariable and CreateDrawer functions to create sub-drawers. In addition to these, you can also call the following helper functions of ObjectField:

  • void CreateDrawersForVariables( params string[] variables ): creates drawers for the specified variables of the inspected object. If no specific variables are provided, drawers will be created for all exposed variables of the inspected object
  • void CreateDrawersForVariablesExcluding( params string[] variablesToExclude ): creates drawers for all exposed variables of the inspected object except the variables specified in variablesToExclude list. If no variables are excluded, drawers will be created for all exposed variables of the inspected object

Here are some example custom drawers:

screenshot

// Custom drawer for Collider type and the types that derive from it
[RuntimeInspectorCustomEditor( typeof( Collider ), true )]
public class ColliderEditor : IRuntimeInspectorCustomEditor
{
	public void GenerateElements( ObjectField parent )
	{
		// Exposes only "enabled" and "isTrigger" properties of Colliders
		// Note that we could achieve the same thing by modifying the "Hidden Variables" and "Exposed Variables" lists of RuntimeInspector's Settings asset
		parent.CreateDrawersForVariables( "enabled", "isTrigger" );
	}

	public void Refresh() { }
	public void Cleanup() { }
}

screenshot

// Custom drawer for MeshRenderer type (but not the types that derive from it)
[RuntimeInspectorCustomEditor( typeof( MeshRenderer ), false )]
public class MeshRendererEditor : IRuntimeInspectorCustomEditor
{
	public void GenerateElements( ObjectField parent )
	{
		// Get the MeshRenderer object we are inspecting
		MeshRenderer renderer = (MeshRenderer) parent.Value;

		// Instead of exposing the MeshRenderer's properties, expose its sharedMaterial's properties
		ExpandableInspectorField materialField = (ExpandableInspectorField) parent.CreateDrawer( typeof( Material ), "", () => renderer.sharedMaterial, ( value ) => renderer.sharedMaterial = (Material) value, false );

		// The drawer for materials is, by default, an ExpandableInspectorField. We don't want to draw its collapsible header in this example
		materialField.HeaderVisibility = RuntimeInspector.HeaderVisibility.Hidden;
	}

	public void Refresh() { }
	public void Cleanup() { }
}

screenshot

// Custom drawer for Camera type (but not the types that derive from it)
[RuntimeInspectorCustomEditor( typeof( Camera ), false )]
public class CameraEditor : IRuntimeInspectorCustomEditor
{
	// Some of the sub-drawers that are created inside GenerateElements
	private BoolField isOrthographicField;
	private NumberField orthographicSizeField, fieldOfViewField;

	public void GenerateElements( ObjectField parent )
	{
		// Create sub-drawers for the Camera's "orthographic", "orthographicSize" and "fieldOfView" properties and store them in variables
		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 ) );

		// Add additional indentation for "orthographicSize" and "fieldOfView" sub-drawers
		orthographicSizeField.Depth++;
		fieldOfViewField.Depth++;

		// Create sub-drawers for the rest of the exposed properties of the Camera
		parent.CreateDrawersForVariablesExcluding( "orthographic", "orthographicSize", "fieldOfView" );
	}

	public void Refresh()
	{
		// Check if Camera is currently using orthographic projection
		bool isOrthographicCamera = (bool) isOrthographicField.Value;

		// Show either "orthographicSize" sub-drawer or "fieldOfView" sub-drawer depending on camera's current projection type
		// (Here, we're first checking if the sub-drawer is already active/inactive via 'activeSelf' for optimization purposes because GameObject.SetActive
		// causes considerable GC allocations and unfortunately doesn't automatically check if GameObject is already active/inactive, at least on some Unity versions)
		if( orthographicSizeField.gameObject.activeSelf != isOrthographicCamera )
			orthographicSizeField.gameObject.SetActive( isOrthographicCamera );
		if( fieldOfViewField.gameObject.activeSelf == isOrthographicCamera )
			fieldOfViewField.gameObject.SetActive( !isOrthographicCamera );
	}

	public void Cleanup() { }
}

unityruntimeinspector's People

Contributors

i-xt avatar yasirkula avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unityruntimeinspector's Issues

Hide Certain Components

is it possible to hide certain components such as Transform and Rigidbody component, or by default all of the components are hidden and expose certain ones ?

Error when deleting object shown by search

Description of the bug

When a GameObject that is visible in the hierarchy is destroyed while in search mode, a NullReferenceException is thrown.

Reproduction steps

  1. Type something in the search bar, so that at least one entry is displayed in the hierarchy
  2. Delete one of the displayed GameObjects from Unity's hierarchy (or by any other means)

Platform specs

  • Unity version: 2020.3.19f1
  • Platform: Windows
  • How did you download the plugin: Package Manager (GitHub)

Additional info

NullReferenceException is thrown here

RuntimeHierarchy AddToPsueDoScene Not working

I followed the steps as you said. Dragged RuntimeHierarchy Prefab into my scene, Created A new Script with following code

` using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RuntimeInspectorNamespace;
public class RunTimeHirearchyHelper : MonoBehaviour {

public RuntimeHierarchy runtimeHierarchy;
public Transform TestTransform;
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
	runtimeHierarchy.AddToPseudoScene("Test scene",TestTransform);
}

}

The Test Psudescene is being created but the objects /children are empty and doesnt show anything

show select wireframe of selected gui elements

nice plugin!
sometimes it's hard to tell which object is selected, if plugin can draw select wireframe of selected gui elements ,or a three-axis in the object's position like unity moving tool, it would be very helpful!

IndexOutOfRangeException in Select right after AddToPseudoScene

As the title says, AddToPseudoScene with Select right afterwards throws an IndexOutOfRangeException, as it seems related to the delayed rebuilding.
Waiting for the rebuild works, but may not be realistically feasible, depending on the refresh interval.
In my case i'm creating an object via code and want to have it immediately selected but it feels strange having to wait for a guessed amount of time before notifying the hierarchy.
I don't think it troubles anyone if the selectionchanged callback was delayed in relation to the rebuild delay, so maybe retaining the selection internally until the rebuild is finished and applying it then would do it.

Vector display error

w value display error:

if( isQuaternion )
{
Quaternion prevVal = (Quaternion) Value;
base.Refresh();
Quaternion val = (Quaternion) Value;

			if( val.x != prevVal.x )
				inputX.Text = val.x.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.y != prevVal.y )
				inputY.Text = val.y.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.z != prevVal.z )
				inputZ.Text = val.z.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.w != prevVal.w )
				inputW.Text = val.z.ToString( RuntimeInspectorUtils.numberFormat );
		}
		else
		{
			Vector4 prevVal = (Vector4) Value;
			base.Refresh();
			Vector4 val = (Vector4) Value;

			if( val.x != prevVal.x )
				inputX.Text = val.x.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.y != prevVal.y )
				inputY.Text = val.y.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.z != prevVal.z )
				inputZ.Text = val.z.ToString( RuntimeInspectorUtils.numberFormat );
			if( val.w != prevVal.w )
				inputW.Text = val.z.ToString( RuntimeInspectorUtils.numberFormat );
		}

Name change in Runtime Inspector event

I am trying to get an event call when the name of gameobject is changed in the Inspector at runtime in Gamview. Can anyone suggest, what event and method I should look for? I have checked in the documentation but unfortunately, I didn't find anything regarding this.

Multiselect in RuntimeHierarchy

Hi,
Thanks for quick reply. Is runtime hierarchy supports Multiselection of nodes? if it is, please reply me how to do it. if its not implemented yet, please add that feature to Runtime Hierarchy. it will be fantastic.

Thanks.
By
S.

NullReferenceException using Hierarchy Search

Description of the bug

Changes to search field did not update the view.

Reproduction steps

Search for something (one time repro)

Platform specs

Please provide the following info if this is a Unity 3D repository.

  • Unity version: 2022.3.5f1
  • Platform: Android
  • Device: Oculus Quest, XROS 50161010000000331
  • How did you download the plugin: GitHub

Additional info

Errors in the order they were reported
NullReferenceException Object reference not set to an instance of an object. <00000000000000000000000000000000> RuntimeInspectorNamespace.HierarchyData.FindDataAtIndex(System.Int32 index) <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.GetDataAt(System.Int32 index) <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.RuntimeInspectorNamespace.IListViewAdapter.SetItemContent(RuntimeInspectorNamespace.RecycledListItem item) <00000000000000000000000000000000> RuntimeInspectorNamespace.RecycledListView.UpdateItemContentsBetweenIndices(System.Int32 topIndex, System.Int32 bottomIndex) <00000000000000000000000000000000> RuntimeInspectorNamespace.RecycledListView.UpdateItemsInTheList(System.Boolean updateAllVisibleItems) <00000000000000000000000000000000> UnityEngine.Events.UnityEvent'1[T0].Invoke(T0 arg0) <00000000000000000000000000000000> UnityEngine.UI.ScrollRect.LateUpdate()

ArgumentOutOfRangeException Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index <00000000000000000000000000000000> System.Collections.Generic.List'1[T].get_Item(System.Int32 index) <00000000000000000000000000000000> RuntimeInspectorNamespace.HierarchyData.FindDataAtIndex(System.Int32 index) <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.GetDataAt(System.Int32 index) <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.RuntimeInspectorNamespace.IListViewAdapter.SetItemContent(RuntimeInspectorNamespace.RecycledListItem item) <00000000000000000000000000000000> RuntimeInspectorNamespace.RecycledListView.UpdateItemContentsBetweenIndices(System.Int32 topIndex, System.Int32 bottomIndex) <00000000000000000000000000000000> RuntimeInspectorNamespace.RecycledListView.UpdateItemsInTheList(System.Boolean updateAllVisibleItems) <00000000000000000000000000000000> UnityEngine.Events.UnityEvent'1[T0].Invoke(T0 arg0) <00000000000000000000000000000000> UnityEngine.UI.ScrollRect.LateUpdate()

NullReferenceException Object reference not set to an instance of an object. <00000000000000000000000000000000> RuntimeInspectorNamespace.HierarchyField.RefreshName() <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.Update()

NullReferenceException Object reference not set to an instance of an object. <00000000000000000000000000000000> RuntimeInspectorNamespace.HierarchyField.Refresh() <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.Refresh() <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.Update()

NullReferenceException Object reference not set to an instance of an object. <00000000000000000000000000000000> RuntimeInspectorNamespace.RuntimeHierarchy.RuntimeInspectorNamespace.IListViewAdapter.OnItemClicked(RuntimeInspectorNamespace.RecycledListItem item) <00000000000000000000000000000000> UnityEngine.EventSystems.ExecuteEvents.Execute[T](UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction'1[T1] functor) <00000000000000000000000000000000> UnityEngine.XR.Interaction.Toolkit.UI.UIInputModule.ProcessPointerButton(UnityEngine.XR.Interaction.Toolkit.UI.ButtonDeltaState mouseButtonChanges, UnityEngine.EventSystems.PointerEventData eventData) <00000000000000000000000000000000> UnityEngine.XR.Interaction.Toolkit.UI.UIInputModule.ProcessTrackedDevice(UnityEngine.XR.Interaction.Toolkit.UI.TrackedDeviceModel& deviceState, System.Boolean force) <00000000000000000000000000000000> UnityEngine.XR.Interaction.Toolkit.UI.XRUIInputModule.DoProcess()

IL2CPP Compatibility

Hello yasirkula,
I just noticed UnityRuntimeInspector doesn't work properly with IL2CPP build.
For an example In unity editor I have a light in the scene, when I select the light in inspector all of light component parameters are exposed, color ,intensity and etc.
But in IL2CPP build the only thing gets exposed is Enabled and Bake Index.
I guess it's because you use .net reflection to extract fields but when it gets converted to C++ it can't be working the same way.
Do you have any solution for this or do you have plans to support IL2CPP as well?

Regards,
Ultran

Members drawn out of order

The Unity Inspector draws elements in the order they are declared. The runtime inspector draws elements based on their member type (variable, property, or method). Because the runtime inspector ignores the order that members are declared it is not possible to control the order that elements are drawn.

Filtering Objects and Layer Filtering

Hello @yasirkula
Your assets are very great and I'm sad I found them so late...
There's 3 things I want to know how to perform in your library :
1- How can I hide some certain objects from Hierarchy?
2- How can I change the Hierarchy root to a certain object, I mean imagine I have a object named MyScene and all of my visual objects are children of it. Now I want to show only children of MyScene in Hierarchy view instead of Scene. I know it's possible using current Expose Scene option but I want to do it as multiple roots.
3- How can I filter objects using their layer id? ( I believe this question has the same answer of 1 )

Regards,
Ultran

Search fallback

After the search is complete, deleting the search content does not return to the original location

Slider (Feature request)

Would you be willing to add a Slider, that works in the same way as the normal Unity slider (where the Range attribute is added that specifies a minimum and maximum value)? It would be really helpful for adjusting values currently set up as sliders in the Unity Inspector. If you are not likely to be able to make the time if you can add some notes about how I may be able to do this myself that would be helpful. I did take a quick look, but I couldn't really see how the various bits hook together.

Numerical display error

image
image
v1.4.53 unity5.5.6
The value of my script is a decimal, which is displayed as an integer in RuntimeInspector

After importing the plugin, I made these changes
In order to solve the error report and solve the API that my unity does not have

Allow Inspected GameObject dropdown to be hidden

By default the inspected GameObject (when using the RuntimeHierarchy) displays the GameObject with name as a dropdown that can be collapsed.
It would be nice to have an option to make it expanded by default and the dropdown hidden.

Dropdown's item height ignores skins

Thank you very much with the plugin! It's great!

Have one issue: dropdown's item height ignores skins. This results in field being too small and text not seen in our setup. See screenshot.

I use custom skin to make texts not be too small when RuntimeInspector is put on our game canvas. (I increased font size, line height and indent amount in three times).

PS As a workaround, can use standalone canvas for RuntimeInspector

2020-07-05 01_08_12-SuperCity - MainScene - Android - Unity 2019 3 2f1 Personal  PREVIEW PACKAGES IN

Compilation error with Input System Package enabled

Description of the bug

Compilation error when using Input System Package

error CS0234: The type or namespace name 'InputSystem' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?)

Reproduction steps

  1. Set Project Settings > Player > Other Settings > Active Input Handling to Input System Package (New)
  2. Install RuntimeInspector package

Platform specs

  • Unity version: 2021.1.15f1
  • Platform: Windows
  • How did you download the plugin: OpenUPM package

Scriptable Object Support

This asset is really phenomenal. I have a use case where I'd like to be able to edit a Scriptable Object at Runtime. At first glance it didn't look like this was supported, but perhaps I'm missing something? If it's not supported do you have any plans on adding support for Scriptable Objects?

UnityException: Transform child out of bounds

Hi! Great asset! And for free! I'm trying to make it work, playing with almost empty scene.

a) positioning inside canvas is off (I'm using Unity 2017.3.1f1), but that can be easily adjusted
b) however, once I start inspecting the hierarchy of RuntimeHierarchy, which is ideal as it is deep, and I do some expand/collapse, the RuntimeHierarchyPool gets populated and if I try to expand RuntimeHierarchyPool it throws the following error

UnityException: Transform child out of bounds
RuntimeInspectorNamespace.HierarchyItemTransform.GetChild (Int32 index) (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyItemTransform.cs:101)
RuntimeInspectorNamespace.HierarchyItem.Refresh () (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyItem.cs:199)
RuntimeInspectorNamespace.HierarchyItemTransform.Refresh () (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyItemTransform.cs:52)
RuntimeInspectorNamespace.HierarchyItem.set_IsExpanded (Boolean value) (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyItem.cs:96)
RuntimeInspectorNamespace.HierarchyItem.m__1 (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyItem.cs:134)
RuntimeInspectorNamespace.PointerEventListener.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Helpers/PointerEventListener.cs:27)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update()

Any suggestions or workarounds?

Thanks!

Ignore item in hierarchy

I need to use unity ignore flags so that some itens won't show in the hierarchy. Is there a way to do it?

Selecting a Transform any other way than clicking it in the hierarchy, leads to wrong results when range selecting afterwards

Description of the bug

When a Transform is selected without clicking it's field in the hierarchy (either by calling RuntimeHierarchy.Select() or by enabling RuntimeHierarchy.syncSelectionWithEditorHierarchy and clicking the GameObject in Unity's hierarchy) RuntimeHierarchy.multiSelectionPivotTransform and RuntimeHierarchy.multiSelectionPivotSceneData are not set. As a result, the wrong items are selected when range selecting afterwards, without clicking another item in the hierarchy first.

Reproduction steps

The easiest way to reproduce this is to use the syncSelectionWithEditorHierarchy option.

  1. Set RuntimeHierarchy.syncSelectionWithEditorHierarchy and RuntimeHierarchy.m_allowMultiSelection to true
  2. Start play mode
  3. Select an item in the runtime hierarchy
  4. Select an item in Unity's hierarchy
  5. Range select another item in the runtime hierarchy

Result: The items between the one that was selected in step 3 and the one that was selected in step 5 get selected.
Expected result: The items between the one that was selected in step 4 and the one that was selected in step 5 get selected.

2021-12-20-13-45-05

Platform specs

  • Unity version: 2020.3.19f1
  • Platform: Windows
  • How did you download the plugin: Package Manager (GitHub)

Feature: Draggable Panels

Encapsulate your RuntimeHierarchy/RuntimeInspector prefab in a separate UI/Panel (i.e. HPanel, IPanel), add the prefab to the appropriate panel and on each panel attach your WindowDrag script. Also make sure there's an EventSystem and StandAloneInputModule set forced active and Cusor.visible. Otherwise in some games it won't register, due to 3rd Party Input managers.

Untitled

Great work by the way! Keep it up. The only issue, The ColorWheel shader when loaded from an assetbundle. :( Unity Issue in older versions, not yours, look at workaround though.

P.S. If you want to make it more friendly to modders, don't use Resource.Load. use assetbundles instead. Unity is backwards compatible on AB's, so if I make a assetbundle in 5.6 a game built with 2019.2 can read it. So when developing this plugin, try to use the lowest possible Unity ver.

Local Euler Angles on Mobile

Hey, I've been using the inspector to position AR objects spawned from markers properly. I would need to use the local euler rotation field to do that propery, but I can't see it on mobile. However, it is visible in the unity editor play mode.

Any ideas on how to make it appear on mobile ?

Thanks !

Keyboard navigation

Hi, fantastic Unity asset!

I would like be able to navigate around the Inspector and Hierarchy using a keyboard. It's fairly easy to add this using Unity's Selectable classes, but the ExpandableInspectorField isn't Selectable, so there isn't a way to navigate to it and expand/collapse it. I'm happy to implement this if you think it's a good idea, and believe there are two ways to do it:

  1. Change the current expand/collapse mechanism to a Button (currently it uses a PointerEventListener to catch the mouse click). This seems the more elegant solution, as conceptually it is a button.
  2. Subclass PointerEventListener from Selectable, so we can navigate to it and trigger it with the keyboard.

Thoughts?

Cheers,
Brian

Change root node of Runtime hierarchy

Hi
Runtime hierarchy lists all the items from the scene. But i need to change the Root node of runtime hierarchy to a specific gameobject that i want. how to do it. where to change that in code?
Thanks.
By
S

Error when selecting objects hidden by search

Description of the bug

The error occurs when an object is selected while it is hidden by the hierarchy search.

Reproduction steps

  • Set Sync Selection With Editor Hierarchy to on, so newly created items get selected
  • Type "aaa" in the search bar to hide all objects
  • Create a new Empty

Platform specs

  • Unity version: 2020.3.19f1
  • Platform: Windows
  • How did you download the plugin: Package Manager

Additional info

ArgumentOutOfRangeException in HierarchyData.cs:253

Multiple Selection

Hi,
First impressive plugin you made, congratulations.

I am working on a pseudoeditor within Unity's editor, including the cross referencing feature of clicking one object on the scene and having it selected on the hierarchy and vice-versa (hierarchy to scene). That much I managed to do.
Now I am stuck with multiple selections, I dug a bit around RuntimeHierarchy currentSelection and I found out that UnityEditor.Selection.activeTransform does not handle Transform arrays but I could, in theory, use UnityEditor.Selection.objects, I am just running into a bunch of nullreferenceexceptions while adapting the code.

Is this a feature you considered in the past? can it be done? I could use some insight on how to do it.

Transforms with only ignored children are expandable

Description of the bug

Transforms where all children are ignored display the expansion arrow. When clicking the arrow, the children of the transform are hidden correctly though.

expand

The reason for this is that HierarchyData.CanExpand uses the HierarchyData.ChildCount property to determine whether or not an item can be expanded and the HierarchyDataTransform.ChildCount override only checks for the nr of children of a Transform and does not take into account whether they are ignored or not.

public override int ChildCount { get { return ( !isSearchEntry && transform ) ? transform.childCount : 0; } }

Reproduction steps

Add a Transform with one child to the hierarchy. Add the child to the ignore list.

Possible Solution

This could be resolved by checking whether or not a Transforms children are ignored. Unfortunately this requires iterating over the Transforms children, but since RuntimeInspectorUtils.IgnoredTransformsHierarchy is a HashSet the performance impact is very low.

	public override int ChildCount
	{
		get
		{
			if( IsSearchEntry || !transform )
				return 0;

			int count = 0;
			foreach( Transform t in transform )
			{
				// Only count children that are not ignored
				if( !RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Contains( t )
				    && ( Root.Hierarchy.GameObjectFilter == null || Root.Hierarchy.GameObjectFilter.Invoke( t ) ) )
					count++;
			}
			return count;
		}
	}

I can send a PR if this change is welcome, but I was hoping that there might be a more elegant solution to this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.