【问题标题】:SwiftUI: add SwiftUI Path to Scenekit SceneSwiftUI:将 SwiftUI 路径添加到 Scenekit 场景
【发布时间】:2020-03-31 15:21:44
【问题描述】:

我正在尝试将 SwiftUI 路径添加到 Scenekit 场景(作为 SCNShape)。

我创建了: Scenekit 视图(图 1) SwiftUI 路径(图 2)

然后我尝试调用 SwiftUI Path,基于以下方法: Unable to create circle using UIBezierPath and SCNShape

   let scnpath = ContentView()
   let shape = SCNShape(path: scnpath)
   let shapeNode = SCNNode(geometry: shape)

没用,结果如下:

import SwiftUI
import SceneKit

struct ScenekitView : UIViewRepresentable {
    let scene = SCNScene(named: "art.scnassets/ship.scn")!


    func makeUIView(context: Context) -> SCNView {
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        scene.rootNode.addChildNode(cameraNode)

        // add SwiftUI Path to Scenekit Scene

        let scnpath = ContentView()
        let shape = SCNShape(path: scnpath)
        let shapeNode = SCNNode(geometry: shape)

        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)


        // retrieve the SCNView
        let scnView = SCNView()
        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        scnView.scene = scene


    }
}

#if DEBUG
struct ScenekitView_Previews : PreviewProvider {
    static var previews: some View {
        ScenekitView()
        .colorScheme(.dark)
        .previewDevice("iPad Pro (12.9-inch) (3rd generation)")
    }
}
#endif


import SwiftUI

struct ContentView: View {
    var body: some View {

                Path { path in
                   path.move(to: CGPoint(x: 63.5, y: 98.38))
                           path.addLine(to: CGPoint(x: 920.14, y: 0))
                           path.addLine(to: CGPoint(x: 1094.24, y: 584.81))
                           path.addLine(to: CGPoint(x: 920.14, y: 938.58))
                           path.addLine(to: CGPoint(x: 498.47, y: 1279.73))
                           path.addLine(to: CGPoint(x: 211.79, y: 938.58))
                           path.addLine(to: CGPoint(x: 617.65, y: 584.81))
                           path.addLine(to: CGPoint(x: 735.35, y: 295.94))
                           path.addLine(to: CGPoint(x: 332.02, y: 349.08))
                           path.addLine(to: CGPoint(x: 0, y: 672.25))
                           path.addLine(to: CGPoint(x: 63.5, y: 98.38))
                }
                .stroke(Color.blue, lineWidth: 3)
            }
        }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

非常感谢任何帮助!

干杯

【问题讨论】:

    标签: scenekit swiftui


    【解决方案1】:

    您的 SwiftUI ContentViewView,这是一个结构,但 SCNShape 预期 UIBezierPath 这是一个类。因此,如果您想加入这些不同的概念,您必须执行以下操作:

    ContentView

    struct ContentView: View {
        let path =  Path { path in
           path.move(to: CGPoint(x: 63.5, y: 98.38))
                   path.addLine(to: CGPoint(x: 920.14, y: 0))
                   path.addLine(to: CGPoint(x: 1094.24, y: 584.81))
                   path.addLine(to: CGPoint(x: 920.14, y: 938.58))
                   path.addLine(to: CGPoint(x: 498.47, y: 1279.73))
                   path.addLine(to: CGPoint(x: 211.79, y: 938.58))
                   path.addLine(to: CGPoint(x: 617.65, y: 584.81))
                   path.addLine(to: CGPoint(x: 735.35, y: 295.94))
                   path.addLine(to: CGPoint(x: 332.02, y: 349.08))
                   path.addLine(to: CGPoint(x: 0, y: 672.25))
                   path.addLine(to: CGPoint(x: 63.5, y: 98.38))
        }
    
        var body: some View {
            self.path
                .stroke(Color.blue, lineWidth: 3)
        }
    }
    

    ScenekitView

    let scnpath = ContentView().path.cgPath
    let shape = SCNShape(path: UIBezierPath(cgPath: scnpath), extrusionDepth: 1.0)
    

    【讨论】:

    • 非常感谢 Asperi!现在它建立了,几乎就在那里! :) 但是我仍然没有在 SceneKit 场景中看到 SwiftUI 路径……我尝试添加一些材质,但没有奏效。您是否在 SceneKit 场景中获得了 SwiftUI 路径?
    • 我刚刚确认 SwiftUI Path 不在 Scenekit 场景中(所以它不是附加材料的问题),因为我从视图调试器导出了一个 .scn 文件并且只有船在那里......
    • 补充:找到这个:hackingwithswift.com/quick-start/swiftui/… 但也没有工作......“如果你从 CGPath 而不是 UIBezierPath 开始,事情就更容易了。这一行:让路径= Path(bezierPath.cgPath) 变成这样:让 path = Path(yourCGPath)"
    【解决方案2】:

    试试这个:

    1) 您没有将 shapenode 添加到场景中 - 所以您不会看到它

    2) 一开始,如果你对scenekit没有那么熟练,你不应该自己控制相机……让这个scenekit为你做,所以我删除了你的相机(因为它需要正确的位置+角度这样你才能真正看到一些东西

    3.) 像 asperi 告诉你的那样将形状更新为你的形状 - 这是你可以采用的一种方法(我没有把它放在我的运行示例中,因为它对你来说太容易了;))

    4.) 结果如图所示

    5.) 我不知道你是否知道:在模拟器中,只有在模拟器中点击“播放”按钮才能看到场景包视图...

    struct ScenekitView : UIViewRepresentable {
    
        let scene = SCNScene()
    
    
        func makeUIView(context: Context) -> SCNView {
    
            let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
            // create and add a camera to the scene
            let cameraNode = SCNNode()
            cameraNode.camera = SCNCamera()
      //      scene.rootNode.addChildNode(cameraNode)
    
            // add SwiftUI Path to Scenekit Scene
    
            let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 20, height: 20))
    
            let shape = SCNShape(path: bezierPath, extrusionDepth: 50)
            let shapeNode = SCNNode(geometry: shape)
    
            // place the camera
            cameraNode.position = SCNVector3(x: 0, y: 10, z: 25)
    
         //   scene.rootNode.addChildNode(cameraNode)
            scene.rootNode.addChildNode(shapeNode)
    
            // retrieve the SCNView
            let scnView = SCNView()
            scnView.scene = scene
            scnView.backgroundColor = UIColor.blue
            scnView.frame = CGRect(x: 0, y: 0, width: 500, height: 500)
    
            return scnView
        }
    
        func updateUIView(_ scnView: SCNView, context: Context) {
            print("test")
    
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果你想让它更“性感”一点,你可以添加镜面反射和光......你会得到:

      代码在这里:

      struct ScenekitView : UIViewRepresentable {
      
          let scene = SCNScene()
      
      
          func makeUIView(context: Context) -> SCNView {
      
              let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
              // create and add a camera to the scene
              let cameraNode = SCNNode()
              cameraNode.camera = SCNCamera()
      
              let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 20, height: 20))
      
              let shape = SCNShape(path: bezierPath, extrusionDepth: 40)
              let shapeNode = SCNNode(geometry: shape)
      
              let material = SCNMaterial()
              material.diffuse.contents = UIColor.red
              material.specular.contents = UIColor.white
      
              let light = SCNLight()
              light.type = .spot
              cameraNode.light = light
      
              shape.materials = [material]
      
              shapeNode.rotation = SCNVector4(0.2, 0.3, 0.1, CGFloat.pi / 2)
      
              // place the camera
              cameraNode.position = SCNVector3(x: 5, y: 16, z: 85)
      
              scene.rootNode.addChildNode(cameraNode)
              scene.rootNode.addChildNode(shapeNode)
      
              // retrieve the SCNView
              let scnView = SCNView()
              scnView.scene = scene
              scnView.backgroundColor = UIColor.blue
              scnView.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
      
              return scnView
          }
      
          func updateUIView(_ scnView: SCNView, context: Context) {
              print("test")
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-06
        • 2020-04-06
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-04-09
        • 1970-01-01
        相关资源
        最近更新 更多