I have created a carousel with a ScrollView that contains as many buttons as there are .usdz files. In the ResourceButton structure, when you tap on a button, it should:
Check if a .usdz file is already present. If yes: -Remove the old one. -Add the new one. Otherwise: -Add the new .usdz file to the scene.
My logic seems correct, and there are no error messages. However, when I tap on a button on the device, nothing appears on the screen. Can anyone see what my error might be? Thank you in advance
import scenekit
import swiftui
struct ContentView: View {
@State private var isUSDZDisplayed = false
@State private var sceneKitView = SceneKitView(isUSDZDisplayed: .constant(false)) // Create SceneKitView's instance
var body: some View {
VStack(alignment: .bottom) {
SceneKitView(isUSDZDisplayed: $isUSDZDisplayed)
.frame(height: 300)
Spacer()
// Overlay aand buttons
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(0..<resourceFiles.count, id: \.self) { index in
ResourceButton(fileName: resourceFiles[index], isUSDZDisplayed: $isUSDZDisplayed, sceneKitView: sceneKitView)
}
}
.padding()
.padding(.bottom, 1)
}
}
}
}
struct SceneKitView: UIViewRepresentable {
@Binding var isUSDZDisplayed: Bool
private let sceneView = SCNView()
init(isUSDZDisplayed: Binding<Bool>) {
self._isUSDZDisplayed = isUSDZDisplayed
}
func makeUIView(context: Context) -> SCNView {
let scnView = SCNView()
let scene = SCNScene()
if let url = Bundle.main.url(forResource: "digestiveS", withExtension: "usdz") {
let scene = try! SCNScene(url: url, options: nil)
let scaleFactor: CGFloat = 0.5
}
// ... (Create and position your model SCNNode here)
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light?.type = .omni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)
scene.rootNode.scale = SCNVector3(0.5, 0.5, 0.5)
scnView.scene = scene
scnView.autoenablesDefaultLighting = true
scnView.allowsCameraControl = true
return scnView
}
func updateUIView(_ uiView: SCNView, context: Context)
{
// update if needed
}
func addUSDZObject(fileName: String)
{
if let scene = loadScene(fileName: fileName)
{
sceneView.scene = scene
isUSDZDisplayed = true
}
}
func removeUSDZObject()
{
sceneView.scene = nil
isUSDZDisplayed = false
}
private func loadUSDZScene(named modelName: String) -> SCNNode?
{
guard let usdzURL = Bundle.main.url(forResource: modelName, withExtension: "usdz") else
{
return nil
}
let referenceNode = SCNReferenceNode(url: usdzURL)
referenceNode?.load()
return referenceNode
}
private func loadScene(fileName: String) -> SCNScene?
{
if let modelURL = Bundle.main.url(forResource: fileName, withExtension: "usdz")
{
let scene = try? SCNScene(url: modelURL, options: nil)
print("DEBUG: button name: \(String(describing: scene))")
return scene
}
return nil
}
}
struct ResourceButton: View {
let fileName: String
@Binding var isUSDZDisplayed: Bool
let sceneKitView: SceneKitView
init(fileName: String, isUSDZDisplayed: Binding<Bool>, sceneKitView: SceneKitView) {
self.fileName = fileName
self._isUSDZDisplayed = isUSDZDisplayed
self.sceneKitView = sceneKitView
}
var body: some View {
Button(action: {
if isUSDZDisplayed {
// remove USDZ from screen
sceneKitView.removeUSDZObject()
// add new USDZ from screen
sceneKitView.addUSDZObject(fileName: fileName)
} else {
// add new USDZ from screen
sceneKitView.addUSDZObject(fileName: fileName)
}
// switch USDZ dispalyed state
isUSDZDisplayed.toggle()
}) {
Image(uiImage: UIImage(named: fileName) ?? UIImage()) // load picture from filename
.resizable()
.frame(width: 40, height: 40)
.padding(2.5)
//.background(Color.blue)
.aspectRatio(1/1, contentMode: .fit)
.cornerRadius(12)
.foregroundColor(.white)
}
.buttonStyle(PlainButtonStyle())
.padding(.trailing, 10)
.background(Color.black.opacity(0.5))
}
}
let resourceFiles = ["digestiveS.usdz", "orcas.usdz", "chair_swan.usdz","cup_saucer_set.usdz", "fender_stratocaster.usdz", "flower_tulip.usdz","FruitCakeSlice.usdz", "gramophone.usdz", "LemonMeringuePie.usdz","PegasusTrail.usdz", "robot_walk_idle.usdz", "Rock.usdz","slide.usdz", "solar_panels.usdz", "teapot.usdz","toy_biplane_idle.usdz", "toy_car.usdz", "toy_drummer_idle.usdz","tv_retro.usdz", "wateringcan.usdz", "AirForce.usdz"] // usdz fileName
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}