Attachments with Object Tracking on visionOS 2

I have been able to get object tracking working with vision OS 2. So now in my reality view, when my reference object is detected - I am overlaying digital content on top of the reference object. I am implementing this with a Transform entity and attaching an object anchor to the entity and then placing my digital content in the scene (inside Reality Composer Pro)

I now want to know if it's possible to create attachments and attach them to the digital content (say modelXYZ) that is spawned when the physical object is detected. If I need to write SwiftUI code to do this that works together with my RCP scene (that has the object tracking content), how do I do this? Some sample code or some reference to accomplish this would be extremely helpful

Answered by Vision Pro Engineer in 798119022

Hi @adityach

This is possible with some code. You mentioned you already have an entity with an anchoring component. Let's refer to that entity as "ModelAnchorEntity".

  • In Reality Composer Pro create a new transform entity and give it a name. I named mine "AttachmentPlaceholderEntity". As the name implies, this is a placeholder for the attachment.
  • Make AttachmentPlaceholderEntity a child of ModelAnchorEntity.
  • Position AttachmentPlaceholderEntity relative to ModelAnchorEntity. An entity's position is relative to its parent so AttachmentPlaceholderTransform's position will remain relative to ModelAnchorEntity.

In Xcode, modify your immersive view to find AttachmentPlaceholderEntity, create an attachment and make that attachment a child of AttachmentPlaceholderEntity. Remember attachments are entities and an entity's position is relative to its parent so by default the center of the attachment will match the position of AttachmentPlaceholderEntity.

Optionally, you can use BillboardComponent to make the attachment always face the user.

struct ImmersiveView: View {
    let attachmentId = "some-attachment"
    
    var body: some View {
        RealityView { content, attachments in
            if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
                content.add(immersiveContentEntity)
                
                // Find the placeholder using the name you provided in
                // Reality Composer Pro.
                if let placeholderEntity = immersiveContentEntity.findEntity(named: "AttachmentPlaceholderEntity"),
                   // Get the attachment.
                   let attachmentEntity = attachments.entity(for: attachmentId) {
                    // Make the attachment a child of the placeholder.
                    placeholderEntity.addChild(attachmentEntity)
                    
                    // Optional, use BillboardComponent to make the
                    // attachment always face the user.
                    attachmentEntity.components.set(BillboardComponent())
                }
            }
        }
        attachments: {
            Attachment(id: attachmentId) {
                VStack {
                    Text("Look an attachment!")
                }
                .padding(60)
                .glassBackgroundEffect()
            }
        }
    }
}

Work with Reality Composer Pro content in Xcode covers this in detail.

Accepted Answer

Hi @adityach

This is possible with some code. You mentioned you already have an entity with an anchoring component. Let's refer to that entity as "ModelAnchorEntity".

  • In Reality Composer Pro create a new transform entity and give it a name. I named mine "AttachmentPlaceholderEntity". As the name implies, this is a placeholder for the attachment.
  • Make AttachmentPlaceholderEntity a child of ModelAnchorEntity.
  • Position AttachmentPlaceholderEntity relative to ModelAnchorEntity. An entity's position is relative to its parent so AttachmentPlaceholderTransform's position will remain relative to ModelAnchorEntity.

In Xcode, modify your immersive view to find AttachmentPlaceholderEntity, create an attachment and make that attachment a child of AttachmentPlaceholderEntity. Remember attachments are entities and an entity's position is relative to its parent so by default the center of the attachment will match the position of AttachmentPlaceholderEntity.

Optionally, you can use BillboardComponent to make the attachment always face the user.

struct ImmersiveView: View {
    let attachmentId = "some-attachment"
    
    var body: some View {
        RealityView { content, attachments in
            if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
                content.add(immersiveContentEntity)
                
                // Find the placeholder using the name you provided in
                // Reality Composer Pro.
                if let placeholderEntity = immersiveContentEntity.findEntity(named: "AttachmentPlaceholderEntity"),
                   // Get the attachment.
                   let attachmentEntity = attachments.entity(for: attachmentId) {
                    // Make the attachment a child of the placeholder.
                    placeholderEntity.addChild(attachmentEntity)
                    
                    // Optional, use BillboardComponent to make the
                    // attachment always face the user.
                    attachmentEntity.components.set(BillboardComponent())
                }
            }
        }
        attachments: {
            Attachment(id: attachmentId) {
                VStack {
                    Text("Look an attachment!")
                }
                .padding(60)
                .glassBackgroundEffect()
            }
        }
    }
}

Work with Reality Composer Pro content in Xcode covers this in detail.

Attachments with Object Tracking on visionOS 2
 
 
Q