Post

Replies

Boosts

Views

Activity

Reply to Buttons become unresponsive after using .windowStyle(.plain) with auto-hiding menu
Hi Michael, Thank you for the previous suggestion about using AnchorEntity(.head) with trackingMode = .once for positioning entities relative to the user's gaze — that approach worked great for our immersive menu positioning. Now I'm running into a different issue with 360° video playback. When rendering an equirectangular video on a sphere using VideoMaterial and MeshResource.generateSphere(), there is a visible black seam line running vertically on the sphere. This appears to be at the UV seam where the texture coordinates wrap from 1.0 back to 0.0. The same video file plays without any visible seam in other 360° video players on Vision Pro, so the issue is not with the video content itself. Here is the relevant code: private func createVideoSphere(content: RealityViewContent, player: AVPlayer) { let sphere = MeshResource.generateSphere(radius: 1000) let material = VideoMaterial(avPlayer: player) let entity = ModelEntity(mesh: sphere, materials: [material]) entity.scale *= .init(x: -1, y: 1, z: 1) // Flip to render on inside content.add(entity) player.play() } The setup is straightforward: MeshResource.generateSphere(radius: 1000) generates the sphere mesh VideoMaterial(avPlayer:) provides the video texture X scale is flipped to -1 so the texture renders on the inside of the sphere The video is a standard equirectangular 360° MP4 file What I've tried: I attempted to create a custom sphere mesh using MeshDescriptor with duplicate vertices at the UV seam (longitude 0°/360°) to ensure proper UV continuity. However, VideoMaterial did not render any video on the custom mesh (only audio played), and the app eventually crashed. It seems VideoMaterial may have specific mesh requirements. Questions: Is the black seam a known limitation of MeshResource.generateSphere() when used with VideoMaterial for 360° video? Is there a recommended way to eliminate this UV seam — for example, a texture addressing mode or a specific mesh configuration that works with VideoMaterial? Is there an official sample project or code example for playing 360° equirectangular video in a fully immersive space on visionOS? That would be extremely helpful as a reference. Any further guidance would be greatly appreciated. Thank you!
Topic: Spatial Computing SubTopic: General Tags:
Feb ’26
Reply to Buttons become unresponsive after using .windowStyle(.plain) with auto-hiding menu
Hi Michael, Thank you for your previous suggestion to use ViewAttachmentComponent for immersive controls. I've implemented it, However, I'm still facing two critical issues: Issue 1: Buttons in ViewAttachmentComponent Not Responding to Gaze + Pinch The buttons inside my ViewAttachmentComponent are visible and render correctly, but they do not respond to eye gaze + pinch gestures. This defeats the purpose of using visionOS's hands-free interaction model. My Implementation: ImmersiveView.swift (for panoramic images): struct ImmersiveView: View { @EnvironmentObject var model: AppModel @State private var menuEntity: Entity? @State private var isMenuVisible: Bool = true var body: some View { RealityView { content in // Invisible sphere for gesture detection let tapDetector = Entity() tapDetector.name = "TapDetector" tapDetector.components.set(CollisionComponent(shapes: [.generateSphere(radius: 900)])) tapDetector.components.set(InputTargetComponent()) content.add(tapDetector) // Create control menu using ViewAttachmentComponent let menuView = ImageControlMenuView(onExit: exitImmersiveMode) let attachmentEntity = Entity() attachmentEntity.name = "ImageControlMenu" attachmentEntity.components.set(ViewAttachmentComponent(rootView: menuView)) attachmentEntity.position = [0, 1.3, -1.5] attachmentEntity.components.set(BillboardComponent()) menuEntity = attachmentEntity content.add(attachmentEntity) } update: { content in if let menu = menuEntity { menu.isEnabled = isMenuVisible } } .gesture( SpatialTapGesture() .targetedToAnyEntity() .onEnded { _ in // This gesture works - menu shows/hides correctly showMenuAndScheduleHide() } ) } } // Control Menu View struct ImageControlMenuView: View { let onExit: () -> Void var body: some View { HStack(spacing: 16) { Button(action: { print("Exit button tapped") // Never prints with gaze+pinch onExit() }) { HStack(spacing: 8) { Image(systemName: "xmark.circle.fill") .font(.title2) Text("Exit") .font(.headline) } .padding(.horizontal, 20) .padding(.vertical, 12) } .buttonStyle(.bordered) .tint(.white) } .padding(16) .glassBackgroundEffect() } } **Question: ** Is there additional configuration required for ViewAttachmentComponent to enable gaze + pinch interaction? Do I need to add InputTargetComponent or CollisionComponent to the attachment entity itself? Issue 2: Positioning Menu at User's Gaze Direction Currently, my menu appears at a fixed position in 3D space ([0, 1.3, -1.5]). I want to implement behavior similar to Apple TV's immersive video controls, where the menu appears wherever the user is looking when they perform a pinch gesture. I'm using BillboardComponent which makes the menu face the user, but the position remains fixed. Desired behavior: User pinches anywhere in space Menu appears directly in front of user's current gaze direction Menu auto-hides after 3 seconds **Question: ** What's the recommended approach to: Get the user's current head position and gaze direction in an ImmersiveSpace? Position the ViewAttachmentComponent entity relative to the user's gaze when the pinch gesture is detected? Should I use ARKit's head tracking (ARSession with WorldTrackingProvider), or is there a simpler visionOS API for this use case? Environment visionOS: 26.3 Xcode: 26.2 Deployment Target: visionOS 26.0 Device: Apple Vision Pro Summary Gaze + Pinch not working: Buttons in ViewAttachmentComponent don't respond to eye&hand interaction Fixed position: Need guidance on positioning attachment at user's gaze direction dynamically Any further guidance would be greatly appreciated!
Topic: Spatial Computing SubTopic: General Tags:
Feb ’26
Reply to App Window Closure Sequence Impacts Main Interface Reload Behavior
Hello Greg @DTS Engineer , Thank you for your prompt response. I've implemented your suggestion and tried several approaches to solve my window management issue, but I'm still encountering problems that I'd like to clarify. Current Issue: When clicking on a country flag in the Earth window, multiple instances of both the main window and Earth window are being created, despite using the same window IDs. What I've Tried: I've implemented a window management system with a centralized WindowManager singleton that queues window open/close operations and prevents operations that are too frequent: // WindowManager singleton to manage window operations class WindowManager { static let shared = WindowManager() // Serial queue to ensure window operations happen in order private let windowOperationQueue = DispatchQueue(label: "com.mxsing.travelimmersive.windowqueue") // Track last operation time by window ID private var lastOperationTime: [String: Date] = [:] // Track pending open requests private var pendingOpenRequests: [String: Bool] = [:] private init() {} // Request to open a window func requestOpenWindow(id: String, openWindowAction: @escaping (String) -> Void, updateStateAction: @escaping () -> Void) { windowOperationQueue.async { [weak self] in guard let self = self else { return } // Check for pending requests if self.pendingOpenRequests[id] == true { print("Window Manager: Already have pending request for \(id), ignoring") return } // Check last operation time to prevent frequent operations let now = Date() if let lastTime = self.lastOperationTime[id], now.timeIntervalSince(lastTime) < 1.0 { print("Window Manager: Operation for \(id) too frequent, ignoring") return } // Update timestamp and request status self.lastOperationTime[id] = now self.pendingOpenRequests[id] = true // Execute UI operations on main thread DispatchQueue.main.async { print("Window Manager: Opening window \(id)") updateStateAction() // Update state first openWindowAction(id) // Then open window // Clear pending status after 300ms DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.pendingOpenRequests[id] = false } } } } } In AppModel, I've added methods to safely open and close windows: // Safe window opening method that uses the WindowManager func safeOpenWindow(id: String, openWindowAction: @escaping (String) -> Void) { WindowManager.shared.requestOpenWindow( id: id, openWindowAction: openWindowAction, updateStateAction: { [weak self] in // Update state if id == "MainWindow" { self?.mainWindowOpen = true self?.updateWindowExistence(id: id, exists: true) } else if id == "Earth" { self?.isGlobeWindowOpen = true self?.updateWindowExistence(id: id, exists: true) } } ) } // Safe window opening method that uses the WindowManager func safeOpenWindow(id: String, openWindowAction: @escaping (String) -> Void) { WindowManager.shared.requestOpenWindow( id: id, openWindowAction: openWindowAction, updateStateAction: { [weak self] in // Update state if id == "MainWindow" { self?.mainWindowOpen = true self?.updateWindowExistence(id: id, exists: true) } else if id == "Earth" { self?.isGlobeWindowOpen = true self?.updateWindowExistence(id: id, exists: true) } } ) } When a flag is clicked in the Earth view, we call this method: // In CountryButtonView Button { // Process country selection appModel.handleGlobeFlagTap(country: country.name) // Use safe window manager to open main window print("Flag clicked: Opening main window through safe window manager") appModel.safeOpenWindow(id: "MainWindow") { windowId in openWindow(id: windowId) } } label: { // Button content } Key Questions: Window Closure Detection: Is it possible to directly capture the event when a user manually closes a window in visionOS? If so, how can we detect this event? Duplicate Windows: According to the documentation, calling openWindow(id:) should focus an existing window with the same ID rather than creating a new one. However, in our testing, we still see multiple instances of windows with the same ID being created. How can we prevent duplicate windows from being created? Is there a recommended way to implement reliable window state tracking in visionOS that avoids these issues? Are there any undocumented limitations or best practices we should be aware of? I've included the relevant code snippets above, but I'm happy to provide more implementation details if needed. Any guidance would be greatly appreciated. Thank you
Topic: Spatial Computing SubTopic: General Tags:
Apr ’25
Reply to App Window Closure Sequence Impacts Main Interface Reload Behavior
I have another question regarding window management in visionOS, specifically about distinguishing between window closure and app backgrounding. Following the solution provided by radicalappdev in this thread, I implemented window state management using ScenePhase and shared state in AppModel: // In AppModel var mainWindowOpen: Bool = true // In ContentView @Environment(\.scenePhase) private var scenePhase .onChange(of: scenePhase, initial: true) { switch scenePhase { case .inactive, .background: appModel.mainWindowOpen = false case .active: appModel.mainWindowOpen = true @unknown default: appModel.mainWindowOpen = false } } This solution successfully handles the window closure sequence issue, but introduces a new problem: when users press the Home button on Vision Pro, the app exits because the main window's ScenePhase changes to .inactive or .background, which triggers the same state change as when the window is closed. I understand that this might be due to a current limitation in visionOS where the system cannot distinguish between: User actively closing the main window (which should exit the app) User pressing the Home button (which should only background the app) My questions are: Is this indeed a current limitation in visionOS, or is there a way to differentiate between these two events? If it is a limitation, are there any workarounds or alternative approaches to handle this scenario? Is this something that might be addressed in future visionOS updates? Any guidance would be greatly appreciated. Thank you.
Topic: Spatial Computing SubTopic: General Tags:
Apr ’25
Reply to Unable to Create a Fully Immersive Experience That Hides Other Windows in visionOS App
Hello Greg, @DTS Engineer Thank you for your previous guidance on using the dismissWindow action. Following your advice, I've successfully implemented window dismissal when entering the immersive panorama viewing experience, which has greatly improved the immersive feeling for users. Here's my current implementation: // When entering immersive panorama mode, I dismiss other windows func getPanoImageAndOpenImmersiveSpace() async { // ...existing code... if !appModel.immersiveSpaceOpened { // Dismiss main window and Earth window before opening immersive space dismissWindow(id: "MainWindow") dismissWindow(id: "Earth") try await openImmersiveSpace(id: "ImmersiveView") await MainActor.run { appModel.immersiveSpaceOpened = true cardState = .normal } } // ...remaining code... This works well for entering the immersive mode - all other windows are properly hidden. However, I'm facing a new challenge: when exiting the immersive panorama view, I can't properly restore the previous window state. My current exit implementation: func exitPanoramaView() { Task { // Close immersive space await dismissImmersiveSpace() // Reset immersive state appModel.resetImmersiveState() // Close panorama menu appModel.updateWindowExistence(id: "PanoramaMenu", exists: false) dismissWindow(id: "PanoramaMenu") // Try to reopen main window and Earth window openWindow(id: "MainWindow") if appModel.isGlobeWindowOpen { openWindow(id: "Earth") } } } While this reopens the windows, they appear in their initial state rather than preserving the state they had before entering the immersive mode (such as scroll position in the main window, or the specific view of the globe in the Earth window). Is there a recommended approach to: Preserve window state when dismissing windows before entering immersive mode? Restore windows with their previous state when exiting immersive mode? Handle the transition between regular windows and immersive space more smoothly? Any further guidance or code examples would be greatly appreciated. Thank you for your assistance.
Topic: Spatial Computing SubTopic: General Tags:
Apr ’25
Reply to App Window Closure Sequence Impacts Main Interface Reload Behavior
Thanks, radicalappdev. I have tried your solution, it works well, if user close the main interface window first, the app will exit, but it seems that this solution can trigger a new problem, when I press home button, the App will also exit, can not run in the background. I asked AI, was told that currently the VisionOS can't differentiate the closure of main interface window and pressing of home button. Look forward to your further help. Thanks~
Topic: Spatial Computing SubTopic: General Tags:
Apr ’25