The inspector window shows the current selection’s properties, in our case called object fields.
In the Inspector
window there can be shown many types of object properties, starting from scene objects, assets, editor preferences, etc.
If many different types are selected (for example some assets in the asset browser and some scene objects) the Inspector
will show a list of those types and their count:
The editor.selection
member is a table of type name and an array of (usually) numerical IDs for the selected type.
As an example, if we selected few scene objects AND an asset in the asset browser, editor.selection
will be made of:
editor.selection.object will be an id array like: {122,334,566,44}
editor.selection.asset will be an id array like: {2,4,53,3442,3434,1566,244}
When editor.selection
is {}, there is no selection in the editor.
Instances and Locking
The inspector can have many instances, created with editor.addInspectorInstance()
or pushing the New Inspector
button in the inspector window.
Also one can lock the inspector to the current selection, and if the editor selection
changes, this will not affect the locked inspector instances, they will keep showing their locked selection fields.
Selection Type Handlers
For the inspector to know what editing UI to show for the current editor selection, the user must call editor.registerInspectorTypeHandler(typeName, guiCallback)
so that when it has a type having a non empty selection,
it will call that specific guiCallback
to draw the inspector window’s UI.
By default there is already a handler registered for "object"
which draws a field values
editor for the selected scene objects.
If a user extension wants to render UI in the inspector for special selections,
it will call the register function in the hook named
onEditorInitialized
which is called right after all extensions were loaded.
-- this is the guiCallback function which will be called to render inspector UI
local function assetInspectorGui(inspectorInfo)
local selectedAssets
-- if this inspector instance is not a locked one (not locked on a specific selection)
-- then use the current editor selection
if inspectorInfo.selection == nil then
selectedAssets = editor.selection.asset
else
-- else use the locked selection from the given inspector info table
selectedAssets = inspectorInfo.selection.asset
end
-- just show the list of selected assets
for _, asset ipairs(selectedAssets) do
ui_imgui.Text(asset)
end
end
-- when the editor is initialized, this will be called after all extensions were loaded
local function onEditorInitialized()
-- register out special selection type handler
-- first is the name if our selection type
-- second is the callback to be invoked when there is a valid editor.selection.asset array of selected assets
editor.registerInspectorTypeHandler("asset", assetInspectorGui)
end
M.onEditorInitialized = onEditorInitialized
M.onExtensionLoaded = onExtensionLoaded
Inspector Header UI
If you want to show some specific tools/widgets depending on the current selection, you can add the onEditorInspectorHeaderGui
to your extension’s M
module.
The function will receive an argument which is the inspectorInfo
inspector instance info, having a selection
member which is nil
or the locked selection of that inspector instance.
It will be called right after the call to render inspector widgets, basically any UI you emit in this function will be at the top of the Inspector
window, independent of any inspector selection type.
You can check the editor.selection
to see if there is a type and an object of that type valid, so you can for example show some
paint buttons for when a terrain is selected. If the current selection is of interest, just return from your function.
-- the function to show our terrain paint gui
local function showTerrainPaintGui(objectId)
local obj = scenetree.findObjectById(objectId)
-- if this object is a terrain block, then yes, show the terrain paint gui
if obj:getClassName() == "TerrainBlock" then
ui_imgui.Button("Raise height")
end
end
-- called at the start of inspector window widget drawing
local function onEditorInspectorHeaderGui(inspectorInfo)
-- if there is a locked selection in this inspector instance, use it
if inspectorInfo.selection and #inspectorInfo.selection.object then
showTerrainPaintGui(inspectorInfo.selection.object[1])
-- if there is a current selection in this inspector instance, use it
elseif editor.selection and #editor.selection.object then
showTerrainPaintGui(editor.selection.object[1])
end
end
-- make sure we're called by extensions.hook
M.onEditorInspectorHeaderGui = onEditorInspectorHeaderGui
There are various usages in the built-in editor tools, just look for onEditorInspectorHeaderGui
occurences in the editor code to learn more.