In Reality Composer, how to add an invisible object for raycasting?

248 Views Asked by At

I have a complex object in RC, and I cannot select sub-objects for use as buttons. So I want to try to add invisible 'hit boxes' to capture taps. But I cannot find any way to create an invisible object. I've tried dozes of material tweaks within Blender (then export to GTLF, then convert to USDZ with Reality Converter) but no matter what the resulting cube has reflectivity and is not truly invisible.

If I cannot select the part of the model that I want to act as a trigger, what can I do to achieve this?

Note: the deliverable is a .reality file, not an app.

1

There are 1 best solutions below

0
Andy Jazz On

Raycasting-ready invisible box

You cannot make any model invisible in macOS Reality Composer 1.5 other than using the Action called Hide. But it's not your case.

However, you can do it programmatically. For that, export your box scene as .usdz or .reality file, import it into Xcode project, find a box primitive in your scene, and apply a new invisible shader using UnlitMaterial(color: .clear) object.

Here's my code:

import SwiftUI
import RealityKit

struct ContentView: View {
    @State var arView = ARView(frame: .zero)
    @State var boolean = true

    var body: some View {
        ARContainer(arView: arView)
            .ignoresSafeArea()
            .onTapGesture {
                let hit = arView.entity(at: $0) as? ModelEntity
                boolean.toggle()
                print(hit?.id as Any)
                
                if boolean {
                    hit?.model?.materials = [UnlitMaterial(color: .clear)]
                } else {
                    hit?.model?.materials = [UnlitMaterial(color: .init(white: 1, 
                                                                   alpha: 0.1))]
                }
            }
    }
}

struct ARContainer: UIViewRepresentable {
    var arView: ARView
    
    func makeUIView(context: Context) -> ARView {
        let scene = try! Entity.load(named: "HitBox")      // usdz
        print(scene)
        
        let box = scene.findEntity(named: "Mesh0") as! ModelEntity
        box.scale *= 5
        box.model?.materials = [UnlitMaterial(color: .clear)]
        box.generateCollisionShapes(recursive: false)
        
        let anchor = AnchorEntity()
        anchor.addChild(box)
        arView.scene.anchors.append(anchor)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}