1

I am trying to change a texture by pressing a button. Loading the usdz (createData()) or creating a text works fine, adding material and texture ...

But when change the state or the bound observedObject in my ContentView, the texture is not updated...

Can please someone give me a hint, where or how to update my model?

struct ContentView : View {
@ObservedObject var store = TextureStore()

func setMyCurrentTexture(textureName: String){
    store.myCurrentTexture = textureName
}

var body: some View {
    VStack {
        ARViewContainer(texture: $store.myCurrentTexture).edgesIgnoringSafeArea(.all)
        Spacer()
        HStack {
            Button(action: {
                self.setMyCurrentTexture(textureName: "one")
            }) {Text("Use texture one")}
            Spacer()
            Button(action: {self.setMyCurrentTexture(textureName: "two")
            }) {Text("Use texture two")}
        }
    }
}

}

struct ARViewContainer: UIViewRepresentable {
@Binding var texture: String

func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)
    let myurl  = URL(fileURLWithPath: "cube", relativeTo: FileManager.documentDirectoryURL).appendingPathExtension("usdz")
    let redbox = try? Entity.load(contentsOf: myurl)

    let textShape = MeshResource.generateText("nice text shape")
    var textMaterial = SimpleMaterial()

    do {
        try textMaterial.baseColor = .texture(.load(named: texture))
    } catch  {
        textMaterial.tintColor = UIColor(cgColor: #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1))
    }

    let myText = ModelEntity(mesh: textShape, materials: [textMaterial])

    redbox?.scale = [0.3, 0.3, 0.3]
    myText.orientation = simd_quatf(angle: 3*Float.pi/2, axis: [1, 0, 0])
    myText.scale = [0.1, 0.1, 0.1]


    //         Creating parent ModelEntity
    let parentEntity = ModelEntity()
    parentEntity.addChild(redbox!)
    parentEntity.addChild(myText)

    let entityBounds = redbox!.visualBounds(relativeTo: parentEntity)
    parentEntity.collision = CollisionComponent(shapes: [ShapeResource.generateBox(size: entityBounds.extents).offsetBy(translation: entityBounds.center)])

    let anchor = AnchorEntity(plane: .any , classification: .any )
    anchor.addChild(parentEntity)

    arView.scene.anchors.append(anchor)
    arView.installGestures(.all, for: parentEntity)

    return arView

}

func updateUIView(_ uiView: ARView, context: Context) {
    // I COULD PRINT INTO CONSOLE, THAT texture IS CHANGING

    var material = SimpleMaterial()
    do {
        try material.baseColor = .texture(.load(named: texture))
    } catch  {
        material.tintColor = UIColor(cgColor: #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1))
    }

    // BUT HOW TO ATTACH TO MY CUBE OR TO MY TEXT
    // I CAN TRIGGER THE VISIBILITY TOUGH WITH isEnabled

}

}

MobJS
  • 31
  • 3
  • Is `myCurrentTexture` declared as `@Published`? Did you debug if you get into `updateUIView` after button click? – Asperi May 07 '20 at 10:02
  • Hi MobJS, welcome to Stackoverflow. please read and consider this https://stackoverflow.com/help/how-to-ask. it is always a great idea to copy runnable code here which reproduces your error. why? because we (as people who would like to help you) can prove that our solutions work. else we can just guess...and you will get quicker answers if your code is runnable. – Chris May 07 '20 at 10:31
  • Hey, @Asperi, yes, if i print the string, i can see in the console. that it changes when pressing the button. – MobJS May 07 '20 at 11:26
  • @Chris Sorry, I missed to add the function , I will do that, but basically its only loading a usdz file – MobJS May 07 '20 at 11:26
  • If you said you get into `updateUIView` then it is no State/Binding issue. – Asperi May 07 '20 at 12:09
  • Just out of curiosity: does anyone know if this is possible at all? I mean, maybe I was naive thinking that I could change the texture at runtime. As I said, setting the visibility to true or false works like a charm. If anyone has any example or hint, if this possible at all, .., I would be very thankful! I will update the code above and remove the createData() func and assume that the project does have a cube.usdz file in its assets. – MobJS May 08 '20 at 06:54
  • Finally, I managed to solve my problem with the help of [this post] (https://stackoverflow.com/questions/59796488/how-do-i-access-the-model-component-of-reality-composer-in-realitykit/59827294#59827294) After changing the material I had to add it to the right children like this... textAnchor.realityComp!.children[0].children[0].components.set(textModelComp) – MobJS May 11 '20 at 09:10

0 Answers0