Error Creating UI Container after Kit 108 update

I would create scene views using the following code snippet:

from omni.ui import scene as sc
from omni import ui

from pxr import Gf, Sdf, Usd, UsdGeom

from omni.kit.scene_view.xr_utils.ui_container import UiContainer
from omni.kit.scene_view.xr_utils.manipulator_components.widget_component import WidgetComponent
from omni.kit.scene_view.xr_utils.spatial_source import SpatialSource

class TestWidget(ui.Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        # Frame container for this widget
        self._root_widget = ui.ZStack()
        self.build()

    def build(self):
        self._root_widget.clear()
        with self._root_widget:
            ui.Rectangle(style={
                "background_color": ui.color("#292929"),
                "border_color": ui.color(0.7),
                "border_width": 2,
                "border_radius": 4,
            })
            with ui.VStack(style={"margin": 8}):
                with ui.VStack(style={"margin": 0}):
                    ui.Label("Hello, Omniverse!")

widget_component = WidgetComponent(
    TestWidget,
    width=400,
    height=400,
    resolution_scale=4.0,
    unit_to_pixel_scale=2.0,
    update_policy=sc.Widget.UpdatePolicy.ALWAYS,
    construct_callback=None,
    widget_kwargs={}
)

widget_container = UiContainer(
    widget_component,
    space_stack=[
        SpatialSource.new_translation_source(Gf.Vec3d(0, 0, 0)),
        SpatialSource.new_rotation_source(
            Gf.Vec3d(90, 0, 0))
    ])

After Kit 108, it appears UiContainer now takes a omni.ui.scene.SceneView type instead of ui.Widget type (if I read it correctly). However, simply changing TestWidget to inherit from omni.ui.scene.SceneView causes the TestWidget instance to be rendered on top of the viewport. How should this be set up now?

Are there any release notes on the scene_view XR utils extensions?

PS. The code above would work with Kit 107 when using the following imports instead:

from omni.kit.xr.scene_view.utils.ui_container import UiContainer
from omni.kit.xr.scene_view.utils.manipulator_components.widget_component import WidgetComponent
from omni.kit.xr.scene_view.utils.spatial_source import SpatialSource
1 Like

Hi , any updates on running xr ui in kit 108+

Just tried with Kit 109, but the issue is still there.

Any advice @Richard3D ?

Yes, the behavior changed in Kit 108: UiContainer now expects a scene-view–style object rather than a plain ui.Widget , and if you just subclass SceneView and attach it to the UI hierarchy, it will draw as a 2D overlay.

How to set it up in Kit 108

The intended pattern is:

  1. Create a SceneView that contains your 3D/UI content, but do not attach it directly to a normal UI frame.
  2. Let WidgetComponent + UiContainer own and place that SceneView in the XR scene.

A minimal adaptation looks like this:

python

import omni.ui as ui
import omni.ui.scene as sc
from pxr import Gf

from omni.kit.scene_view.xr_utils.ui_container import UiContainer
from omni.kit.scene_view.xr_utils.manipulator_components.widget_component import WidgetComponent
from omni.kit.scene_view.xr_utils.spatial_source import SpatialSource


class TestSceneView(sc.SceneView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        # Build scene content into self.scene, not a top-level ui.Widget
        with self.scene:
            # Example: a simple quad with UI drawn via scene primitives
            sc.Rectangle(width=1.0, height=1.0, color=ui.color(0.2, 0.2, 0.2, 1.0))
            sc.Text("Hello, Omniverse!", alignment=ui.Alignment.CENTER)


# Build a component that creates/owns the SceneView
widget_component = WidgetComponent(
    TestSceneView,
    width=400,
    height=400,
    resolution_scale=4.0,
    unit_to_pixel_scale=2.0,
    update_policy=sc.Widget.UpdatePolicy.ALWAYS,
    construct_callback=None,
    widget_kwargs={}
)

# Attach to 3D/XR space via UiContainer
widget_container = UiContainer(
    widget_component,
    space_stack=[
        SpatialSource.new_translation_source(Gf.Vec3d(0, 0, 0)),
        SpatialSource.new_rotation_source(Gf.Vec3d(90, 0, 0)),
    ],
)

Hello Richard, thanks for the additional information. Unfortunately, the provided code does not work because UiContainer now takes a new argument “scene_view_type”. Passing the WidgetComponent alone does not work. I did try the following:

widget_component = WidgetComponent(
    TestSceneView,
    width=400,
    height=400,
    resolution_scale=4.0,
    unit_to_pixel_scale=2.0,
    update_policy=sc.Widget.UpdatePolicy.ALWAYS,
    construct_callback=None,
    widget_kwargs={},
)

self._widget_container = UiContainer(
    TestSceneView,
    widget_component,
    space_stack=[
        SpatialSource.new_translation_source(Gf.Vec3d(0, 0, 0)),
        SpatialSource.new_rotation_source(Gf.Vec3d(90, 0, 0)),
    ],
)

Although this works, the view is being created twice (you can see the second tiny label)!

If you do not use the widget_component, as such:

self._widget_container = UiContainer(
    TestSceneView,
    space_stack=[
        SpatialSource.new_translation_source(Gf.Vec3d(0, 0, 0)),
        SpatialSource.new_rotation_source(Gf.Vec3d(90, 0, 0)),
    ],
)

Then, you get one the tiny one:

Also, you defined the rectangle and label using sc.Rectangle and sc.Label, does that mean everywhere it was ui. has to be changed to sc.???

Let me ask one of our XR engineers and get back to you.

1 Like